use log::{warn};
#[allow(unused_imports)]
use crate::*;
use std::ops::Deref;
const RUN_PAYMENT_INVARIANTS: bool = false;
#[derive(Clone, Debug)]
pub struct PaymentSolution(CashflowSolution);
#[derive(Clone, Debug)]
pub struct PaymentSeries(CashflowSeries);
impl PaymentSolution {
pub(crate) fn new(solution: CashflowSolution) -> Self {
Self {
0: solution,
}
}
pub fn print_table(&self) {
self.series().print_table(true, true)
}
pub fn series(&self) -> PaymentSeries {
let mut series = vec![];
if self.future_value() != 0.0 {
return PaymentSeries::new(CashflowSeries::new(series));
}
let mut payments_to_date = 0.0;
let mut principal_to_date = 0.0;
let mut interest_to_date = 0.0;
for period in 1..=self.periods() {
let principal_remaining_at_start_of_period = self.present_value() + principal_to_date;
let interest = if self.due_at_beginning() && period == 1 {
0.0
} else {
-principal_remaining_at_start_of_period * self.rate()
};
let principal = self.payment() - interest;
payments_to_date += self.payment();
principal_to_date += principal;
interest_to_date += interest;
let payments_remaining = self.sum_of_payments() - payments_to_date;
let principal_remaining = -(self.present_value() + principal_to_date);
let interest_remaining = self.sum_of_interest() - interest_to_date;
let (formula, symbolic_formula) = if self.due_at_beginning() && period == 1 {
("0".to_string(), "interest = 0".to_string())
} else {
let formula = format!("{:.4} = -({:.4} * {:.6})", interest, principal_remaining_at_start_of_period, self.rate());
let symbolic_formula = "interest = -(principal * rate)".to_string();
(formula, symbolic_formula)
};
let entry = CashflowPeriod::new(period, self.rate(), self.due_at_beginning(), self.payment(), payments_to_date,
payments_remaining, principal, principal_to_date, principal_remaining, interest,
interest_to_date, interest_remaining, formula, symbolic_formula);
series.push(entry);
}
let payment_series = PaymentSeries::new(CashflowSeries::new(series));
if RUN_PAYMENT_INVARIANTS {
payment_series.invariant(self);
}
payment_series
}
pub fn print_ab_comparison(
&self,
other: &PaymentSolution,
include_running_totals: bool,
include_remaining_amounts: bool)
{
self.print_ab_comparison_locale_opt(other, include_running_totals, include_remaining_amounts, None, None);
}
pub fn print_ab_comparison_locale(
&self,
other: &PaymentSolution,
include_running_totals: bool,
include_remaining_amounts: bool,
locale: &num_format::Locale,
precision: usize)
{
self.print_ab_comparison_locale_opt(other, include_running_totals, include_remaining_amounts, Some(locale), Some(precision));
}
fn print_ab_comparison_locale_opt(
&self,
other: &PaymentSolution,
include_running_totals: bool,
include_remaining_amounts: bool,
locale: Option<&num_format::Locale>,
precision: Option<usize>)
{
println!();
print_ab_comparison_values_rate("rate", self.rate(), other.rate(), locale, precision);
print_ab_comparison_values_int("periods", i128::from(self.periods()), i128::from(other.periods()), locale);
print_ab_comparison_values_float("present_value", self.present_value(), other.present_value(), locale, precision);
print_ab_comparison_values_float("future_value", self.future_value(), other.future_value(), locale, precision);
print_ab_comparison_values_bool("due_at_beginning", self.due_at_beginning(), other.due_at_beginning());
print_ab_comparison_values_float("payment", self.payment(), other.payment(), locale, precision);
print_ab_comparison_values_float("sum_of_payments", self.sum_of_payments(), other.sum_of_payments(), locale, precision);
print_ab_comparison_values_float("sum_of_interest", self.sum_of_interest(), other.sum_of_interest(), locale, precision);
print_ab_comparison_values_string("formula", &self.formula(), &other.formula());
print_ab_comparison_values_string("symbolic_formula", &self.symbolic_formula(), &other.symbolic_formula());
self.series().print_ab_comparison_locale_opt(&other.series(), include_running_totals, include_remaining_amounts, locale, precision);
}
fn invariant(&self) {
let rate = self.rate();
let periods = self.periods();
let present_value = self.present_value();
let future_value = self.future_value();
let payment = self.payment();
let sum_of_payments = self.sum_of_payments();
let sum_of_interest = self.sum_of_interest();
let formula = self.formula();
let symbolic_formula = self.symbolic_formula();
let present_and_future_value= present_value + future_value;
assert!(self.calculated_field().is_payment());
assert!(rate.is_finite());
assert!(present_value.is_finite());
assert!(future_value.is_finite());
assert!(payment.is_finite());
if future_value == 0.0 {
if present_value == 0.0 {
assert_eq!(0.0, payment);
} else if present_value.is_sign_positive() {
assert!(payment.is_sign_negative());
} else if present_value.is_sign_negative() {
assert!(payment.is_sign_positive());
}
}
assert!(sum_of_payments.is_finite());
assert_approx_equal!(sum_of_payments, payment * periods as f64);
if future_value == 0.0 {
assert_same_sign_or_zero!(sum_of_interest, sum_of_payments);
}
if periods > 0 && rate != 0.0 && future_value == 0.0 && !is_approx_equal!(0.0, present_value) {
assert!(sum_of_interest.abs() < sum_of_payments.abs());
}
assert_approx_equal!(sum_of_interest, sum_of_payments + present_and_future_value);
assert!(!formula.is_empty());
assert!(!symbolic_formula.is_empty());
}
}
impl Deref for PaymentSolution {
type Target = CashflowSolution;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl PaymentSeries {
pub(crate) fn new(series: CashflowSeries) -> Self {
Self {
0: series,
}
}
fn invariant(&self, solution: &CashflowSolution) {
let periods = solution.periods();
if solution.future_value() != 0.0 {
assert_eq!(0, self.len());
} else {
assert_eq!(periods as usize, self.len());
}
if self.len() == 0 {
return;
}
let rate = solution.rate();
let present_value = solution.present_value();
let due_at_beginning = solution.due_at_beginning();
assert!(solution.calculated_field().is_payment());
let payment = solution.payment();
let sum_of_payments = solution.sum_of_payments();
let sum_of_interest = solution.sum_of_interest();
let mut running_sum_of_payments = 0.0;
let mut running_sum_of_principal = 0.0;
let mut running_sum_of_interest = 0.0;
let mut previous_principal: Option<f64> = None;
let mut previous_interest: Option<f64> = None;
for (index, entry) in self.iter().enumerate() {
running_sum_of_payments += entry.payment();
running_sum_of_principal += entry.principal();
running_sum_of_interest += entry.interest();
assert_eq!(rate, entry.rate());
assert_eq!(index + 1, entry.period() as usize);
assert_eq!(payment, entry.payment());
assert_approx_equal!(running_sum_of_payments, entry.payments_to_date());
assert_approx_equal!(sum_of_payments - running_sum_of_payments, entry.payments_remaining());
if present_value == 0.0 || rate == 0.0 || (due_at_beginning && index == 0) {
assert_eq!(payment, entry.principal());
assert_eq!(0.0, entry.interest());
} else if present_value > 0.0 {
assert!(entry.principal() < 0.0);
assert!(entry.interest() < 0.0);
} else {
assert!(entry.principal() > 0.0);
assert!(entry.interest() > 0.0);
}
if index > 0 && previous_interest.unwrap() != 0.0 {
assert!(entry.principal().abs() > previous_principal.unwrap().abs());
assert!(entry.interest().abs() < previous_interest.unwrap().abs());
}
assert_approx_equal!(running_sum_of_principal, entry.principal_to_date());
assert_approx_equal!(-present_value - running_sum_of_principal, entry.principal_remaining());
assert_approx_equal!(running_sum_of_interest, entry.interest_to_date());
assert_approx_equal!(sum_of_interest - running_sum_of_interest, entry.interest_remaining());
assert_approx_equal!(payment, entry.principal() + entry.interest());
if index == periods as usize - 1 {
assert_approx_equal!(0.0, entry.payments_remaining());
assert_approx_equal!(0.0, entry.principal_remaining());
assert_approx_equal!(0.0, entry.interest_remaining());
}
assert!(!entry.formula().is_empty());
assert!(!entry.symbolic_formula().is_empty());
previous_principal = Some(entry.principal());
previous_interest = Some(entry.interest());
}
assert_approx_equal!(running_sum_of_payments, sum_of_payments);
assert_approx_equal!(running_sum_of_principal, -present_value);
assert_approx_equal!(running_sum_of_interest, sum_of_interest);
}
}
impl Deref for PaymentSeries {
type Target = CashflowSeries;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub fn payment<P, F>(rate: f64, periods: u32, present_value: P, future_value: F, due_at_beginning: bool) -> f64
where
P: Into<f64> + Copy,
F: Into<f64> + Copy
{
let present_value = present_value.into();
let future_value = future_value.into();
assert!(rate.is_finite(), "The rate must be finite (not NaN or infinity)");
assert!(rate > -1.0, "The rate must be greater than -1.0 (-100%).");
if rate > 1.0 {
warn!("You provided a periodic rate ({}) greater than 1. Are you sure you expect a {}% return?", rate, rate * 100.0);
}
assert!(present_value.is_finite(), "The present value must be finite (not NaN or infinity)");
assert!(future_value.is_finite(), "The present value must be finite (not NaN or infinity)");
assert!(!(periods == 0 && present_value + future_value != 0.0), "There are no periods and the present value + future value is not zero so there is no way to calculate payments.");
if periods == 0 {
assert_approx_equal!(present_value, -future_value);
return 0.0;
}
if rate == 0.0 {
return (-present_value - future_value) / periods as f64;
}
let rate_mult = 1.0 + rate;
let num= ((present_value * rate_mult.powf(periods as f64)) + future_value) * -rate;
assert!(num.is_finite());
let mut denom = (rate_mult).powf(periods as f64) - 1.0;
assert!(denom.is_finite());
assert!(denom.is_normal());
if due_at_beginning {
denom *= rate_mult;
}
assert!(denom.is_finite());
assert!(denom.is_normal());
let payment = num / denom;
assert!(payment.is_finite());
payment
}
pub fn payment_solution<P, F>(rate: f64, periods: u32, present_value: P, future_value: F, due_at_beginning: bool) -> PaymentSolution
where
P: Into<f64> + Copy,
F: Into<f64> + Copy
{
let present_value = present_value.into();
let future_value = future_value.into();
let payment = payment(rate, periods, present_value, future_value, due_at_beginning);
let (formula, symbolic_formula) = payment_formula(rate, periods, present_value, future_value, due_at_beginning, payment);
let solution = PaymentSolution::new(CashflowSolution::new(CashflowVariable::Payment, rate, periods, present_value, future_value, due_at_beginning, payment, &formula, &symbolic_formula));
if RUN_PAYMENT_INVARIANTS {
solution.invariant();
}
solution
}
fn payment_formula(rate: f64, periods: u32, present_value: f64, future_value: f64, due_at_beginning: bool, payment: f64) -> (String, String) {
let rate_multiplier = 1.0 + rate;
let (mut formula, mut symbolic_formula) = if periods == 0 {
(format!("{:.4}", 0.0), "0".to_string())
} else if rate == 0.0 {
if future_value == 0.0 {
(format!("{:.4} / {}", -present_value, periods), "-pv / n".to_string())
} else if present_value == 0.0 {
(format!("{:.4} / {}", -future_value, periods), "-fv / n".to_string())
} else {
let add_future_value = if future_value > 0.0 {
format!(" - {:.4}", future_value)
} else {
format!(" + {:.4}", -future_value)
};
let formula = format!("({:.4}{}) / {}", -present_value, add_future_value, periods);
let symbolic_formula = "(-pv - fv) / n".to_string();
(formula, symbolic_formula)
}
} else {
let (formula_num, symbolic_formula_num) = if future_value == 0.0 {
(format!("({:.4} * {:.6}^{} * {:.6})", present_value, rate_multiplier, periods, -rate), "(pv * (1 + r)^n * -r)".to_string())
} else if present_value == 0.0 {
(format!("({:.4} * {:.6})", future_value, -rate), "(fv * -r)".to_string())
} else {
let add_future_value = if future_value > 0.0 {
format!(" + {:.4}", future_value)
} else {
format!(" - {:.4}", 0.0 - future_value)
};
(format!("((({:.4} * {:.6}^{}){}) * {:.6})", present_value, rate_multiplier, periods, add_future_value, -rate), "(((pv * (1 + r)^n) + fv) * -r)".to_string())
};
let mut formula_denom = format!("({:.6}^{} - 1)", rate_multiplier, periods);
let mut symbolic_formula_denom = "((1 + r)^n - 1)".to_string();
if due_at_beginning {
formula_denom = format!("({} * {:.6})", formula_denom, rate_multiplier);
symbolic_formula_denom = format!("({} * (1 + r))", symbolic_formula_denom);
}
(format!("{} / {}", formula_num, formula_denom), format!("{} / {}", symbolic_formula_num, symbolic_formula_denom))
};
formula = format!("{:.4} = {}", payment, formula);
symbolic_formula = format!("pmt = {}", symbolic_formula);
(formula, symbolic_formula)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_payment_due_at_end_nominal() {
assert_approx_equal!(-11.9636085342686f64, payment(0.034, 10, 100.0, 0.0, false));
assert_approx_equal!(-8.22683411973293f64, payment(-0.034, 10, 100.0, 0.0, false));
assert_approx_equal!(11.9636085342686f64, payment(0.034, 10, -100.0, 0.0, false));
assert_approx_equal!(-100.097751710655f64, payment(1.0, 10, 100.0, 0.0, false));
assert_approx_equal!(-150.01573028944f64, payment(1.5, 10, 100.0, 0.0, false));
assert_approx_equal!(-10f64, payment(0.0, 10, 100.0, 0.0, false));
assert_approx_equal!(-10.00055000825f64, payment(0.00001, 10, 100.0, 0.0, false));
assert_approx_equal!(8.22683411973293f64, payment(-0.034, 10, -100.0, 0.0, false));
assert_approx_equal!(9.82270640070143f64, payment(0.034, 10, -100.0, 25.0, false));
assert_approx_equal!(14.1045106678357f64, payment(0.034, 10, -100.0, -25.0, false));
assert_approx_equal!(-10f64, payment(0.0, 10, 100.0, 0.0, false));
assert_approx_equal!(-11f64, payment(0.0, 10, 100.0, 10.0, false));
assert_approx_equal!(-9f64, payment(0.0, 10, 100.0, -10.0, false));
assert_approx_equal!(-1f64, payment(0.0, 10, 10.0, 0.0, false));
assert_approx_equal!(-11f64, payment(0.0, 10, 10.0, 100.0, false));
assert_approx_equal!(9f64, payment(0.0, 10, 10.0, -100.0, false));
assert_approx_equal!(10f64, payment(0.0, 10, -100.0, 0.0, false));
assert_approx_equal!(9f64, payment(0.0, 10, -100.0, 10.0, false));
assert_approx_equal!(11f64, payment(0.0, 10, -100.0, -10.0, false));
assert_approx_equal!(1f64, payment(0.0, 10, -10.0, 0.0, false));
assert_approx_equal!(-9f64, payment(0.0, 10, -10.0, 100.0, false));
assert_approx_equal!(11f64, payment(0.0, 10, -10.0, -100.0, false));
}
#[test]
fn test_payment_due_at_beginning_nominal() {
assert_approx_equal!(-11.5702210196021f64, payment(0.034, 10, 100.0, 0.0, true));
assert_approx_equal!(-8.51639142829496f64, payment(-0.034, 10, 100.0, 0.0, true));
assert_approx_equal!(-8.51639142829496f64, payment(-0.034, 10, 100.0, 0.0, true));
assert_approx_equal!(-50.0488758553275f64, payment(1.0, 10, 100.0, 0.0, true));
assert_approx_equal!(-60.0062921157762f64, payment(1.5, 10, 100.0, 0.0, true));
assert_approx_equal!(-10f64, payment(0.0, 10, 100.0, 0.0, true));
assert_approx_equal!(-10.0004500037499f64, payment(0.00001, 10, 100.0, 0.0, true));
assert_approx_equal!(8.51639142829496f64, payment(-0.034, 10, -100.0, 0.0, true));
assert_approx_equal!(9.49971605483697f64, payment(0.034, 10, -100.0, 25.0, true));
assert_approx_equal!(13.6407259843672f64, payment(0.034, 10, -100.0, -25.0, true));
assert_approx_equal!(-10f64, payment(0.0, 10, 100.0, 0.0, true));
assert_approx_equal!(-11f64, payment(0.0, 10, 100.0, 10.0, true));
assert_approx_equal!(-9f64, payment(0.0, 10, 100.0, -10.0, true));
assert_approx_equal!(-1f64, payment(0.0, 10, 10.0, 0.0, true));
assert_approx_equal!(-11f64, payment(0.0, 10, 10.0, 100.0, true));
assert_approx_equal!(9f64, payment(0.0, 10, 10.0, -100.0, true));
assert_approx_equal!(10f64, payment(0.0, 10, -100.0, 0.0, true));
assert_approx_equal!(9f64, payment(0.0, 10, -100.0, 10.0, true));
assert_approx_equal!(11f64, payment(0.0, 10, -100.0, -10.0, true));
assert_approx_equal!(1f64, payment(0.0, 10, -10.0, 0.0, true));
assert_approx_equal!(-9f64, payment(0.0, 10, -10.0, 100.0, true));
assert_approx_equal!(11f64, payment(0.0, 10, -10.0, -100.0, true));
}
fn run_payment_invariants(solution: &PaymentSolution, series: &PaymentSeries) {
let result = std::panic::catch_unwind(|| {
solution.invariant();
series.invariant(solution);
});
if result.is_err() {
dbg!(&solution, &series);
solution.invariant();
series.invariant(solution);
}
}
#[test]
fn test_against_excel_ipmt_month_1() {
let solution = payment_solution(0.0056, 12, 20000.0, 0.0, false);
assert_approx_equal!(-1727.95439349254, solution.payment());
let series = solution.series();
assert_approx_equal!(-112.0, series[0].interest());
assert_approx_equal!(-102.950655396442, series[1].interest());
assert_approx_equal!(-93.8506344631036, series[2].interest());
assert_approx_equal!(-84.6996534125387, series[3].interest());
assert_approx_equal!(-75.4974268680907, series[4].interest());
assert_approx_equal!(-66.2436678549938, series[5].interest());
assert_approx_equal!(-56.9380877914235, series[6].interest());
assert_approx_equal!(-47.5803964794972, series[7].interest());
assert_approx_equal!(-38.1703020962241, series[8].interest());
assert_approx_equal!(-28.7075111844048, series[9].interest());
assert_approx_equal!(-19.1917286434792, series[10].interest());
assert_approx_equal!(-9.62265772032443, series[11].interest());
}
#[test]
fn test_against_excel_ipmt_month_2() {
let solution = payment_solution(0.0056, 12, 20000.0, 0.0, true);
assert_approx_equal!(-1718.33173577222, solution.payment());
let series = solution.series();
assert_approx_equal!(0.0, series[0].interest());
assert_approx_equal!(-102.377342279676, series[1].interest());
assert_approx_equal!(-93.3279976761173, series[2].interest());
assert_approx_equal!(-84.2279767427791, series[3].interest());
assert_approx_equal!(-75.0769956922143, series[4].interest());
assert_approx_equal!(-65.8747691477663, series[5].interest());
assert_approx_equal!(-56.6210101346693, series[6].interest());
assert_approx_equal!(-47.315430071099, series[7].interest());
assert_approx_equal!(-37.9577387591728, series[8].interest());
assert_approx_equal!(-28.5476443758997, series[9].interest());
assert_approx_equal!(-19.0848534640803, series[10].interest());
assert_approx_equal!(-9.56907092315476, series[11].interest());
}
#[test]
fn test_against_excel_pmt_mod_5() {
assert_approx_equal!(26063.0811111111f64, payment(-0.1, 1, -12345.67, -12345.67, true));
assert_approx_equal!(11111.103f64, payment(-0.1, 1, -12345.67, 0.0, false));
assert_approx_equal!(12208.4958888889f64, payment(-0.1, 1, -12345.67, 123.4567, true));
assert_approx_equal!(234.56773f64, payment(-0.1, 1, -123.4567, -123.4567, false));
assert_approx_equal!(123.4567f64, payment(-0.1, 1, -123.4567, 0.0, true));
assert_approx_equal!(-12234.55897f64, payment(-0.1, 1, -123.4567, 12345.67, false));
assert_approx_equal!(138.408678111111f64, payment(-0.1, 1, -1.234567, -123.4567, true));
assert_approx_equal!(-0.1234567f64, payment(-0.1, 1, -1.234567, 1.234567, false));
assert_approx_equal!(-13716.1765441111f64, payment(-0.1, 1, -1.234567, 12345.67, true));
assert_approx_equal!(1.234567f64, payment(-0.1, 1, 0.0, -1.234567, false));
assert_approx_equal!(-1.37174111111111f64, payment(-0.1, 1, 0.0, 1.234567, true));
assert_approx_equal!(12344.5588897f64, payment(-0.1, 1, 1.234567, -12345.67, false));
assert_approx_equal!(0.137174111111111f64, payment(-0.1, 1, 1.234567, -1.234567, true));
assert_approx_equal!(-124.5678103f64, payment(-0.1, 1, 1.234567, 123.4567, false));
assert_approx_equal!(13593.9544111111f64, payment(-0.1, 1, 123.4567, -12345.67, true));
assert_approx_equal!(-111.11103f64, payment(-0.1, 1, 123.4567, 0.0, false));
assert_approx_equal!(-260.630811111111f64, payment(-0.1, 1, 123.4567, 123.4567, true));
assert_approx_equal!(-10987.6463f64, payment(-0.1, 1, 12345.67, -123.4567, false));
assert_approx_equal!(-12345.67f64, payment(-0.1, 1, 12345.67, 0.0, true));
assert_approx_equal!(-23456.773f64, payment(-0.1, 1, 12345.67, 12345.67, false));
assert_approx_equal!(5920.14584795322f64, payment(-0.1, 2, -12345.67, -123.4567, true));
assert_approx_equal!(5262.50428052632f64, payment(-0.1, 2, -12345.67, 1.234567, false));
assert_approx_equal!(-1371.74111111111f64, payment(-0.1, 2, -12345.67, 12345.67, true));
assert_approx_equal!(53.2813126315789f64, payment(-0.1, 2, -123.4567, -1.234567, false));
assert_approx_equal!(57.7575204678363f64, payment(-0.1, 2, -123.4567, 1.234567, true));
assert_approx_equal!(6498.24736803684f64, payment(-0.1, 2, -1.234567, -12345.67, false));
assert_approx_equal!(1.3067639005848f64, payment(-0.1, 2, -1.234567, -1.234567, true));
assert_approx_equal!(-64.4508951210526f64, payment(-0.1, 2, -1.234567, 123.4567, false));
assert_approx_equal!(7219.69005847953f64, payment(-0.1, 2, 0.0, -12345.67, true));
assert_approx_equal!(0f64, payment(-0.1, 2, 0.0, 0.0, false));
assert_approx_equal!(-72.1969005847953f64, payment(-0.1, 2, 0.0, 123.4567, true));
assert_approx_equal!(64.4508951210526f64, payment(-0.1, 2, 1.234567, -123.4567, false));
assert_approx_equal!(-0.584794894736842f64, payment(-0.1, 2, 1.234567, 0.0, true));
assert_approx_equal!(-6498.24736803684f64, payment(-0.1, 2, 1.234567, 12345.67, false));
assert_approx_equal!(13.7174111111111f64, payment(-0.1, 2, 123.4567, -123.4567, true));
assert_approx_equal!(-53.2813126315789f64, payment(-0.1, 2, 123.4567, 1.234567, false));
assert_approx_equal!(-7278.16954795322f64, payment(-0.1, 2, 123.4567, 12345.67, true));
assert_approx_equal!(-5262.50428052632f64, payment(-0.1, 2, 12345.67, -1.234567, false));
assert_approx_equal!(-5848.67091637427f64, payment(-0.1, 2, 12345.67, 1.234567, true));
assert_approx_equal!(4794.91701748431f64, payment(-0.1, 5, -12345.67, -12345.67, false));
assert_approx_equal!(1978.30720327003f64, payment(-0.1, 5, -12345.67, -1.234567, true));
assert_approx_equal!(1750.02758865473f64, payment(-0.1, 5, -12345.67, 123.4567, false));
assert_approx_equal!(3369.4930653662f64, payment(-0.1, 5, -123.4567, -12345.67, true));
assert_approx_equal!(17.8017500874216f64, payment(-0.1, 5, -123.4567, 0.0, false));
assert_approx_equal!(-13.7174111111111f64, payment(-0.1, 5, -123.4567, 123.4567, true));
assert_approx_equal!(30.3254375882958f64, payment(-0.1, 5, -1.234567, -123.4567, false));
assert_approx_equal!(0.197797223193573f64, payment(-0.1, 5, -1.234567, 0.0, true));
assert_approx_equal!(-3014.56399124128f64, payment(-0.1, 5, -1.234567, 12345.67, false));
assert_approx_equal!(33.4971334304684f64, payment(-0.1, 5, 0.0, -123.4567, true));
assert_approx_equal!(-0.301474200874216f64, payment(-0.1, 5, 0.0, 1.234567, false));
assert_approx_equal!(-3349.71334304684f64, payment(-0.1, 5, 0.0, 12345.67, true));
assert_approx_equal!(0.1234567f64, payment(-0.1, 5, 1.234567, -1.234567, false));
assert_approx_equal!(-0.532768557498257f64, payment(-0.1, 5, 1.234567, 1.234567, true));
assert_approx_equal!(2996.94025865473f64, payment(-0.1, 5, 123.4567, -12345.67, false));
assert_approx_equal!(-19.4447509850526f64, payment(-0.1, 5, 123.4567, -1.234567, true));
assert_approx_equal!(-47.9491701748431f64, payment(-0.1, 5, 123.4567, 123.4567, false));
assert_approx_equal!(1371.74111111111f64, payment(-0.1, 5, 12345.67, -12345.67, true));
assert_approx_equal!(-1780.17500874216f64, payment(-0.1, 5, 12345.67, 0.0, false));
assert_approx_equal!(-2011.4693653662f64, payment(-0.1, 5, 12345.67, 123.4567, true));
assert_approx_equal!(679.867814949844f64, payment(-0.1, 10, -12345.67, -123.4567, false));
assert_approx_equal!(734.34779422425f64, payment(-0.1, 10, -12345.67, 0.0, true));
assert_approx_equal!(-1234.567f64, payment(-0.1, 10, -12345.67, 12345.67, false));
assert_approx_equal!(28.4043669955961f64, payment(-0.1, 10, -123.4567, -123.4567, true));
assert_approx_equal!(6.41958214653807f64, payment(-0.1, 10, -123.4567, 1.234567, false));
assert_approx_equal!(-2098.74542739312f64, payment(-0.1, 10, -123.4567, 12345.67, true));
assert_approx_equal!(0.255639302960365f64, payment(-0.1, 10, -1.234567, -1.234567, false));
assert_approx_equal!(-0.137174111111111f64, payment(-0.1, 10, -1.234567, 1.234567, true));
assert_approx_equal!(1895.48001480183f64, payment(-0.1, 10, 0.0, -12345.67, false));
assert_approx_equal!(0.210608890533536f64, payment(-0.1, 10, 0.0, -1.234567, true));
assert_approx_equal!(-18.9548001480183f64, payment(-0.1, 10, 0.0, 123.4567, false));
assert_approx_equal!(2106.01547055594f64, payment(-0.1, 10, 1.234567, -12345.67, true));
assert_approx_equal!(-0.0660913014801825f64, payment(-0.1, 10, 1.234567, 0.0, false));
assert_approx_equal!(-21.134323832776f64, payment(-0.1, 10, 1.234567, 123.4567, true));
assert_approx_equal!(12.34567f64, payment(-0.1, 10, 123.4567, -123.4567, false));
assert_approx_equal!(-7.3434779422425f64, payment(-0.1, 10, 123.4567, 0.0, true));
assert_approx_equal!(-1902.08914494984f64, payment(-0.1, 10, 123.4567, 12345.67, false));
assert_approx_equal!(-713.286905170897f64, payment(-0.1, 10, 12345.67, -123.4567, true));
assert_approx_equal!(-661.102562803305f64, payment(-0.1, 10, 12345.67, 1.234567, false));
assert_approx_equal!(-2840.43669955961f64, payment(-0.1, 10, 12345.67, 12345.67, true));
assert_approx_equal!(6.51973876437762f64, payment(-0.1, 50, -12345.67, -1.234567, false));
assert_approx_equal!(6.96838470653066f64, payment(-0.1, 50, -12345.67, 1.234567, true));
assert_approx_equal!(1241.02659892513f64, payment(-0.1, 50, -123.4567, -12345.67, false));
assert_approx_equal!(0.208947432501432f64, payment(-0.1, 50, -123.4567, -1.234567, true));
assert_approx_equal!(-12.34567f64, payment(-0.1, 50, -123.4567, 123.4567, false));
assert_approx_equal!(1378.84809118264f64, payment(-0.1, 50, -1.234567, -12345.67, true));
assert_approx_equal!(0.000639564250012761f64, payment(-0.1, 50, -1.234567, 0.0, false));
assert_approx_equal!(-13.7877631786125f64, payment(-0.1, 50, -1.234567, 123.4567, true));
assert_approx_equal!(12.4096264250013f64, payment(-0.1, 50, 0.0, -123.4567, false));
assert_approx_equal!(0f64, payment(-0.1, 50, 0.0, 0.0, true));
assert_approx_equal!(-1240.96264250013f64, payment(-0.1, 50, 0.0, 12345.67, false));
assert_approx_equal!(13.7877631786125f64, payment(-0.1, 50, 1.234567, -123.4567, true));
assert_approx_equal!(-0.124735828500026f64, payment(-0.1, 50, 1.234567, 1.234567, false));
assert_approx_equal!(-1378.84809118264f64, payment(-0.1, 50, 1.234567, 12345.67, true));
assert_approx_equal!(0.0601398392487366f64, payment(-0.1, 50, 123.4567, -1.234567, false));
assert_approx_equal!(-0.208947432501432f64, payment(-0.1, 50, 123.4567, 1.234567, true));
assert_approx_equal!(1234.567f64, payment(-0.1, 50, 12345.67, -12345.67, false));
assert_approx_equal!(-6.96838470653066f64, payment(-0.1, 50, 12345.67, -1.234567, true));
assert_approx_equal!(-18.8052689251289f64, payment(-0.1, 50, 12345.67, 123.4567, false));
assert_approx_equal!(1371.74111112109f64, payment(-0.1, 250, -12345.67, -12345.67, true));
assert_approx_equal!(4.48892163617149E-09f64, payment(-0.1, 250, -12345.67, 0.0, false));
assert_approx_equal!(-13.7174111061733f64, payment(-0.1, 250, -12345.67, 123.4567, true));
assert_approx_equal!(12.3456700000898f64, payment(-0.1, 250, -123.4567, -123.4567, false));
assert_approx_equal!(4.98769070685721E-11f64, payment(-0.1, 250, -123.4567, 0.0, true));
assert_approx_equal!(-1234.56700000444f64, payment(-0.1, 250, -123.4567, 12345.67, false));
assert_approx_equal!(13.7174111111615f64, payment(-0.1, 250, -1.234567, -123.4567, true));
assert_approx_equal!(-0.1234567f64, payment(-0.1, 250, -1.234567, 1.234567, false));
assert_approx_equal!(-1371.7411111161f64, payment(-0.1, 250, -1.234567, 12345.67, true));
assert_approx_equal!(0.123456700000449f64, payment(-0.1, 250, 0.0, -1.234567, false));
assert_approx_equal!(-0.13717411111161f64, payment(-0.1, 250, 0.0, 1.234567, true));
assert_approx_equal!(1234.56700000449f64, payment(-0.1, 250, 1.234567, -12345.67, false));
assert_approx_equal!(0.137174111111111f64, payment(-0.1, 250, 1.234567, -1.234567, true));
assert_approx_equal!(-12.3456700000453f64, payment(-0.1, 250, 1.234567, 123.4567, false));
assert_approx_equal!(1371.74111111605f64, payment(-0.1, 250, 123.4567, -12345.67, true));
assert_approx_equal!(-4.48892163617149E-11f64, payment(-0.1, 250, 123.4567, 0.0, false));
assert_approx_equal!(-13.7174111112109f64, payment(-0.1, 250, 123.4567, 123.4567, true));
assert_approx_equal!(12.345669995556f64, payment(-0.1, 250, 12345.67, -123.4567, false));
assert_approx_equal!(-4.98769070685721E-09f64, payment(-0.1, 250, 12345.67, 0.0, true));
assert_approx_equal!(-1234.56700000898f64, payment(-0.1, 250, 12345.67, 12345.67, false));
assert_approx_equal!(12223.447867f64, payment(-0.01, 1, -12345.67, -1.234567, false));
assert_approx_equal!(12344.4229626263f64, payment(-0.01, 1, -12345.67, 1.234567, true));
assert_approx_equal!(12467.892133f64, payment(-0.01, 1, -123.4567, -12345.67, false));
assert_approx_equal!(124.703737373737f64, payment(-0.01, 1, -123.4567, -1.234567, true));
assert_approx_equal!(-1.234567f64, payment(-0.01, 1, -123.4567, 123.4567, false));
assert_approx_equal!(12471.6083043737f64, payment(-0.01, 1, -1.234567, -12345.67, true));
assert_approx_equal!(1.22222133f64, payment(-0.01, 1, -1.234567, 0.0, false));
assert_approx_equal!(-123.469170373737f64, payment(-0.01, 1, -1.234567, 123.4567, true));
assert_approx_equal!(123.4567f64, payment(-0.01, 1, 0.0, -123.4567, false));
assert_approx_equal!(0f64, payment(-0.01, 1, 0.0, 0.0, true));
assert_approx_equal!(-12345.67f64, payment(-0.01, 1, 0.0, 12345.67, false));
assert_approx_equal!(123.469170373737f64, payment(-0.01, 1, 1.234567, -123.4567, true));
assert_approx_equal!(-2.45678833f64, payment(-0.01, 1, 1.234567, 1.234567, false));
assert_approx_equal!(-12471.6083043737f64, payment(-0.01, 1, 1.234567, 12345.67, true));
assert_approx_equal!(-120.987566f64, payment(-0.01, 1, 123.4567, -1.234567, false));
assert_approx_equal!(-124.703737373737f64, payment(-0.01, 1, 123.4567, 1.234567, true));
assert_approx_equal!(123.4567f64, payment(-0.01, 1, 12345.67, -12345.67, false));
assert_approx_equal!(-12344.4229626263f64, payment(-0.01, 1, 12345.67, -1.234567, true));
assert_approx_equal!(-12345.67f64, payment(-0.01, 1, 12345.67, 123.4567, false));
assert_approx_equal!(12408.3351946602f64, payment(-0.01, 2, -12345.67, -12345.67, true));
assert_approx_equal!(6080.39757135678f64, payment(-0.01, 2, -12345.67, 0.0, false));
assert_approx_equal!(6079.15053398305f64, payment(-0.01, 2, -12345.67, 123.4567, true));
assert_approx_equal!(122.842518427136f64, payment(-0.01, 2, -123.4567, -123.4567, false));
assert_approx_equal!(61.4181572864322f64, payment(-0.01, 2, -123.4567, 0.0, true));
assert_approx_equal!(-6143.05029564322f64, payment(-0.01, 2, -123.4567, 12345.67, false));
assert_approx_equal!(63.2793762330339f64, payment(-0.01, 2, -1.234567, -123.4567, true));
assert_approx_equal!(-0.01234567f64, payment(-0.01, 2, -1.234567, 1.234567, false));
assert_approx_equal!(-6265.90528444409f64, payment(-0.01, 2, -1.234567, 12345.67, true));
assert_approx_equal!(0.620385427135678f64, payment(-0.01, 2, 0.0, -1.234567, false));
assert_approx_equal!(-0.626651946601695f64, payment(-0.01, 2, 0.0, 1.234567, true));
assert_approx_equal!(6203.24623159965f64, payment(-0.01, 2, 1.234567, -12345.67, false));
assert_approx_equal!(0.0124703737373737f64, payment(-0.01, 2, 1.234567, -1.234567, true));
assert_approx_equal!(-62.6465824707035f64, payment(-0.01, 2, 1.234567, 123.4567, false));
assert_approx_equal!(6205.10130873052f64, payment(-0.01, 2, 123.4567, -12345.67, true));
assert_approx_equal!(-60.8039757135678f64, payment(-0.01, 2, 123.4567, 0.0, false));
assert_approx_equal!(-124.083351946602f64, payment(-0.01, 2, 123.4567, 123.4567, true));
assert_approx_equal!(-6018.35902864322f64, payment(-0.01, 2, 12345.67, -123.4567, false));
assert_approx_equal!(-6141.81572864322f64, payment(-0.01, 2, 12345.67, 0.0, true));
assert_approx_equal!(-12284.2518427136f64, payment(-0.01, 2, 12345.67, 12345.67, false));
assert_approx_equal!(2445.19838434817f64, payment(-0.01, 5, -12345.67, -123.4567, true));
assert_approx_equal!(2395.30436949964f64, payment(-0.01, 5, -12345.67, 1.234567, false));
assert_approx_equal!(-124.703737373737f64, payment(-0.01, 5, -12345.67, 12345.67, true));
assert_approx_equal!(24.2074640050469f64, payment(-0.01, 5, -123.4567, -1.234567, false));
assert_approx_equal!(23.9430923342298f64, payment(-0.01, 5, -123.4567, 1.234567, true));
assert_approx_equal!(2519.2525264238f64, payment(-0.01, 5, -1.234567, -12345.67, false));
assert_approx_equal!(0.496421135514489f64, payment(-0.01, 5, -1.234567, -1.234567, true));
assert_approx_equal!(-24.9505740808875f64, payment(-0.01, 5, -1.234567, 123.4567, false));
assert_approx_equal!(2544.45754625931f64, payment(-0.01, 5, 0.0, -12345.67, true));
assert_approx_equal!(0f64, payment(-0.01, 5, 0.0, 0.0, false));
assert_approx_equal!(-25.4445754625931f64, payment(-0.01, 5, 0.0, 123.4567, true));
assert_approx_equal!(24.9505740808875f64, payment(-0.01, 5, 1.234567, -123.4567, false));
assert_approx_equal!(-0.241975380888558f64, payment(-0.01, 5, 1.234567, 0.0, true));
assert_approx_equal!(-2519.2525264238f64, payment(-0.01, 5, 1.234567, 12345.67, false));
assert_approx_equal!(1.24703737373737f64, payment(-0.01, 5, 123.4567, -123.4567, true));
assert_approx_equal!(-24.2074640050469f64, payment(-0.01, 5, 123.4567, 1.234567, false));
assert_approx_equal!(-2568.65508434817f64, payment(-0.01, 5, 123.4567, 12345.67, true));
assert_approx_equal!(-2395.30436949964f64, payment(-0.01, 5, 12345.67, -1.234567, false));
assert_approx_equal!(-2420.0082546402f64, payment(-0.01, 5, 12345.67, 1.234567, true));
assert_approx_equal!(2458.83527112085f64, payment(-0.01, 10, -12345.67, -12345.67, false));
assert_approx_equal!(1179.61454561513f64, payment(-0.01, 10, -12345.67, -1.234567, true));
assert_approx_equal!(1154.77782570482f64, payment(-0.01, 10, -12345.67, 123.4567, false));
assert_approx_equal!(1315.98270547074f64, payment(-0.01, 10, -123.4567, -12345.67, true));
assert_approx_equal!(11.6768928556043f64, payment(-0.01, 10, -123.4567, 0.0, false));
assert_approx_equal!(-1.24703737373737f64, payment(-0.01, 10, -123.4567, 123.4567, true));
assert_approx_equal!(13.0282287841603f64, payment(-0.01, 10, -1.234567, -123.4567, false));
assert_approx_equal!(0.117948412682871f64, payment(-0.01, 10, -1.234567, 0.0, true));
assert_approx_equal!(-1291.02921663187f64, payment(-0.01, 10, -1.234567, 12345.67, false));
assert_approx_equal!(13.0418786420245f64, payment(-0.01, 10, 0.0, -123.4567, true));
assert_approx_equal!(-0.129114598556043f64, payment(-0.01, 10, 0.0, 1.234567, false));
assert_approx_equal!(-1304.18786420245f64, payment(-0.01, 10, 0.0, 12345.67, true));
assert_approx_equal!(0.01234567f64, payment(-0.01, 10, 1.234567, -1.234567, false));
assert_approx_equal!(-0.248367199103116f64, payment(-0.01, 10, 1.234567, 1.234567, true));
assert_approx_equal!(1279.46909270482f64, payment(-0.01, 10, 123.4567, -12345.67, false));
assert_approx_equal!(-11.6644224818669f64, payment(-0.01, 10, 123.4567, -1.234567, true));
assert_approx_equal!(-24.5883527112085f64, payment(-0.01, 10, 123.4567, 123.4567, false));
assert_approx_equal!(124.703737373737f64, payment(-0.01, 10, 12345.67, -12345.67, true));
assert_approx_equal!(-1167.68928556043f64, payment(-0.01, 10, 12345.67, 0.0, false));
assert_approx_equal!(-1192.52600547074f64, payment(-0.01, 10, 12345.67, 123.4567, true));
assert_approx_equal!(192.222242449522f64, payment(-0.01, 50, -12345.67, -123.4567, false));
assert_approx_equal!(191.006776127135f64, payment(-0.01, 50, -12345.67, 0.0, true));
assert_approx_equal!(-123.4567f64, payment(-0.01, 50, -12345.67, 12345.67, false));
assert_approx_equal!(5.06717289628007f64, payment(-0.01, 50, -123.4567, -123.4567, true));
assert_approx_equal!(1.85971174282205f64, payment(-0.01, 50, -123.4567, 1.234567, false));
assert_approx_equal!(-313.800445739601f64, payment(-0.01, 50, -123.4567, 12345.67, true));
assert_approx_equal!(0.0501650116731727f64, payment(-0.01, 50, -1.234567, -1.234567, false));
assert_approx_equal!(-0.0124703737373737f64, payment(-0.01, 50, -1.234567, 1.234567, true));
assert_approx_equal!(312.553408365864f64, payment(-0.01, 50, 0.0, -12345.67, false));
assert_approx_equal!(0.0315710513500872f64, payment(-0.01, 50, 0.0, -1.234567, true));
assert_approx_equal!(-3.12553408365864f64, payment(-0.01, 50, 0.0, 123.4567, false));
assert_approx_equal!(315.69141282326f64, payment(-0.01, 50, 1.234567, -12345.67, true));
assert_approx_equal!(-0.0189096708365864f64, payment(-0.01, 50, 1.234567, 0.0, false));
assert_approx_equal!(-3.17620581262144f64, payment(-0.01, 50, 1.234567, 123.4567, true));
assert_approx_equal!(1.234567f64, payment(-0.01, 50, 123.4567, -123.4567, false));
assert_approx_equal!(-1.91006776127135f64, payment(-0.01, 50, 123.4567, 0.0, true));
assert_approx_equal!(-314.444375449522f64, payment(-0.01, 50, 123.4567, 12345.67, false));
assert_approx_equal!(-187.849670992126f64, payment(-0.01, 50, 12345.67, -123.4567, true));
assert_approx_equal!(-189.1279637067f64, payment(-0.01, 50, 12345.67, 1.234567, false));
assert_approx_equal!(-506.717289628007f64, payment(-0.01, 50, 12345.67, 12345.67, true));
assert_approx_equal!(10.9033738910495f64, payment(-0.01, 250, -12345.67, -1.234567, false));
assert_approx_equal!(10.9863682456607f64, payment(-0.01, 250, -12345.67, 1.234567, true));
assert_approx_equal!(134.455538619398f64, payment(-0.01, 250, -123.4567, -12345.67, false));
assert_approx_equal!(0.123569753731294f64, payment(-0.01, 250, -123.4567, -1.234567, true));
assert_approx_equal!(-1.234567f64, payment(-0.01, 250, -123.4567, 123.4567, false));
assert_approx_equal!(135.704775980858f64, payment(-0.01, 250, -1.234567, -12345.67, true));
assert_approx_equal!(0.00108899392271268f64, payment(-0.01, 250, -1.234567, 0.0, false));
assert_approx_equal!(-1.35593676600864f64, payment(-0.01, 250, -1.234567, 123.4567, true));
assert_approx_equal!(1.34346639227127f64, payment(-0.01, 250, 0.0, -123.4567, false));
assert_approx_equal!(0f64, payment(-0.01, 250, 0.0, 0.0, true));
assert_approx_equal!(-134.346639227127f64, payment(-0.01, 250, 0.0, 12345.67, false));
assert_approx_equal!(1.35593676600864f64, payment(-0.01, 250, 1.234567, -123.4567, true));
assert_approx_equal!(-0.0145236578454254f64, payment(-0.01, 250, 1.234567, 1.234567, false));
assert_approx_equal!(-135.704775980858f64, payment(-0.01, 250, 1.234567, 12345.67, true));
assert_approx_equal!(-0.0954647283485555f64, payment(-0.01, 250, 123.4567, -1.234567, false));
assert_approx_equal!(-0.123569753731294f64, payment(-0.01, 250, 123.4567, 1.234567, true));
assert_approx_equal!(123.4567f64, payment(-0.01, 250, 12345.67, -12345.67, false));
assert_approx_equal!(-10.9863682456607f64, payment(-0.01, 250, 12345.67, -1.234567, true));
assert_approx_equal!(-12.2334056193981f64, payment(-0.01, 250, 12345.67, 123.4567, false));
assert_approx_equal!(12456.78103f64, payment(-0.001, 1, -12345.67, -123.4567, false));
assert_approx_equal!(12345.67f64, payment(-0.001, 1, -12345.67, 0.0, true));
assert_approx_equal!(-12.34567f64, payment(-0.001, 1, -12345.67, 12345.67, false));
assert_approx_equal!(247.03698028028f64, payment(-0.001, 1, -123.4567, -123.4567, true));
assert_approx_equal!(122.0986763f64, payment(-0.001, 1, -123.4567, 1.234567, false));
assert_approx_equal!(-12234.571328028f64, payment(-0.001, 1, -123.4567, 12345.67, true));
assert_approx_equal!(2.467899433f64, payment(-0.001, 1, -1.234567, -1.234567, false));
assert_approx_equal!(-0.0012358028028028f64, payment(-0.001, 1, -1.234567, 1.234567, true));
assert_approx_equal!(12345.67f64, payment(-0.001, 1, 0.0, -12345.67, false));
assert_approx_equal!(1.2358028028028f64, payment(-0.001, 1, 0.0, -1.234567, true));
assert_approx_equal!(-123.4567f64, payment(-0.001, 1, 0.0, 123.4567, false));
assert_approx_equal!(12356.793461028f64, payment(-0.001, 1, 1.234567, -12345.67, true));
assert_approx_equal!(-1.233332433f64, payment(-0.001, 1, 1.234567, 0.0, false));
assert_approx_equal!(-124.81484728028f64, payment(-0.001, 1, 1.234567, 123.4567, true));
assert_approx_equal!(0.1234567f64, payment(-0.001, 1, 123.4567, -123.4567, false));
assert_approx_equal!(-123.4567f64, payment(-0.001, 1, 123.4567, 0.0, true));
assert_approx_equal!(-12469.0032433f64, payment(-0.001, 1, 123.4567, 12345.67, false));
assert_approx_equal!(-12222.0897197197f64, payment(-0.001, 1, 12345.67, -123.4567, true));
assert_approx_equal!(-12334.558897f64, payment(-0.001, 1, 12345.67, 1.234567, false));
assert_approx_equal!(-24703.698028028f64, payment(-0.001, 1, 12345.67, 12345.67, true));
assert_approx_equal!(6164.19488377689f64, payment(-0.001, 2, -12345.67, -1.234567, false));
assert_approx_equal!(6169.12882801261f64, payment(-0.001, 2, -12345.67, 1.234567, true));
assert_approx_equal!(6237.55873439555f64, payment(-0.001, 2, -123.4567, -12345.67, false));
assert_approx_equal!(62.3156808918473f64, payment(-0.001, 2, -123.4567, -1.234567, true));
assert_approx_equal!(-0.1234567f64, payment(-0.001, 2, -123.4567, 123.4567, false));
assert_approx_equal!(6182.72204125114f64, payment(-0.001, 2, -1.234567, -12345.67, true));
assert_approx_equal!(0.616357729148074f64, payment(-0.001, 2, -1.234567, 0.0, false));
assert_approx_equal!(-61.204075961621f64, payment(-0.001, 2, -1.234567, 123.4567, true));
assert_approx_equal!(61.7592296148074f64, payment(-0.001, 2, 0.0, -123.4567, false));
assert_approx_equal!(0f64, payment(-0.001, 2, 0.0, 0.0, true));
assert_approx_equal!(-6175.92296148074f64, payment(-0.001, 2, 0.0, 12345.67, false));
assert_approx_equal!(61.204075961621f64, payment(-0.001, 2, 1.234567, -123.4567, true));
assert_approx_equal!(-1.23395002529615f64, payment(-0.001, 2, 1.234567, 1.234567, false));
assert_approx_equal!(-6182.72204125114f64, payment(-0.001, 2, 1.234567, 12345.67, true));
assert_approx_equal!(-61.0181806186593f64, payment(-0.001, 2, 123.4567, -1.234567, false));
assert_approx_equal!(-62.3156808918473f64, payment(-0.001, 2, 123.4567, 1.234567, true));
assert_approx_equal!(12.34567f64, payment(-0.001, 2, 12345.67, -12345.67, false));
assert_approx_equal!(-6169.12882801261f64, payment(-0.001, 2, 12345.67, -1.234567, true));
assert_approx_equal!(-6225.33652109555f64, payment(-0.001, 2, 12345.67, 123.4567, false));
assert_approx_equal!(4940.74949697025f64, payment(-0.001, 5, -12345.67, -12345.67, true));
assert_approx_equal!(2461.73153873664f64, payment(-0.001, 5, -12345.67, 0.0, false));
assert_approx_equal!(2439.43019684612f64, payment(-0.001, 5, -12345.67, 123.4567, true));
assert_approx_equal!(49.3580874747328f64, payment(-0.001, 5, -123.4567, -123.4567, false));
assert_approx_equal!(24.6419573447111f64, payment(-0.001, 5, -123.4567, 0.0, true));
assert_approx_equal!(-2449.45989334927f64, payment(-0.001, 5, -123.4567, 12345.67, false));
assert_approx_equal!(25.0119571984385f64, payment(-0.001, 5, -1.234567, -123.4567, true));
assert_approx_equal!(-0.001234567f64, payment(-0.001, 5, -1.234567, 1.234567, false));
assert_approx_equal!(-2476.30734292569f64, payment(-0.001, 5, -1.234567, 12345.67, true));
assert_approx_equal!(0.247407720873664f64, payment(-0.001, 5, 0.0, -1.234567, false));
assert_approx_equal!(-0.247655376249914f64, payment(-0.001, 5, 0.0, 1.234567, true));
assert_approx_equal!(2473.83103558276f64, payment(-0.001, 5, 1.234567, -12345.67, false));
assert_approx_equal!(0.0012358028028028f64, payment(-0.001, 5, 1.234567, -1.234567, true));
assert_approx_equal!(-24.98694524124f64, payment(-0.001, 5, 1.234567, 123.4567, false));
assert_approx_equal!(2451.91180515443f64, payment(-0.001, 5, 123.4567, -12345.67, true));
assert_approx_equal!(-24.6173153873664f64, payment(-0.001, 5, 123.4567, 0.0, false));
assert_approx_equal!(-49.4074949697025f64, payment(-0.001, 5, 123.4567, 123.4567, true));
assert_approx_equal!(-2436.99076664927f64, payment(-0.001, 5, 12345.67, -123.4567, false));
assert_approx_equal!(-2464.19573447111f64, payment(-0.001, 5, 12345.67, 0.0, true));
assert_approx_equal!(-4935.80874747328f64, payment(-0.001, 5, 12345.67, 12345.67, false));
assert_approx_equal!(1241.42982900313f64, payment(-0.001, 10, -12345.67, -123.4567, true));
assert_approx_equal!(1227.66305848239f64, payment(-0.001, 10, -12345.67, 1.234567, false));
assert_approx_equal!(-12.358028028028f64, payment(-0.001, 10, -12345.67, 12345.67, true));
assert_approx_equal!(12.4018839917413f64, payment(-0.001, 10, -123.4567, -1.234567, false));
assert_approx_equal!(12.1660234668569f64, payment(-0.001, 10, -123.4567, 1.234567, true));
assert_approx_equal!(1240.25552046374f64, payment(-0.001, 10, -1.234567, -12345.67, false));
assert_approx_equal!(0.247039020371685f64, payment(-0.001, 10, -1.234567, -1.234567, true));
assert_approx_equal!(-12.27854871039f64, payment(-0.001, 10, -1.234567, 123.4567, false));
assert_approx_equal!(1241.37411587244f64, payment(-0.001, 10, 0.0, -12345.67, true));
assert_approx_equal!(0f64, payment(-0.001, 10, 0.0, 0.0, false));
assert_approx_equal!(-12.4137411587244f64, payment(-0.001, 10, 0.0, 123.4567, true));
assert_approx_equal!(12.27854871039f64, payment(-0.001, 10, 1.234567, -123.4567, false));
assert_approx_equal!(-0.122901608784441f64, payment(-0.001, 10, 1.234567, 0.0, true));
assert_approx_equal!(-1240.25552046374f64, payment(-0.001, 10, 1.234567, 12345.67, false));
assert_approx_equal!(0.12358028028028f64, payment(-0.001, 10, 123.4567, -123.4567, true));
assert_approx_equal!(-12.4018839917413f64, payment(-0.001, 10, 123.4567, 1.234567, false));
assert_approx_equal!(-1253.66427675088f64, payment(-0.001, 10, 123.4567, 12345.67, true));
assert_approx_equal!(-1227.66305848239f64, payment(-0.001, 10, 12345.67, -1.234567, false));
assert_approx_equal!(-1229.140225256f64, payment(-0.001, 10, 12345.67, 1.234567, true));
assert_approx_equal!(493.682773192249f64, payment(-0.001, 50, -12345.67, -12345.67, false));
assert_approx_equal!(240.93478780609f64, payment(-0.001, 50, -12345.67, -1.234567, true));
assert_approx_equal!(238.138409380163f64, payment(-0.001, 50, -12345.67, 123.4567, false));
assert_approx_equal!(255.676583695782f64, payment(-0.001, 50, -123.4567, -12345.67, true));
assert_approx_equal!(2.40668551596125f64, payment(-0.001, 50, -123.4567, 0.0, false));
assert_approx_equal!(-0.12358028028028f64, payment(-0.001, 50, -123.4567, 123.4567, true));
assert_approx_equal!(2.55420907112086f64, payment(-0.001, 50, -1.234567, -123.4567, false));
assert_approx_equal!(0.0240909461057182f64, payment(-0.001, 50, -1.234567, 0.0, true));
assert_approx_equal!(-252.990154740965f64, payment(-0.001, 50, -1.234567, 12345.67, false));
assert_approx_equal!(2.5326748908521f64, payment(-0.001, 50, 0.0, -123.4567, true));
assert_approx_equal!(-0.0253014221596125f64, payment(-0.001, 50, 0.0, 1.234567, false));
assert_approx_equal!(-253.26748908521f64, payment(-0.001, 50, 0.0, 12345.67, true));
assert_approx_equal!(0.001234567f64, payment(-0.001, 50, 1.234567, -1.234567, false));
assert_approx_equal!(-0.0494176950142391f64, payment(-0.001, 50, 1.234567, 1.234567, true));
assert_approx_equal!(250.607536080163f64, payment(-0.001, 50, 123.4567, -12345.67, false));
assert_approx_equal!(-2.3837678616633f64, payment(-0.001, 50, 123.4567, -1.234567, true));
assert_approx_equal!(-4.93682773192249f64, payment(-0.001, 50, 123.4567, 123.4567, false));
assert_approx_equal!(12.358028028028f64, payment(-0.001, 50, 12345.67, -12345.67, true));
assert_approx_equal!(-240.668551596125f64, payment(-0.001, 50, 12345.67, 0.0, false));
assert_approx_equal!(-243.442135948034f64, payment(-0.001, 50, 12345.67, 123.4567, true));
assert_approx_equal!(44.0000905837691f64, payment(-0.001, 250, -12345.67, -123.4567, false));
assert_approx_equal!(43.4856974635716f64, payment(-0.001, 250, -12345.67, 0.0, true));
assert_approx_equal!(-12.34567f64, payment(-0.001, 250, -12345.67, 12345.67, false));
assert_approx_equal!(0.993294229551712f64, payment(-0.001, 250, -123.4567, -123.4567, true));
assert_approx_equal!(0.42884332948447f64, payment(-0.001, 250, -123.4567, 1.234567, false));
assert_approx_equal!(-55.4088685169639f64, payment(-0.001, 250, -123.4567, 12345.67, true));
assert_approx_equal!(0.00992300935322161f64, payment(-0.001, 250, -1.234567, -1.234567, false));
assert_approx_equal!(-0.0012358028028028f64, payment(-0.001, 250, -1.234567, 1.234567, true));
assert_approx_equal!(55.787881766108f64, payment(-0.001, 250, 0.0, -12345.67, false));
assert_approx_equal!(0.00558437254915996f64, payment(-0.001, 250, 0.0, -1.234567, true));
assert_approx_equal!(-0.55787881766108f64, payment(-0.001, 250, 0.0, 123.4567, false));
assert_approx_equal!(55.8393769218533f64, payment(-0.001, 250, 1.234567, -12345.67, true));
assert_approx_equal!(-0.0043442211766108f64, payment(-0.001, 250, 1.234567, 0.0, false));
assert_approx_equal!(-0.562785824662353f64, payment(-0.001, 250, 1.234567, 123.4567, true));
assert_approx_equal!(0.1234567f64, payment(-0.001, 250, 123.4567, -123.4567, false));
assert_approx_equal!(-0.434856974635716f64, payment(-0.001, 250, 123.4567, 0.0, true));
assert_approx_equal!(-56.2223038837691f64, payment(-0.001, 250, 123.4567, 12345.67, false));
assert_approx_equal!(-42.9272602086556f64, payment(-0.001, 250, 12345.67, -123.4567, true));
assert_approx_equal!(-43.4477905542846f64, payment(-0.001, 250, 12345.67, 1.234567, false));
assert_approx_equal!(-99.3294229551712f64, payment(-0.001, 250, 12345.67, 12345.67, true));
assert_approx_equal!(24691.34f64, payment(0.0, 1, -12345.67, -12345.67, false));
assert_approx_equal!(12346.904567f64, payment(0.0, 1, -12345.67, -1.234567, true));
assert_approx_equal!(12222.2133f64, payment(0.0, 1, -12345.67, 123.4567, false));
assert_approx_equal!(12469.1267f64, payment(0.0, 1, -123.4567, -12345.67, true));
assert_approx_equal!(123.4567f64, payment(0.0, 1, -123.4567, 0.0, false));
assert_approx_equal!(0f64, payment(0.0, 1, -123.4567, 123.4567, true));
assert_approx_equal!(124.691267f64, payment(0.0, 1, -1.234567, -123.4567, false));
assert_approx_equal!(1.234567f64, payment(0.0, 1, -1.234567, 0.0, true));
assert_approx_equal!(-12344.435433f64, payment(0.0, 1, -1.234567, 12345.67, false));
assert_approx_equal!(123.4567f64, payment(0.0, 1, 0.0, -123.4567, true));
assert_approx_equal!(-1.234567f64, payment(0.0, 1, 0.0, 1.234567, false));
assert_approx_equal!(-12345.67f64, payment(0.0, 1, 0.0, 12345.67, true));
assert_approx_equal!(0f64, payment(0.0, 1, 1.234567, -1.234567, false));
assert_approx_equal!(-2.469134f64, payment(0.0, 1, 1.234567, 1.234567, true));
assert_approx_equal!(12222.2133f64, payment(0.0, 1, 123.4567, -12345.67, false));
assert_approx_equal!(-122.222133f64, payment(0.0, 1, 123.4567, -1.234567, true));
assert_approx_equal!(-246.9134f64, payment(0.0, 1, 123.4567, 123.4567, false));
assert_approx_equal!(0f64, payment(0.0, 1, 12345.67, -12345.67, true));
assert_approx_equal!(-12345.67f64, payment(0.0, 1, 12345.67, 0.0, false));
assert_approx_equal!(-12469.1267f64, payment(0.0, 1, 12345.67, 123.4567, true));
assert_approx_equal!(6234.56335f64, payment(0.0, 2, -12345.67, -123.4567, false));
assert_approx_equal!(6172.835f64, payment(0.0, 2, -12345.67, 0.0, true));
assert_approx_equal!(0f64, payment(0.0, 2, -12345.67, 12345.67, false));
assert_approx_equal!(123.4567f64, payment(0.0, 2, -123.4567, -123.4567, true));
assert_approx_equal!(61.1110665f64, payment(0.0, 2, -123.4567, 1.234567, false));
assert_approx_equal!(-6111.10665f64, payment(0.0, 2, -123.4567, 12345.67, true));
assert_approx_equal!(1.234567f64, payment(0.0, 2, -1.234567, -1.234567, false));
assert_approx_equal!(0f64, payment(0.0, 2, -1.234567, 1.234567, true));
assert_approx_equal!(6172.835f64, payment(0.0, 2, 0.0, -12345.67, false));
assert_approx_equal!(0.6172835f64, payment(0.0, 2, 0.0, -1.234567, true));
assert_approx_equal!(-61.72835f64, payment(0.0, 2, 0.0, 123.4567, false));
assert_approx_equal!(6172.2177165f64, payment(0.0, 2, 1.234567, -12345.67, true));
assert_approx_equal!(-0.6172835f64, payment(0.0, 2, 1.234567, 0.0, false));
assert_approx_equal!(-62.3456335f64, payment(0.0, 2, 1.234567, 123.4567, true));
assert_approx_equal!(0f64, payment(0.0, 2, 123.4567, -123.4567, false));
assert_approx_equal!(-61.72835f64, payment(0.0, 2, 123.4567, 0.0, true));
assert_approx_equal!(-6234.56335f64, payment(0.0, 2, 123.4567, 12345.67, false));
assert_approx_equal!(-6111.10665f64, payment(0.0, 2, 12345.67, -123.4567, true));
assert_approx_equal!(-6173.4522835f64, payment(0.0, 2, 12345.67, 1.234567, false));
assert_approx_equal!(-12345.67f64, payment(0.0, 2, 12345.67, 12345.67, true));
assert_approx_equal!(2469.3809134f64, payment(0.0, 5, -12345.67, -1.234567, false));
assert_approx_equal!(2468.8870866f64, payment(0.0, 5, -12345.67, 1.234567, true));
assert_approx_equal!(2493.82534f64, payment(0.0, 5, -123.4567, -12345.67, false));
assert_approx_equal!(24.9382534f64, payment(0.0, 5, -123.4567, -1.234567, true));
assert_approx_equal!(0f64, payment(0.0, 5, -123.4567, 123.4567, false));
assert_approx_equal!(2469.3809134f64, payment(0.0, 5, -1.234567, -12345.67, true));
assert_approx_equal!(0.2469134f64, payment(0.0, 5, -1.234567, 0.0, false));
assert_approx_equal!(-24.4444266f64, payment(0.0, 5, -1.234567, 123.4567, true));
assert_approx_equal!(24.69134f64, payment(0.0, 5, 0.0, -123.4567, false));
assert_approx_equal!(0f64, payment(0.0, 5, 0.0, 0.0, true));
assert_approx_equal!(-2469.134f64, payment(0.0, 5, 0.0, 12345.67, false));
assert_approx_equal!(24.4444266f64, payment(0.0, 5, 1.234567, -123.4567, true));
assert_approx_equal!(-0.4938268f64, payment(0.0, 5, 1.234567, 1.234567, false));
assert_approx_equal!(-2469.3809134f64, payment(0.0, 5, 1.234567, 12345.67, true));
assert_approx_equal!(-24.4444266f64, payment(0.0, 5, 123.4567, -1.234567, false));
assert_approx_equal!(-24.9382534f64, payment(0.0, 5, 123.4567, 1.234567, true));
assert_approx_equal!(0f64, payment(0.0, 5, 12345.67, -12345.67, false));
assert_approx_equal!(-2468.8870866f64, payment(0.0, 5, 12345.67, -1.234567, true));
assert_approx_equal!(-2493.82534f64, payment(0.0, 5, 12345.67, 123.4567, false));
assert_approx_equal!(2469.134f64, payment(0.0, 10, -12345.67, -12345.67, true));
assert_approx_equal!(1234.567f64, payment(0.0, 10, -12345.67, 0.0, false));
assert_approx_equal!(1222.22133f64, payment(0.0, 10, -12345.67, 123.4567, true));
assert_approx_equal!(24.69134f64, payment(0.0, 10, -123.4567, -123.4567, false));
assert_approx_equal!(12.34567f64, payment(0.0, 10, -123.4567, 0.0, true));
assert_approx_equal!(-1222.22133f64, payment(0.0, 10, -123.4567, 12345.67, false));
assert_approx_equal!(12.4691267f64, payment(0.0, 10, -1.234567, -123.4567, true));
assert_approx_equal!(0f64, payment(0.0, 10, -1.234567, 1.234567, false));
assert_approx_equal!(-1234.4435433f64, payment(0.0, 10, -1.234567, 12345.67, true));
assert_approx_equal!(0.1234567f64, payment(0.0, 10, 0.0, -1.234567, false));
assert_approx_equal!(-0.1234567f64, payment(0.0, 10, 0.0, 1.234567, true));
assert_approx_equal!(1234.4435433f64, payment(0.0, 10, 1.234567, -12345.67, false));
assert_approx_equal!(0f64, payment(0.0, 10, 1.234567, -1.234567, true));
assert_approx_equal!(-12.4691267f64, payment(0.0, 10, 1.234567, 123.4567, false));
assert_approx_equal!(1222.22133f64, payment(0.0, 10, 123.4567, -12345.67, true));
assert_approx_equal!(-12.34567f64, payment(0.0, 10, 123.4567, 0.0, false));
assert_approx_equal!(-24.69134f64, payment(0.0, 10, 123.4567, 123.4567, true));
assert_approx_equal!(-1222.22133f64, payment(0.0, 10, 12345.67, -123.4567, false));
assert_approx_equal!(-1234.567f64, payment(0.0, 10, 12345.67, 0.0, true));
assert_approx_equal!(-2469.134f64, payment(0.0, 10, 12345.67, 12345.67, false));
assert_approx_equal!(249.382534f64, payment(0.0, 50, -12345.67, -123.4567, true));
assert_approx_equal!(246.88870866f64, payment(0.0, 50, -12345.67, 1.234567, false));
assert_approx_equal!(0f64, payment(0.0, 50, -12345.67, 12345.67, true));
assert_approx_equal!(2.49382534f64, payment(0.0, 50, -123.4567, -1.234567, false));
assert_approx_equal!(2.44444266f64, payment(0.0, 50, -123.4567, 1.234567, true));
assert_approx_equal!(246.93809134f64, payment(0.0, 50, -1.234567, -12345.67, false));
assert_approx_equal!(0.04938268f64, payment(0.0, 50, -1.234567, -1.234567, true));
assert_approx_equal!(-2.44444266f64, payment(0.0, 50, -1.234567, 123.4567, false));
assert_approx_equal!(246.9134f64, payment(0.0, 50, 0.0, -12345.67, true));
assert_approx_equal!(0f64, payment(0.0, 50, 0.0, 0.0, false));
assert_approx_equal!(-2.469134f64, payment(0.0, 50, 0.0, 123.4567, true));
assert_approx_equal!(2.44444266f64, payment(0.0, 50, 1.234567, -123.4567, false));
assert_approx_equal!(-0.02469134f64, payment(0.0, 50, 1.234567, 0.0, true));
assert_approx_equal!(-246.93809134f64, payment(0.0, 50, 1.234567, 12345.67, false));
assert_approx_equal!(0f64, payment(0.0, 50, 123.4567, -123.4567, true));
assert_approx_equal!(-2.49382534f64, payment(0.0, 50, 123.4567, 1.234567, false));
assert_approx_equal!(-249.382534f64, payment(0.0, 50, 123.4567, 12345.67, true));
assert_approx_equal!(-246.88870866f64, payment(0.0, 50, 12345.67, -1.234567, false));
assert_approx_equal!(-246.93809134f64, payment(0.0, 50, 12345.67, 1.234567, true));
assert_approx_equal!(98.76536f64, payment(0.0, 250, -12345.67, -12345.67, false));
assert_approx_equal!(49.387618268f64, payment(0.0, 250, -12345.67, -1.234567, true));
assert_approx_equal!(48.8888532f64, payment(0.0, 250, -12345.67, 123.4567, false));
assert_approx_equal!(49.8765068f64, payment(0.0, 250, -123.4567, -12345.67, true));
assert_approx_equal!(0.4938268f64, payment(0.0, 250, -123.4567, 0.0, false));
assert_approx_equal!(0f64, payment(0.0, 250, -123.4567, 123.4567, true));
assert_approx_equal!(0.498765068f64, payment(0.0, 250, -1.234567, -123.4567, false));
assert_approx_equal!(0.004938268f64, payment(0.0, 250, -1.234567, 0.0, true));
assert_approx_equal!(-49.377741732f64, payment(0.0, 250, -1.234567, 12345.67, false));
assert_approx_equal!(0.4938268f64, payment(0.0, 250, 0.0, -123.4567, true));
assert_approx_equal!(-0.004938268f64, payment(0.0, 250, 0.0, 1.234567, false));
assert_approx_equal!(-49.38268f64, payment(0.0, 250, 0.0, 12345.67, true));
assert_approx_equal!(0f64, payment(0.0, 250, 1.234567, -1.234567, false));
assert_approx_equal!(-0.009876536f64, payment(0.0, 250, 1.234567, 1.234567, true));
assert_approx_equal!(48.8888532f64, payment(0.0, 250, 123.4567, -12345.67, false));
assert_approx_equal!(-0.488888532f64, payment(0.0, 250, 123.4567, -1.234567, true));
assert_approx_equal!(-0.9876536f64, payment(0.0, 250, 123.4567, 123.4567, false));
assert_approx_equal!(0f64, payment(0.0, 250, 12345.67, -12345.67, true));
assert_approx_equal!(-49.38268f64, payment(0.0, 250, 12345.67, 0.0, false));
assert_approx_equal!(-49.8765068f64, payment(0.0, 250, 12345.67, 123.4567, true));
assert_approx_equal!(12468.8434011773f64, payment(0.0023, 1, -12345.67, -123.4567, true));
assert_approx_equal!(12372.830474f64, payment(0.0023, 1, -12345.67, 1.234567, false));
assert_approx_equal!(28.3298822707772f64, payment(0.0023, 1, -12345.67, 12345.67, true));
assert_approx_equal!(124.97521741f64, payment(0.0023, 1, -123.4567, -1.234567, false));
assert_approx_equal!(122.224965988227f64, payment(0.0023, 1, -123.4567, 1.234567, true));
assert_approx_equal!(12346.9074065041f64, payment(0.0023, 1, -1.234567, -12345.67, false));
assert_approx_equal!(2.46630101177292f64, payment(0.0023, 1, -1.234567, -1.234567, true));
assert_approx_equal!(-122.2192934959f64, payment(0.0023, 1, -1.234567, 123.4567, false));
assert_approx_equal!(12317.3401177292f64, payment(0.0023, 1, 0.0, -12345.67, true));
assert_approx_equal!(0f64, payment(0.0023, 1, 0.0, 0.0, false));
assert_approx_equal!(-123.173401177292f64, payment(0.0023, 1, 0.0, 123.4567, true));
assert_approx_equal!(122.2192934959f64, payment(0.0023, 1, 1.234567, -123.4567, false));
assert_approx_equal!(-1.234567f64, payment(0.0023, 1, 1.234567, 0.0, true));
assert_approx_equal!(-12346.9074065041f64, payment(0.0023, 1, 1.234567, 12345.67, false));
assert_approx_equal!(-0.283298822707772f64, payment(0.0023, 1, 123.4567, -123.4567, true));
assert_approx_equal!(-124.97521741f64, payment(0.0023, 1, 123.4567, 1.234567, false));
assert_approx_equal!(-12440.7968177292f64, payment(0.0023, 1, 123.4567, 12345.67, true));
assert_approx_equal!(-12372.830474f64, payment(0.0023, 1, 12345.67, -1.234567, false));
assert_approx_equal!(-12346.9017340118f64, payment(0.0023, 1, 12345.67, 1.234567, true));
assert_approx_equal!(12359.8838288939f64, payment(0.0023, 2, -12345.67, -12345.67, false));
assert_approx_equal!(6180.54076562542f64, payment(0.0023, 2, -12345.67, -1.234567, true));
assert_approx_equal!(6132.48199100749f64, payment(0.0023, 2, -12345.67, 123.4567, false));
assert_approx_equal!(6213.39497984279f64, payment(0.0023, 2, -123.4567, -12345.67, true));
assert_approx_equal!(61.9413943494696f64, payment(0.0023, 2, -123.4567, 0.0, false));
assert_approx_equal!(0.283298822707772f64, payment(0.0023, 2, -123.4567, 123.4567, true));
assert_approx_equal!(62.2768578829643f64, payment(0.0023, 2, -1.234567, -123.4567, false));
assert_approx_equal!(0.617992560605304f64, payment(0.0023, 2, -1.234567, 0.0, true));
assert_approx_equal!(-6165.12498000346f64, payment(0.0023, 2, -1.234567, 12345.67, false));
assert_approx_equal!(61.5159572378226f64, payment(0.0023, 2, 0.0, -123.4567, true));
assert_approx_equal!(-0.616574439394696f64, payment(0.0023, 2, 0.0, 1.234567, false));
assert_approx_equal!(-6151.59572378226f64, payment(0.0023, 2, 0.0, 12345.67, true));
assert_approx_equal!(-0.0028395041f64, payment(0.0023, 2, 1.234567, -1.234567, false));
assert_approx_equal!(-1.23315213298353f64, payment(0.0023, 2, 1.234567, 1.234567, true));
assert_approx_equal!(6103.80299959749f64, payment(0.0023, 2, 123.4567, -12345.67, false));
assert_approx_equal!(-61.1840964881522f64, payment(0.0023, 2, 123.4567, -1.234567, true));
assert_approx_equal!(-123.598838288939f64, payment(0.0023, 2, 123.4567, 123.4567, false));
assert_approx_equal!(-28.3298822707772f64, payment(0.0023, 2, 12345.67, -12345.67, true));
assert_approx_equal!(-6194.13943494696f64, payment(0.0023, 2, 12345.67, 0.0, false));
assert_approx_equal!(-6241.44156329086f64, payment(0.0023, 2, 12345.67, 123.4567, true));
assert_approx_equal!(2510.7751387519f64, payment(0.0023, 5, -12345.67, -123.4567, false));
assert_approx_equal!(2480.49198641332f64, payment(0.0023, 5, -12345.67, 0.0, true));
assert_approx_equal!(28.395041f64, payment(0.0023, 5, -12345.67, 12345.67, false));
assert_approx_equal!(49.3265409055587f64, payment(0.0023, 5, -123.4567, -123.4567, true));
assert_approx_equal!(24.6161909721225f64, payment(0.0023, 5, -123.4567, 1.234567, false));
assert_approx_equal!(-2427.35718427841f64, payment(0.0023, 5, -123.4567, 12345.67, true));
assert_approx_equal!(0.494399919496415f64, payment(0.0023, 5, -1.234567, -1.234567, false));
assert_approx_equal!(0.00283298822707772f64, payment(0.0023, 5, -1.234567, 1.234567, true));
assert_approx_equal!(2457.80207698207f64, payment(0.0023, 5, 0.0, -12345.67, false));
assert_approx_equal!(0.245216210414255f64, payment(0.0023, 5, 0.0, -1.234567, true));
assert_approx_equal!(-24.5780207698207f64, payment(0.0023, 5, 0.0, 123.4567, false));
assert_approx_equal!(2451.91405494391f64, payment(0.0023, 5, 1.234567, -12345.67, true));
assert_approx_equal!(-0.248619711798207f64, payment(0.0023, 5, 1.234567, 0.0, false));
assert_approx_equal!(-24.7696702400668f64, payment(0.0023, 5, 1.234567, 123.4567, true));
assert_approx_equal!(-0.28395041f64, payment(0.0023, 5, 123.4567, -123.4567, false));
assert_approx_equal!(-24.8049198641332f64, payment(0.0023, 5, 123.4567, 0.0, true));
assert_approx_equal!(-2482.6640481619f64, payment(0.0023, 5, 123.4567, 12345.67, false));
assert_approx_equal!(-2455.9703653719f64, payment(0.0023, 5, 12345.67, -123.4567, true));
assert_approx_equal!(-2486.44289818977f64, payment(0.0023, 5, 12345.67, 1.234567, false));
assert_approx_equal!(-4932.65409055587f64, payment(0.0023, 5, 12345.67, 12345.67, true));
assert_approx_equal!(1250.36027410036f64, payment(0.0023, 10, -12345.67, -1.234567, false));
assert_approx_equal!(1247.24723684586f64, payment(0.0023, 10, -12345.67, 1.234567, true));
assert_approx_equal!(1234.34542969344f64, payment(0.0023, 10, -123.4567, -12345.67, false));
assert_approx_equal!(12.5955953335671f64, payment(0.0023, 10, -123.4567, -1.234567, true));
assert_approx_equal!(0.28395041f64, payment(0.0023, 10, -123.4567, 123.4567, false));
assert_approx_equal!(1219.16399541501f64, payment(0.0023, 10, -1.234567, -12345.67, true));
assert_approx_equal!(0.125023808979548f64, payment(0.0023, 10, -1.234567, 0.0, false));
assert_approx_equal!(-12.0656556709321f64, payment(0.0023, 10, -1.234567, 123.4567, true));
assert_approx_equal!(12.2184304879548f64, payment(0.0023, 10, 0.0, -123.4567, false));
assert_approx_equal!(0f64, payment(0.0023, 10, 0.0, 0.0, true));
assert_approx_equal!(-1221.84304879548f64, payment(0.0023, 10, 0.0, 12345.67, false));
assert_approx_equal!(12.0656556709321f64, payment(0.0023, 10, 1.234567, -123.4567, true));
assert_approx_equal!(-0.247208113859096f64, payment(0.0023, 10, 1.234567, 1.234567, false));
assert_approx_equal!(-1219.16399541501f64, payment(0.0023, 10, 1.234567, 12345.67, true));
assert_approx_equal!(-12.3801965930753f64, payment(0.0023, 10, 123.4567, -1.234567, false));
assert_approx_equal!(-12.5955953335671f64, payment(0.0023, 10, 123.4567, 1.234567, true));
assert_approx_equal!(-28.395041f64, payment(0.0023, 10, 12345.67, -12345.67, false));
assert_approx_equal!(-1247.24723684586f64, payment(0.0023, 10, 12345.67, -1.234567, true));
assert_approx_equal!(-1262.45652028344f64, payment(0.0023, 10, 12345.67, 123.4567, false));
assert_approx_equal!(493.80223210177f64, payment(0.0023, 50, -12345.67, -12345.67, true));
assert_approx_equal!(261.666509117802f64, payment(0.0023, 50, -12345.67, 0.0, false));
assert_approx_equal!(258.738695437118f64, payment(0.0023, 50, -12345.67, 123.4567, true));
assert_approx_equal!(4.94937977235604f64, payment(0.0023, 50, -123.4567, -123.4567, false));
assert_approx_equal!(2.61066057186273f64, payment(0.0023, 50, -123.4567, 0.0, true));
assert_approx_equal!(-230.654803026624f64, payment(0.0023, 50, -123.4567, 12345.67, false));
assert_approx_equal!(2.35346835487359f64, payment(0.0023, 50, -1.234567, -123.4567, true));
assert_approx_equal!(0.0028395041f64, payment(0.0023, 50, -1.234567, 1.234567, false));
assert_approx_equal!(-232.710068309778f64, payment(0.0023, 50, -1.234567, 12345.67, true));
assert_approx_equal!(0.0233271468117802f64, payment(0.0023, 50, 0.0, -1.234567, false));
assert_approx_equal!(-0.0232736174915496f64, payment(0.0023, 50, 0.0, 1.234567, true));
assert_approx_equal!(233.24530146689f64, payment(0.0023, 50, 1.234567, -12345.67, false));
assert_approx_equal!(-0.00283298822707772f64, payment(0.0023, 50, 1.234567, -1.234567, true));
assert_approx_equal!(-2.3588813320898f64, payment(0.0023, 50, 1.234567, 123.4567, false));
assert_approx_equal!(230.125514343633f64, payment(0.0023, 50, 123.4567, -12345.67, true));
assert_approx_equal!(-2.61666509117802f64, payment(0.0023, 50, 123.4567, 0.0, false));
assert_approx_equal!(-4.9380223210177f64, payment(0.0023, 50, 123.4567, 123.4567, true));
assert_approx_equal!(-259.333794436624f64, payment(0.0023, 50, 12345.67, -123.4567, false));
assert_approx_equal!(-261.066057186273f64, payment(0.0023, 50, 12345.67, 0.0, true));
assert_approx_equal!(-494.937977235604f64, payment(0.0023, 50, 12345.67, 12345.67, false));
assert_approx_equal!(65.204553816131f64, payment(0.0023, 250, -12345.67, -123.4567, true));
assert_approx_equal!(64.984929457009f64, payment(0.0023, 250, -12345.67, 1.234567, false));
assert_approx_equal!(28.3298822707772f64, payment(0.0023, 250, -12345.67, 12345.67, true));
assert_approx_equal!(0.653545242899081f64, payment(0.0023, 250, -123.4567, -1.234567, false));
assert_approx_equal!(0.644743623003814f64, payment(0.0023, 250, -123.4567, 1.234567, true));
assert_approx_equal!(36.6000466706714f64, payment(0.0023, 250, -1.234567, -12345.67, false));
assert_approx_equal!(0.0101349033845735f64, payment(0.0023, 250, -1.234567, -1.234567, true));
assert_approx_equal!(-0.359436619236723f64, payment(0.0023, 250, -1.234567, 123.4567, false));
assert_approx_equal!(36.509575787479f64, payment(0.0023, 250, 0.0, -12345.67, true));
assert_approx_equal!(0f64, payment(0.0023, 250, 0.0, 0.0, false));
assert_approx_equal!(-0.36509575787479f64, payment(0.0023, 250, 0.0, 123.4567, true));
assert_approx_equal!(0.359436619236723f64, payment(0.0023, 250, 1.234567, -123.4567, false));
assert_approx_equal!(-0.00648394580582562f64, payment(0.0023, 250, 1.234567, 0.0, true));
assert_approx_equal!(-36.6000466706714f64, payment(0.0023, 250, 1.234567, 12345.67, false));
assert_approx_equal!(-0.283298822707772f64, payment(0.0023, 250, 123.4567, -123.4567, true));
assert_approx_equal!(-0.653545242899081f64, payment(0.0023, 250, 123.4567, 1.234567, false));
assert_approx_equal!(-37.1579703680616f64, payment(0.0023, 250, 123.4567, 12345.67, true));
assert_approx_equal!(-64.984929457009f64, payment(0.0023, 250, 12345.67, -1.234567, false));
assert_approx_equal!(-64.843109015835f64, payment(0.0023, 250, 12345.67, 1.234567, true));
assert_approx_equal!(24413.7736168133f64, payment(0.023, 1, -12345.67, -12345.67, true));
assert_approx_equal!(12629.62041f64, payment(0.023, 1, -12345.67, 0.0, false));
assert_approx_equal!(12224.9889638319f64, payment(0.023, 1, -12345.67, 123.4567, true));
assert_approx_equal!(249.7529041f64, payment(0.023, 1, -123.4567, -123.4567, false));
assert_approx_equal!(123.4567f64, payment(0.023, 1, -123.4567, 0.0, true));
assert_approx_equal!(-12219.3737959f64, payment(0.023, 1, -123.4567, 12345.67, false));
assert_approx_equal!(121.915603168133f64, payment(0.023, 1, -1.234567, -123.4567, true));
assert_approx_equal!(0.028395041f64, payment(0.023, 1, -1.234567, 1.234567, false));
assert_approx_equal!(-12066.8690498133f64, payment(0.023, 1, -1.234567, 12345.67, true));
assert_approx_equal!(1.234567f64, payment(0.023, 1, 0.0, -1.234567, false));
assert_approx_equal!(-1.20681036168133f64, payment(0.023, 1, 0.0, 1.234567, true));
assert_approx_equal!(12344.407037959f64, payment(0.023, 1, 1.234567, -12345.67, false));
assert_approx_equal!(-0.0277566383186706f64, payment(0.023, 1, 1.234567, -1.234567, true));
assert_approx_equal!(-124.719662041f64, payment(0.023, 1, 1.234567, 123.4567, false));
assert_approx_equal!(11944.6469168133f64, payment(0.023, 1, 123.4567, -12345.67, true));
assert_approx_equal!(-126.2962041f64, payment(0.023, 1, 123.4567, 0.0, false));
assert_approx_equal!(-244.137736168133f64, payment(0.023, 1, 123.4567, 123.4567, true));
assert_approx_equal!(-12506.16371f64, payment(0.023, 1, 12345.67, -123.4567, false));
assert_approx_equal!(-12345.67f64, payment(0.023, 1, 12345.67, 0.0, true));
assert_approx_equal!(-24975.29041f64, payment(0.023, 1, 12345.67, 12345.67, false));
assert_approx_equal!(6302.67001787847f64, payment(0.023, 2, -12345.67, -123.4567, true));
assert_approx_equal!(6385.99461810677f64, payment(0.023, 2, -12345.67, 1.234567, false));
assert_approx_equal!(277.566383186706f64, payment(0.023, 2, -12345.67, 12345.67, true));
assert_approx_equal!(64.4763142828967f64, payment(0.023, 2, -123.4567, -1.234567, false));
assert_approx_equal!(61.8336103501328f64, payment(0.023, 2, -123.4567, 1.234567, true));
assert_approx_equal!(6103.29313404248f64, payment(0.023, 2, -1.234567, -12345.67, false));
assert_approx_equal!(1.2208464669705f64, payment(0.023, 2, -1.234567, -1.234567, true));
assert_approx_equal!(-60.3878842471859f64, payment(0.023, 2, -1.234567, 123.4567, false));
assert_approx_equal!(5965.44914325917f64, payment(0.023, 2, 0.0, -12345.67, true));
assert_approx_equal!(0f64, payment(0.023, 2, 0.0, 0.0, false));
assert_approx_equal!(-59.6544914325917f64, payment(0.023, 2, 0.0, 123.4567, true));
assert_approx_equal!(60.3878842471859f64, payment(0.023, 2, 1.234567, -123.4567, false));
assert_approx_equal!(-0.624301552644587f64, payment(0.023, 2, 1.234567, 0.0, true));
assert_approx_equal!(-6103.29313404248f64, payment(0.023, 2, 1.234567, 12345.67, false));
assert_approx_equal!(-2.77566383186706f64, payment(0.023, 2, 123.4567, -123.4567, true));
assert_approx_equal!(-64.4763142828967f64, payment(0.023, 2, 123.4567, 1.234567, false));
assert_approx_equal!(-6027.87929852363f64, payment(0.023, 2, 123.4567, 12345.67, true));
assert_approx_equal!(-6385.99461810677f64, payment(0.023, 2, 12345.67, -1.234567, false));
assert_approx_equal!(-6243.6120713602f64, payment(0.023, 2, 12345.67, 1.234567, true));
assert_approx_equal!(5000.22243424033f64, payment(0.023, 5, -12345.67, -12345.67, false));
assert_approx_equal!(2582.91518643341f64, payment(0.023, 5, -12345.67, -1.234567, true));
assert_approx_equal!(2618.50506199896f64, payment(0.023, 5, -12345.67, 123.4567, false));
assert_approx_equal!(2330.9451381636f64, payment(0.023, 5, -123.4567, -12345.67, true));
assert_approx_equal!(26.4208642212016f64, payment(0.023, 5, -123.4567, 0.0, false));
assert_approx_equal!(2.77566383186706f64, payment(0.023, 5, -123.4567, 123.4567, true));
assert_approx_equal!(23.8455687634136f64, payment(0.023, 5, -1.234567, -123.4567, false));
assert_approx_equal!(0.258268467460426f64, payment(0.023, 5, -1.234567, 0.0, true));
assert_approx_equal!(-2357.87180347795f64, payment(0.023, 5, -1.234567, 12345.67, false));
assert_approx_equal!(23.0511829141756f64, payment(0.023, 5, 0.0, -123.4567, true));
assert_approx_equal!(-0.235813601212016f64, payment(0.023, 5, 0.0, 1.234567, false));
assert_approx_equal!(-2305.11829141756f64, payment(0.023, 5, 0.0, 12345.67, true));
assert_approx_equal!(-0.028395041f64, payment(0.023, 5, 1.234567, -1.234567, false));
assert_approx_equal!(-0.488780296602182f64, payment(0.023, 5, 1.234567, 1.234567, true));
assert_approx_equal!(2331.71514789896f64, payment(0.023, 5, 123.4567, -12345.67, false));
assert_approx_equal!(-25.5963349169009f64, payment(0.023, 5, 123.4567, -1.234567, true));
assert_approx_equal!(-50.0022243424032f64, payment(0.023, 5, 123.4567, 123.4567, false));
assert_approx_equal!(-277.566383186706f64, payment(0.023, 5, 12345.67, -12345.67, true));
assert_approx_equal!(-2642.08642212016f64, payment(0.023, 5, 12345.67, 0.0, false));
assert_approx_equal!(-2605.73585751844f64, payment(0.023, 5, 12345.67, 123.4567, true));
assert_approx_equal!(1407.18314215102f64, payment(0.023, 10, -12345.67, -123.4567, false));
assert_approx_equal!(1364.67451221027f64, payment(0.023, 10, -12345.67, 0.0, true));
assert_approx_equal!(283.95041f64, payment(0.023, 10, -12345.67, 12345.67, false));
assert_approx_equal!(24.5178264123383f64, payment(0.023, 10, -123.4567, -123.4567, true));
assert_approx_equal!(13.8494090983119f64, payment(0.023, 10, -123.4567, 1.234567, false));
assert_approx_equal!(-1073.46138390146f64, payment(0.023, 10, -123.4567, 12345.67, true));
assert_approx_equal!(0.250817364198221f64, payment(0.023, 10, -1.234567, -1.234567, false));
assert_approx_equal!(0.0277566383186706f64, payment(0.023, 10, -1.234567, 1.234567, true));
assert_approx_equal!(1112.1116159911f64, payment(0.023, 10, 0.0, -12345.67, false));
assert_approx_equal!(0.108710812902356f64, payment(0.023, 10, 0.0, -1.234567, true));
assert_approx_equal!(-11.121116159911f64, payment(0.023, 10, 0.0, 123.4567, false));
assert_approx_equal!(1086.97166157234f64, payment(0.023, 10, 1.234567, -12345.67, true));
assert_approx_equal!(-0.13960620259911f64, payment(0.023, 10, 1.234567, 0.0, false));
assert_approx_equal!(-11.0075487414567f64, payment(0.023, 10, 1.234567, 123.4567, true));
assert_approx_equal!(-2.8395041f64, payment(0.023, 10, 123.4567, -123.4567, false));
assert_approx_equal!(-13.6467451221027f64, payment(0.023, 10, 123.4567, 0.0, true));
assert_approx_equal!(-1126.07223625102f64, payment(0.023, 10, 123.4567, 12345.67, false));
assert_approx_equal!(-1353.80343092003f64, payment(0.023, 10, 12345.67, -123.4567, true));
assert_approx_equal!(-1396.1732371527f64, payment(0.023, 10, 12345.67, 1.234567, false));
assert_approx_equal!(-2451.78264123383f64, payment(0.023, 10, 12345.67, 12345.67, true));
assert_approx_equal!(418.072090469851f64, payment(0.023, 50, -12345.67, -1.234567, false));
assert_approx_equal!(408.646401579592f64, payment(0.023, 50, -12345.67, 1.234567, true));
assert_approx_equal!(138.288856439316f64, payment(0.023, 50, -123.4567, -12345.67, false));
assert_approx_equal!(4.09970442169419f64, payment(0.023, 50, -123.4567, -1.234567, true));
assert_approx_equal!(2.8395041f64, payment(0.023, 50, -123.4567, 123.4567, false));
assert_approx_equal!(131.133993656746f64, payment(0.023, 50, -1.234567, -12345.67, true));
assert_approx_equal!(0.0418058679642887f64, payment(0.023, 50, -1.234567, 0.0, false));
assert_approx_equal!(-1.27006532596733f64, payment(0.023, 50, -1.234567, 123.4567, true));
assert_approx_equal!(1.34108269642887f64, payment(0.023, 50, 0.0, -123.4567, false));
assert_approx_equal!(0f64, payment(0.023, 50, 0.0, 0.0, true));
assert_approx_equal!(-134.108269642887f64, payment(0.023, 50, 0.0, 12345.67, false));
assert_approx_equal!(1.27006532596733f64, payment(0.023, 50, 1.234567, -123.4567, true));
assert_approx_equal!(-0.0552166949285774f64, payment(0.023, 50, 1.234567, 1.234567, false));
assert_approx_equal!(-131.133993656746f64, payment(0.023, 50, 1.234567, 12345.67, true));
assert_approx_equal!(-4.16717596946458f64, payment(0.023, 50, 123.4567, -1.234567, false));
assert_approx_equal!(-4.09970442169419f64, payment(0.023, 50, 123.4567, 1.234567, true));
assert_approx_equal!(-283.95041f64, payment(0.023, 50, 12345.67, -12345.67, false));
assert_approx_equal!(-408.646401579592f64, payment(0.023, 50, 12345.67, -1.234567, true));
assert_approx_equal!(-419.399762339316f64, payment(0.023, 50, 12345.67, 123.4567, false));
assert_approx_equal!(279.458579666982f64, payment(0.023, 250, -12345.67, -12345.67, true));
assert_approx_equal!(284.918268499661f64, payment(0.023, 250, -12345.67, 0.0, false));
assert_approx_equal!(278.503020444443f64, payment(0.023, 250, -12345.67, 123.4567, true));
assert_approx_equal!(2.85886126999323f64, payment(0.023, 250, -123.4567, -123.4567, false));
assert_approx_equal!(2.78512481426844f64, payment(0.023, 250, -123.4567, 0.0, true));
assert_approx_equal!(1.8813241853352f64, payment(0.023, 250, -123.4567, 12345.67, false));
assert_approx_equal!(0.0373122305440668f64, payment(0.023, 250, -1.234567, -123.4567, true));
assert_approx_equal!(0.028395041f64, payment(0.023, 250, -1.234567, 1.234567, false));
assert_approx_equal!(-0.918246991995591f64, payment(0.023, 250, -1.234567, 12345.67, true));
assert_approx_equal!(9.67858499661454E-05f64, payment(0.023, 250, 0.0, -1.234567, false));
assert_approx_equal!(-9.46098240138273E-05f64, payment(0.023, 250, 0.0, 1.234567, true));
assert_approx_equal!(0.939366672811489f64, payment(0.023, 250, 1.234567, -12345.67, false));
assert_approx_equal!(-0.0277566383186706f64, payment(0.023, 250, 1.234567, -1.234567, true));
assert_approx_equal!(-0.0381704118465804f64, payment(0.023, 250, 1.234567, 123.4567, false));
assert_approx_equal!(-1.83902657413021f64, payment(0.023, 250, 123.4567, -12345.67, true));
assert_approx_equal!(-2.84918268499661f64, payment(0.023, 250, 123.4567, 0.0, false));
assert_approx_equal!(-2.79458579666982f64, payment(0.023, 250, 123.4567, 123.4567, true));
assert_approx_equal!(-284.908589914665f64, payment(0.023, 250, 12345.67, -123.4567, false));
assert_approx_equal!(-278.512481426844f64, payment(0.023, 250, 12345.67, 0.0, true));
assert_approx_equal!(-285.886126999323f64, payment(0.023, 250, 12345.67, 12345.67, false));
assert_approx_equal!(15186.408667f64, payment(0.23, 1, -12345.67, -1.234567, false));
assert_approx_equal!(12344.6662869919f64, payment(0.23, 1, -12345.67, 1.234567, true));
assert_approx_equal!(12497.521741f64, payment(0.23, 1, -123.4567, -12345.67, false));
assert_approx_equal!(124.46041300813f64, payment(0.23, 1, -123.4567, -1.234567, true));
assert_approx_equal!(28.395041f64, payment(0.23, 1, -123.4567, 123.4567, false));
assert_approx_equal!(10038.3646483008f64, payment(0.23, 1, -1.234567, -12345.67, true));
assert_approx_equal!(1.51851741f64, payment(0.23, 1, -1.234567, 0.0, false));
assert_approx_equal!(-99.1367338130081f64, payment(0.23, 1, -1.234567, 123.4567, true));
assert_approx_equal!(123.4567f64, payment(0.23, 1, 0.0, -123.4567, false));
assert_approx_equal!(0f64, payment(0.23, 1, 0.0, 0.0, true));
assert_approx_equal!(-12345.67f64, payment(0.23, 1, 0.0, 12345.67, false));
assert_approx_equal!(99.1367338130081f64, payment(0.23, 1, 1.234567, -123.4567, true));
assert_approx_equal!(-2.75308441f64, payment(0.23, 1, 1.234567, 1.234567, false));
assert_approx_equal!(-10038.3646483008f64, payment(0.23, 1, 1.234567, 12345.67, true));
assert_approx_equal!(-150.617174f64, payment(0.23, 1, 123.4567, -1.234567, false));
assert_approx_equal!(-124.46041300813f64, payment(0.23, 1, 123.4567, 1.234567, true));
assert_approx_equal!(-2839.5041f64, payment(0.23, 1, 12345.67, -12345.67, false));
assert_approx_equal!(-12344.6662869919f64, payment(0.23, 1, 12345.67, -1.234567, true));
assert_approx_equal!(-15308.6308f64, payment(0.23, 1, 12345.67, 123.4567, false));
assert_approx_equal!(11310.4503055161f64, payment(0.23, 2, -12345.67, -12345.67, true));
assert_approx_equal!(8375.67898789238f64, payment(0.23, 2, -12345.67, 0.0, false));
assert_approx_equal!(6764.48556017354f64, payment(0.23, 2, -12345.67, 123.4567, true));
assert_approx_equal!(139.118538757848f64, payment(0.23, 2, -123.4567, -123.4567, false));
assert_approx_equal!(68.0949511210762f64, payment(0.23, 2, -123.4567, 0.0, true));
assert_approx_equal!(-5452.41809801345f64, payment(0.23, 2, -123.4567, 12345.67, false));
assert_approx_equal!(45.6905014452951f64, payment(0.23, 2, -1.234567, -123.4567, true));
assert_approx_equal!(0.28395041f64, payment(0.23, 2, -1.234567, 1.234567, false));
assert_approx_equal!(-4500.27424389723f64, payment(0.23, 2, -1.234567, 12345.67, true));
assert_approx_equal!(0.553617488789238f64, payment(0.23, 2, 0.0, -1.234567, false));
assert_approx_equal!(-0.450095519340844f64, payment(0.23, 2, 0.0, 1.234567, true));
assert_approx_equal!(5535.33731999359f64, payment(0.23, 2, 1.234567, -12345.67, false));
assert_approx_equal!(-0.230853991869919f64, payment(0.23, 2, 1.234567, -1.234567, true));
assert_approx_equal!(-56.199316777713f64, payment(0.23, 2, 1.234567, 123.4567, false));
assert_approx_equal!(4432.86024228736f64, payment(0.23, 2, 123.4567, -12345.67, true));
assert_approx_equal!(-83.7567898789238f64, payment(0.23, 2, 123.4567, 0.0, false));
assert_approx_equal!(-113.104503055161f64, payment(0.23, 2, 123.4567, 123.4567, true));
assert_approx_equal!(-8320.31723901346f64, payment(0.23, 2, 12345.67, -123.4567, false));
assert_approx_equal!(-6809.49511210762f64, payment(0.23, 2, 12345.67, 0.0, true));
assert_approx_equal!(-13911.8538757848f64, payment(0.23, 2, 12345.67, 12345.67, false));
assert_approx_equal!(3592.96564272554f64, payment(0.23, 5, -12345.67, -123.4567, true));
assert_approx_equal!(4403.54930414689f64, payment(0.23, 5, -12345.67, 1.234567, false));
assert_approx_equal!(2308.53991869919f64, payment(0.23, 5, -12345.67, 12345.67, true));
assert_approx_equal!(44.1934774055241f64, payment(0.23, 5, -123.4567, -1.234567, false));
assert_approx_equal!(35.6753146997254f64, payment(0.23, 5, -123.4567, 1.234567, true));
assert_approx_equal!(1564.64199488175f64, payment(0.23, 5, -1.234567, -12345.67, false));
assert_approx_equal!(0.485195719399889f64, payment(0.23, 5, -1.234567, -1.234567, true));
assert_approx_equal!(-15.2016456706623f64, payment(0.23, 5, -1.234567, 123.4567, false));
assert_approx_equal!(1271.70863764985f64, payment(0.23, 5, 0.0, -12345.67, true));
assert_approx_equal!(0f64, payment(0.23, 5, 0.0, 0.0, false));
assert_approx_equal!(-12.7170863764985f64, payment(0.23, 5, 0.0, 123.4567, true));
assert_approx_equal!(15.2016456706623f64, payment(0.23, 5, 1.234567, -123.4567, false));
assert_approx_equal!(-0.358024855634904f64, payment(0.23, 5, 1.234567, 0.0, true));
assert_approx_equal!(-1564.64199488175f64, payment(0.23, 5, 1.234567, 12345.67, false));
assert_approx_equal!(-23.0853991869919f64, payment(0.23, 5, 123.4567, -123.4567, true));
assert_approx_equal!(-44.1934774055241f64, payment(0.23, 5, 123.4567, 1.234567, false));
assert_approx_equal!(-1307.51112321334f64, payment(0.23, 5, 123.4567, 12345.67, true));
assert_approx_equal!(-4403.54930414689f64, payment(0.23, 5, 12345.67, -1.234567, false));
assert_approx_equal!(-3580.3757272128f64, payment(0.23, 5, 12345.67, 1.234567, true));
assert_approx_equal!(3659.46546285804f64, payment(0.23, 10, -12345.67, -12345.67, false));
assert_approx_equal!(2641.89087763997f64, payment(0.23, 10, -12345.67, -1.234567, true));
assert_approx_equal!(3245.38497461473f64, payment(0.23, 10, -12345.67, 123.4567, false));
assert_approx_equal!(359.736202636836f64, payment(0.23, 10, -123.4567, -12345.67, true));
assert_approx_equal!(32.4948478142902f64, payment(0.23, 10, -123.4567, 0.0, false));
assert_approx_equal!(23.0853991869919f64, payment(0.23, 10, -123.4567, 123.4567, true));
assert_approx_equal!(4.42475529243308f64, payment(0.23, 10, -1.234567, -123.4567, false));
assert_approx_equal!(0.264185754587725f64, payment(0.23, 10, -1.234567, 0.0, true));
assert_approx_equal!(-409.655732950875f64, payment(0.23, 10, -1.234567, 12345.67, false));
assert_approx_equal!(3.33317627178063f64, payment(0.23, 10, 0.0, -123.4567, true));
assert_approx_equal!(-0.0409980681429018f64, payment(0.23, 10, 0.0, 1.234567, false));
assert_approx_equal!(-333.317627178063f64, payment(0.23, 10, 0.0, 12345.67, true));
assert_approx_equal!(-0.28395041f64, payment(0.23, 10, 1.234567, -1.234567, false));
assert_approx_equal!(-0.297517517305531f64, payment(0.23, 10, 1.234567, 1.234567, true));
assert_approx_equal!(377.485833614727f64, payment(0.23, 10, 123.4567, -12345.67, false));
assert_approx_equal!(-26.3852436960547f64, payment(0.23, 10, 123.4567, -1.234567, true));
assert_approx_equal!(-36.5946546285804f64, payment(0.23, 10, 123.4567, 123.4567, false));
assert_approx_equal!(-2308.53991869919f64, payment(0.23, 10, 12345.67, -12345.67, true));
assert_approx_equal!(-3249.48478142902f64, payment(0.23, 10, 12345.67, 0.0, false));
assert_approx_equal!(-2645.19072214903f64, payment(0.23, 10, 12345.67, 123.4567, true));
assert_approx_equal!(2839.59579004515f64, payment(0.23, 50, -12345.67, -123.4567, false));
assert_approx_equal!(2308.61372538449f64, payment(0.23, 50, -12345.67, 0.0, true));
assert_approx_equal!(2839.5041f64, payment(0.23, 50, -12345.67, 12345.67, false));
assert_approx_equal!(23.0868753206979f64, payment(0.23, 50, -123.4567, -123.4567, true));
assert_approx_equal!(28.3959397440069f64, payment(0.23, 50, -123.4567, 1.234567, false));
assert_approx_equal!(23.0123305685425f64, payment(0.23, 50, -123.4567, 12345.67, true));
assert_approx_equal!(0.283968566444584f64, payment(0.23, 50, -1.234567, -1.234567, false));
assert_approx_equal!(0.230853991869919f64, payment(0.23, 50, -1.234567, 1.234567, true));
assert_approx_equal!(0.0907822229220255f64, payment(0.23, 50, 0.0, -12345.67, false));
assert_approx_equal!(7.38066853025501E-06f64, payment(0.23, 50, 0.0, -1.234567, true));
assert_approx_equal!(-0.000907822229219732f64, payment(0.23, 50, 0.0, 123.4567, false));
assert_approx_equal!(-0.157054687235803f64, payment(0.23, 50, 1.234567, -12345.67, true));
assert_approx_equal!(-0.283959488222292f64, payment(0.23, 50, 1.234567, 0.0, false));
assert_approx_equal!(-0.231599439391473f64, payment(0.23, 50, 1.234567, 123.4567, true));
assert_approx_equal!(-28.395041f64, payment(0.23, 50, 123.4567, -123.4567, false));
assert_approx_equal!(-23.0861372538449f64, payment(0.23, 50, 123.4567, 0.0, true));
assert_approx_equal!(-28.4867310451513f64, payment(0.23, 50, 123.4567, 12345.67, false));
assert_approx_equal!(-2308.61298731764f64, payment(0.23, 50, 12345.67, -123.4567, true));
assert_approx_equal!(-2839.59489130114f64, payment(0.23, 50, 12345.67, 1.234567, false));
assert_approx_equal!(-2308.68753206979f64, payment(0.23, 50, 12345.67, 12345.67, true));
assert_approx_equal!(2839.5041f64, payment(0.23, 250, -12345.67, -1.234567, false));
assert_approx_equal!(2308.53991869919f64, payment(0.23, 250, -12345.67, 1.234567, true));
assert_approx_equal!(28.3950410000001f64, payment(0.23, 250, -123.4567, -12345.67, false));
assert_approx_equal!(23.0853991869919f64, payment(0.23, 250, -123.4567, -1.234567, true));
assert_approx_equal!(28.395041f64, payment(0.23, 250, -123.4567, 123.4567, false));
assert_approx_equal!(0.230853991869828f64, payment(0.23, 250, -1.234567, -12345.67, true));
assert_approx_equal!(0.28395041f64, payment(0.23, 250, -1.234567, 0.0, false));
assert_approx_equal!(0.230853991869918f64, payment(0.23, 250, -1.234567, 123.4567, true));
assert_approx_equal!(0f64, payment(0.23, 250, 0.0, -123.4567, false));
assert_approx_equal!(0f64, payment(0.23, 250, 0.0, 0.0, true));
assert_approx_equal!(0f64, payment(0.23, 250, 0.0, 12345.67, false));
assert_approx_equal!(-0.230853991869918f64, payment(0.23, 250, 1.234567, -123.4567, true));
assert_approx_equal!(-0.28395041f64, payment(0.23, 250, 1.234567, 1.234567, false));
assert_approx_equal!(-0.230853991869828f64, payment(0.23, 250, 1.234567, 12345.67, true));
assert_approx_equal!(-28.395041f64, payment(0.23, 250, 123.4567, -1.234567, false));
assert_approx_equal!(-23.0853991869919f64, payment(0.23, 250, 123.4567, 1.234567, true));
assert_approx_equal!(-2839.5041f64, payment(0.23, 250, 12345.67, -12345.67, false));
assert_approx_equal!(-2308.53991869919f64, payment(0.23, 250, 12345.67, -1.234567, true));
assert_approx_equal!(-2839.5041f64, payment(0.23, 250, 12345.67, 123.4567, false));
}
}