Skip to main content

finance_solution/cashflow/
payment.rs

1//! **Payment calculations.** What is the periodic payment needed for an amortized loan and how much
2//! of that is interest or principal?
3//!
4//! For most common usages, we recommend the [`payment_solution`](./fn.payment_solution.html) function, which provides a better debugging experience and additional functionality.
5//!
6//! ## Example
7//! ```
8//! let (rate, periods, present_value, future_value, due_at_beginning) = (0.034, 10, 1000, 0, false);
9//! let solution = finance_solution::payment_solution(rate, periods, present_value, future_value, due_at_beginning).unwrap();
10//! dbg!(&solution);
11//! ```
12//! Outputs to terminal:
13//! ```text
14//! {
15//!     calculated_field: Payment,
16//!     rate: 0.034,
17//!     periods: 10,
18//!     present_value: 1000.0,
19//!     future_value: 0.0,
20//!     due_at_beginning: false,
21//!     payment: -119.63608534268569,
22//!     sum_of_payments: -1196.360853426857,
23//!     sum_of_interest: -196.36085342685692,
24//!     formula: "-119.6361 = ((1000.0000 * 1.034000^10) * -0.034000) / (1.034000^10 - 1)",
25//!     symbolic_formula: "pmt = ((pv * (1 + r)^n) * -r) / ((1 + r)^n - 1)",
26//! }
27//! ```
28//! ```
29//! # use finance_solution::*;
30//! # let (rate, periods, present_value, future_value, due_at_beginning) = (0.034, 10, 1000, 0, false);
31//! # let solution = payment_solution(rate, periods, present_value, future_value, due_at_beginning).unwrap();
32//! dbg!(solution.print_table());
33//! ```
34//! Outputs to terminal:
35//! ```text
36//! period  payments_to_date  payments_remaining  principal  principal_to_date  principal_remaining  interest  interest_to_date  interest_remaining
37//! ------  ----------------  ------------------  ---------  -----------------  -------------------  --------  ----------------  ------------------
38//!     1         -119.6361         -1_076.7248   -85.6361           -85.6361            -914.3639  -34.0000          -34.0000           -162.3609
39//!     2         -239.2722           -957.0887   -88.5477          -174.1838            -825.8162  -31.0884          -65.0884           -131.2725
40//!     3         -358.9083           -837.4526   -91.5583          -265.7421            -734.2579  -28.0778          -93.1661           -103.1947
41//!     4         -478.5443           -717.8165   -94.6713          -360.4134            -639.5866  -24.9648         -118.1309            -78.2300
42//!     5         -598.1804           -598.1804   -97.8901          -458.3036            -541.6964  -21.7459         -139.8768            -56.4840
43//!     6         -717.8165           -478.5443  -101.2184          -559.5220            -440.4780  -18.4177         -158.2945            -38.0663
44//!     7         -837.4526           -358.9083  -104.6598          -664.1818            -335.8182  -14.9763         -173.2708            -23.0901
45//!     8         -957.0887           -239.2722  -108.2183          -772.4001            -227.5999  -11.4178         -184.6886            -11.6723
46//!     9       -1_076.7248           -119.6361  -111.8977          -884.2978            -115.7022   -7.7384         -192.4270             -3.9339
47//!     10      -1_196.3609             -0.0000  -115.7022          -999.0000              -0.0000   -3.9339         -196.3609              0.0000
48//! ```
49//! # Payment Due at the Beginning vs. the End of the Period
50//!
51//! In a typical loan the payment is due at the end of each period. All other factors being equal,
52//! if the payment is instead due at the beginning of the period the payment amount will be slightly
53//! smaller. This is justified because it means the outstanding principal at any point during the
54//! loan will be slightly smaller since it was paid down one period earlier.
55//!
56//! To make this concrete, suppose we have an amortized loan for $100,000 at 12% annual interest for
57//! ten years. We can run an A/B test where scenario A has the payments due at the end of the period
58//! and scenario B has them due at the beginning. We'll look at the details of the first five
59//! periods:
60//! ```text
61//! period  payment_a  payment_b  principal_a  principal_b  princ_remaining_a  princ_remaining_b
62//! ------  ---------  ---------  -----------  -----------  -----------------  -----------------
63//!      1   1,434.71   1,420.50       434.71     1,420.50          99,565.29          98,579.50
64//!      2   1,434.71   1,420.50       439.06       434.71          99,126.23          98,144.79
65//!      3   1,434.71   1,420.50       443.45       439.06          98,682.79          97,705.73
66//!      4   1,434.71   1,420.50       447.88       443.45          98,234.91          97,262.28
67//!      5   1,434.71   1,420.50       452.36       447.88          97,782.54          96,814.40
68//! ```
69//!
70//! For scenario A a payment of $1,434.71 is due at the end of the month and for scenario B a
71//! lower payment of $1,420.50 is due at the beginning of the month. Yet in both scenarios the loan
72//! is fully paid off by the end of the 120<sup>th</sup> period.
73//!
74//! The reason is that the first monthly payment in the second case went entirely to paying down the
75//! principal, and from that point on the principal (the last two columns in this table) was
76//! slightly smaller at every point in time. Thus the amount of each payment that went toward the
77//! interest was smaller and the amount left to go to principal was larger.
78//!
79//! The sum of the payments in the first case (due at the end) is $172,165.14 and the sum of the
80//! payments in the second case is $170,460.53, a difference of $1,704.61. The relationship between
81//! these sums (and the monthly payment amounts) is based on the interest rate. Specifically:
82//!
83//! > <img src="http://i.upmath.me/svg/payment%5C_due%5C_at%5C_beginning(x)%20%3D%20%7Bpayment%5C_due%5C_at%5C_end(x)%20%5Cover%201%20%2B%20rate%7D" />
84//!
85//! and indeed it turns out that:
86//!
87//! > <img src="http://i.upmath.me/svg/170%2C460.53%20%3D%20%7B172%2C165.14%20%5Cover%201.01%7D" />
88//!
89//! which is a relief. By the way, A/B comparisons like the table above are built into the crate.
90//! See [CashflowSolution::print_ab_comparison](././cashflow/struct.CashflowSolution.html#method.print_ab_comparison).
91//!
92//! # Positive and Negative Amounts
93//!
94//! The example above was an amortized loan for $100,000 at 12% annual interest for ten years. Thus
95//! the present value (the original principal of the loan) was $10,000 and the future value (the
96//! amount still owed at the end) was zero. Also the rate was positive. In cases like this if the
97//! present value is entered as a positive number the payment will be negative, and vice versa:
98//! ```
99//! use finance_solution::*;
100//!
101//! let (rate, periods, present_value, due_at_beginning) = (0.01, 120, 100_000, false);
102//!
103//! let pmt_positive_present_value = payment(rate, periods, present_value, 0.0, due_at_beginning).unwrap();
104//! assert_rounded_2!(-1_434.71, pmt_positive_present_value);
105//!
106//! let pmt_negative_present_value = payment(rate, periods, -present_value, 0.0, due_at_beginning).unwrap();
107//! assert_rounded_2!(1_434.71, pmt_negative_present_value);
108//! ```
109//! Either way is fine. It depends on whether we're thinking of the payment as a stream of money
110//! being paid out or coming in. In the period-by-period detail the principal and interest (and
111//! remaining principal and interest and so on) for each period will have the same sign as the
112//! payment.
113//!
114//! # Formulas
115//!
116//! ## Present Value but no Future Value
117//!
118//! In the typical case of an amortized loan the present value will be nonzero and the future value
119//! will be zero. This represents the loan being paid off by the end of the last period.
120//!
121//! If the payment is due at the end of the period the calculation is:
122//!
123//! > <img src="http://i.upmath.me/svg/payment%20%3D%20%7B%7Bpresent%5C_value%20%5Ctimes%20%5Cleft(1%2Brate%5Cright)%5E%7Bperiods%7D%20%5Ctimes%20-rate%7D%20%5Cover%20%5Cleft(1%2Brate%5Cright)%5E%7Bperiods%7D%20-%201%7D" />
124//!
125//! or with some of the more commonly used variables:
126//!
127//! > <img src="http://i.upmath.me/svg/pmt%20%3D%20%7B%7Bpv%20%5Ctimes%20%5Cleft(1%2Br%5Cright)%5En%20%5Ctimes%20-r%7D%20%5Cover%20%5Cleft(1%2Br%5Cright)%5En%20-%201%7D" />
128//!
129//! Often the payment is shown as `A` and the present value is `P` for principal. In this crate we
130//! use the same symbols for present value, rate, etc. across all of the functions.
131//!
132//! If the payment is due at the beginning of the period the only difference is that we have to
133//! divide the above payment by `(1 + rate)`. So the formula is:
134//!
135//! > <img src="http://i.upmath.me/svg/pmt%20%3D%20%7B%7Bpv%20%5Ctimes%20%5Cleft(1%2Br%5Cright)%5En%20%5Ctimes%20-r%7D%20%5Cover%20%5Cleft%5B%5Cleft(1%2Br%5Cright)%5En%20-%201%5Cright%5D%20%5Ctextcolor%7Bblue%7D%7B%5Ctimes%20%5Cleft(1%2Br)%7D" />
136//!
137//! ## Future Value but no Present Value
138//!
139//! If there's a future value and the present value is zero, and the payment is due at the end of
140//! the period, the formula is:
141//!
142//! > <img src="http://i.upmath.me/svg/payment%20%3D%20%7Bfuture%5C_value%20%5Ctimes%20-rate%20%5Cover%20%7B%5Cleft(1%2Brate%5Cright)%5E%7Bperiods%7D%20-%201%7D" />
143//!
144//! or:
145//!
146//! > <img src="http://i.upmath.me/svg/pmt%20%3D%20%7Bfv%20%5Ctimes%20-r%20%5Cover%20%5Cleft(1%2Br%5Cright)%5En%20-%201%5Cright%7D" />
147//!
148//! If the payment is due at the beginning of the period it's:
149//!
150//! > <img src="http://i.upmath.me/svg/pmt%20%3D%20%7Bfv%20%5Ctimes%20-r%20%5Cover%20%5Cleft%5B%5Cleft(1%2Br%5Cright)%5En%20-%201%5Cright%5D%20%5Ctextcolor%7Bblue%7D%7B%5Ctimes%20(1%2Br)%7D%7D" />
151//!
152//! ## Both Present Value and Future Value
153//!
154//! If both present value and future value are nonzero the formula is:
155//!
156//! > <img src="http://i.upmath.me/svg/payment%20%3D%20%7B%5Cleft%5C%7B%5Cleft%5Bpresent%5C_value%20%5Ctimes%20%5Cleft(1%2Brate%5Cright)%5E%7Bperiods%7D%5Cright%5D%2Bfuture%5C_value%5Cright%5C%7D%20%5Ctimes%20-rate%20%5Cover%20%5Cleft(1%2Brate%5Cright)%5E%7Bperiods%7D%20-%201%7D" />
157//!
158//! or:
159//!
160//! > <img src="http://i.upmath.me/svg/pmt%20%3D%20%7B%5Cleft%5C%7B%5Cleft%5Bpv%20%5Ctimes%20%5Cleft(1%2Br%5Cright)%5En%5Cright%5D%2Bfv%5Cright%5C%7D%20%5Ctimes%20-r%20%5Cover%20%5Cleft(1%2Br%5Cright)%5En%20-%201%7D" />
161//!
162//! If the payment is due at the beginning of the period it's:
163//!
164//! > <img src="http://i.upmath.me/svg/pmt%20%3D%20%7B%5Cleft%5C%7B%5Cleft%5Bpv%20%5Ctimes%20%5Cleft(1%2Br%5Cright)%5En%5Cright%5D%2Bfv%5Cright%5C%7D%20%5Ctimes%20-r%20%5Cover%20%5Cleft%5B%5Cleft(1%2Br%5Cright)%5En%20-%201%5Cright%5D%20%5Ctextcolor%7Bblue%7D%7B%5Ctimes%20(1%2Br)%7D%7D" />
165//!
166use log::warn;
167
168// Import needed for the function references in the Rustdoc comments.
169#[allow(unused_imports)]
170use crate::*;
171use std::ops::Deref;
172
173const RUN_PAYMENT_INVARIANTS: bool = false;
174
175#[derive(Clone, Debug)]
176pub struct PaymentSolution(CashflowSolution);
177
178#[derive(Clone, Debug)]
179pub struct PaymentSeries(CashflowSeries);
180
181impl PaymentSolution {
182    pub(crate) fn new(solution: CashflowSolution) -> Self {
183        Self { 0: solution }
184    }
185    pub fn print_table(&self) {
186        self.series().print_table(true, true)
187    }
188
189    /// Calculates the period-by-period details of a payment calculation including how the payment
190    /// is broken down between principal and interest.
191    ///
192    /// # Examples
193    /// An amortized loan. Uses [`payment`].
194    /// ```
195    /// use finance_solution::*;
196    ///
197    /// let years = 5;
198    ///
199    /// // The annual percentage rate is 15% and the interest will compound monthly.
200    /// let rate = convert_apr_to_epr(0.15, 12).unwrap();
201    ///
202    /// // Each period will be one month.
203    /// let periods = years * 12;
204    ///
205    /// // The amount of the loan is $20,000.
206    /// let present_value = 20_000;
207    ///
208    /// // The loan will be fully paid off ot the end of the last period.
209    /// let future_value = 0;
210    ///
211    /// // Payments are due at the end of the month.
212    /// let due_at_beginning = false;
213    ///
214    /// // Calculate the payment, creating a struct that contains additional information and the option
215    /// // to generate period-by-period details.
216    /// let solution = payment_solution(rate, periods, present_value, future_value, due_at_beginning).unwrap();
217    /// dbg!(&solution);
218    ///
219    /// // Calculate the month-by-month details including the principal and interest paid every month.
220    /// let series = solution.series();
221    /// dbg!(&series);
222    ///
223    /// // Confirm that we have one entry for each period.
224    /// assert_eq!(periods as usize, series.len());
225    ///
226    /// // Print the period detail numbers as a formatted table.
227    /// let include_running_totals = true;
228    /// let include_remaining_amounts = true;
229    /// let locale = num_format::Locale::en;
230    /// let precision = 2; // Two decimal places.
231    /// series.print_table_locale(include_running_totals, include_remaining_amounts, &locale, precision);
232    ///
233    /// // As above but print only the last period for every yeor of the loan, that is periods 12, 24,
234    /// // 36, 48, and 60; and use default formatting.
235    /// series
236    ///     .filter(|x| x.period() % 12 == 0)
237    ///     .print_table(include_running_totals, include_remaining_amounts);
238    /// ```
239    pub fn series(&self) -> PaymentSeries {
240        let mut series = vec![];
241        if self.future_value() != 0.0 {
242            return PaymentSeries::new(CashflowSeries::new(series));
243        }
244        let mut payments_to_date = 0.0;
245        let mut principal_to_date = 0.0;
246        let mut interest_to_date = 0.0;
247        for period in 1..=self.periods() {
248            let principal_remaining_at_start_of_period = self.present_value() + principal_to_date;
249            let interest = if self.due_at_beginning() && period == 1 {
250                0.0
251            } else {
252                -principal_remaining_at_start_of_period * self.rate()
253            };
254            let principal = self.payment() - interest;
255            payments_to_date += self.payment();
256            principal_to_date += principal;
257            interest_to_date += interest;
258            let payments_remaining = self.sum_of_payments() - payments_to_date;
259            let principal_remaining = -(self.present_value() + principal_to_date);
260            let interest_remaining = self.sum_of_interest() - interest_to_date;
261            let (formula, symbolic_formula) = if self.due_at_beginning() && period == 1 {
262                ("0".to_string(), "interest = 0".to_string())
263            } else {
264                let formula = format!(
265                    "{:.4} = -({:.4} * {:.6})",
266                    interest,
267                    principal_remaining_at_start_of_period,
268                    self.rate()
269                );
270                let symbolic_formula = "interest = -(principal * rate)".to_string();
271                (formula, symbolic_formula)
272            };
273            let entry = CashflowPeriod::new(
274                period,
275                self.rate(),
276                self.due_at_beginning(),
277                self.payment(),
278                payments_to_date,
279                payments_remaining,
280                principal,
281                principal_to_date,
282                principal_remaining,
283                interest,
284                interest_to_date,
285                interest_remaining,
286                formula,
287                symbolic_formula,
288            );
289            series.push(entry);
290        }
291        let payment_series = PaymentSeries::new(CashflowSeries::new(series));
292        if RUN_PAYMENT_INVARIANTS {
293            payment_series.invariant(self);
294        }
295        payment_series
296    }
297
298    pub fn print_ab_comparison(
299        &self,
300        other: &PaymentSolution,
301        include_running_totals: bool,
302        include_remaining_amounts: bool,
303    ) {
304        self.print_ab_comparison_locale_opt(
305            other,
306            include_running_totals,
307            include_remaining_amounts,
308            None,
309            None,
310        );
311    }
312
313    pub fn print_ab_comparison_locale(
314        &self,
315        other: &PaymentSolution,
316        include_running_totals: bool,
317        include_remaining_amounts: bool,
318        locale: &num_format::Locale,
319        precision: usize,
320    ) {
321        self.print_ab_comparison_locale_opt(
322            other,
323            include_running_totals,
324            include_remaining_amounts,
325            Some(locale),
326            Some(precision),
327        );
328    }
329
330    fn print_ab_comparison_locale_opt(
331        &self,
332        other: &PaymentSolution,
333        include_running_totals: bool,
334        include_remaining_amounts: bool,
335        locale: Option<&num_format::Locale>,
336        precision: Option<usize>,
337    ) {
338        println!();
339        // print_ab_comparison_values_string("calculated_field", &self.calculated_field().to_string(), &other.calculated_field.to_string());
340        print_ab_comparison_values_rate("rate", self.rate(), other.rate(), locale, precision);
341        print_ab_comparison_values_int(
342            "periods",
343            i128::from(self.periods()),
344            i128::from(other.periods()),
345            locale,
346        );
347        print_ab_comparison_values_float(
348            "present_value",
349            self.present_value(),
350            other.present_value(),
351            locale,
352            precision,
353        );
354        print_ab_comparison_values_float(
355            "future_value",
356            self.future_value(),
357            other.future_value(),
358            locale,
359            precision,
360        );
361        print_ab_comparison_values_bool(
362            "due_at_beginning",
363            self.due_at_beginning(),
364            other.due_at_beginning(),
365        );
366        print_ab_comparison_values_float(
367            "payment",
368            self.payment(),
369            other.payment(),
370            locale,
371            precision,
372        );
373        print_ab_comparison_values_float(
374            "sum_of_payments",
375            self.sum_of_payments(),
376            other.sum_of_payments(),
377            locale,
378            precision,
379        );
380        print_ab_comparison_values_float(
381            "sum_of_interest",
382            self.sum_of_interest(),
383            other.sum_of_interest(),
384            locale,
385            precision,
386        );
387        print_ab_comparison_values_string("formula", &self.formula(), &other.formula());
388        print_ab_comparison_values_string(
389            "symbolic_formula",
390            &self.symbolic_formula(),
391            &other.symbolic_formula(),
392        );
393
394        self.series().print_ab_comparison_locale_opt(
395            &other.series(),
396            include_running_totals,
397            include_remaining_amounts,
398            locale,
399            precision,
400        );
401    }
402
403    fn invariant(&self) {
404        let rate = self.rate();
405        let periods = self.periods();
406        let present_value = self.present_value();
407        let future_value = self.future_value();
408        let payment = self.payment();
409        let sum_of_payments = self.sum_of_payments();
410        let sum_of_interest = self.sum_of_interest();
411        let formula = self.formula();
412        let symbolic_formula = self.symbolic_formula();
413        let present_and_future_value = present_value + future_value;
414        assert!(self.calculated_field().is_payment());
415        assert!(rate.is_finite());
416        assert!(present_value.is_finite());
417        assert!(future_value.is_finite());
418        assert!(payment.is_finite());
419        if future_value == 0.0 {
420            if present_value == 0.0 {
421                assert_eq!(0.0, payment);
422            } else if present_value.is_sign_positive() {
423                assert!(payment.is_sign_negative());
424            } else if present_value.is_sign_negative() {
425                assert!(payment.is_sign_positive());
426            }
427        }
428        assert!(sum_of_payments.is_finite());
429        assert_approx_equal!(sum_of_payments, payment * periods as f64);
430        if future_value == 0.0 {
431            assert_same_sign_or_zero!(sum_of_interest, sum_of_payments);
432        }
433        if periods > 0
434            && rate != 0.0
435            && future_value == 0.0
436            && !is_approx_equal!(0.0, present_value)
437        {
438            assert!(sum_of_interest.abs() < sum_of_payments.abs());
439        }
440        assert_approx_equal!(sum_of_interest, sum_of_payments + present_and_future_value);
441        assert!(!formula.is_empty());
442        assert!(!symbolic_formula.is_empty());
443    }
444}
445
446impl Deref for PaymentSolution {
447    type Target = CashflowSolution;
448
449    fn deref(&self) -> &Self::Target {
450        &self.0
451    }
452}
453
454impl PaymentSeries {
455    pub(crate) fn new(series: CashflowSeries) -> Self {
456        Self { 0: series }
457    }
458
459    fn invariant(&self, solution: &CashflowSolution) {
460        let periods = solution.periods();
461        if solution.future_value() != 0.0 {
462            assert_eq!(0, self.len());
463        } else {
464            assert_eq!(periods as usize, self.len());
465        }
466        if self.len() == 0 {
467            return;
468        }
469        let rate = solution.rate();
470        let present_value = solution.present_value();
471        let due_at_beginning = solution.due_at_beginning();
472        assert!(solution.calculated_field().is_payment());
473        let payment = solution.payment();
474        let sum_of_payments = solution.sum_of_payments();
475        let sum_of_interest = solution.sum_of_interest();
476        let mut running_sum_of_payments = 0.0;
477        let mut running_sum_of_principal = 0.0;
478        let mut running_sum_of_interest = 0.0;
479        let mut previous_principal: Option<f64> = None;
480        let mut previous_interest: Option<f64> = None;
481        for (index, entry) in self.iter().enumerate() {
482            running_sum_of_payments += entry.payment();
483            running_sum_of_principal += entry.principal();
484            running_sum_of_interest += entry.interest();
485            assert_eq!(rate, entry.rate());
486            assert_eq!(index + 1, entry.period() as usize);
487            assert_eq!(payment, entry.payment());
488            assert_approx_equal!(running_sum_of_payments, entry.payments_to_date());
489            assert_approx_equal!(
490                sum_of_payments - running_sum_of_payments,
491                entry.payments_remaining()
492            );
493            if present_value == 0.0 || rate == 0.0 || (due_at_beginning && index == 0) {
494                assert_eq!(payment, entry.principal());
495                assert_eq!(0.0, entry.interest());
496            } else if present_value > 0.0 {
497                assert!(entry.principal() < 0.0);
498                assert!(entry.interest() < 0.0);
499            } else {
500                // if entry.principal() <= 0.0 {
501                //     bg!(&solution, &series[..10]);
502                // }
503                assert!(entry.principal() > 0.0);
504                assert!(entry.interest() > 0.0);
505            }
506            if index > 0 && previous_interest.unwrap() != 0.0 {
507                // Compared to the previous period the principal should be further from zero and the
508                // interest should be further toward zero. There's a special case where payments are due
509                // at the beginning and we're currently on the second entry. In this case the previous
510                // entry will have had zero interest and a principal matching the full payment amount,
511                // so the two assertions below wouldn't make sense.
512                assert!(entry.principal().abs() > previous_principal.unwrap().abs());
513                assert!(entry.interest().abs() < previous_interest.unwrap().abs());
514            }
515            assert_approx_equal!(running_sum_of_principal, entry.principal_to_date());
516            assert_approx_equal!(
517                -present_value - running_sum_of_principal,
518                entry.principal_remaining()
519            );
520            assert_approx_equal!(running_sum_of_interest, entry.interest_to_date());
521            assert_approx_equal!(
522                sum_of_interest - running_sum_of_interest,
523                entry.interest_remaining()
524            );
525            assert_approx_equal!(payment, entry.principal() + entry.interest());
526            if index == periods as usize - 1 {
527                // This is the entry for the last period.
528                assert_approx_equal!(0.0, entry.payments_remaining());
529                // if !is_approx_equal!(0.0, entry.principal_remaining()) {
530                //     bg!(&solution, &series[..10], &series[250], &series[490..500]);
531                //}
532                assert_approx_equal!(0.0, entry.principal_remaining());
533                assert_approx_equal!(0.0, entry.interest_remaining());
534            }
535            assert!(!entry.formula().is_empty());
536            assert!(!entry.symbolic_formula().is_empty());
537
538            previous_principal = Some(entry.principal());
539            previous_interest = Some(entry.interest());
540        }
541        assert_approx_equal!(running_sum_of_payments, sum_of_payments);
542        assert_approx_equal!(running_sum_of_principal, -present_value);
543        assert_approx_equal!(running_sum_of_interest, sum_of_interest);
544    }
545}
546
547impl Deref for PaymentSeries {
548    type Target = CashflowSeries;
549
550    fn deref(&self) -> &Self::Target {
551        &self.0
552    }
553}
554
555/// Returns the payment needed at the end of every period for an amortized loan.
556///
557/// Related functions:
558/// * To calculate the payment needed at the end of each period and return a struct that shows the
559/// interest, the formula, and optionally the period-by-period values use [`payment_solution`].
560///
561/// In the typical case where there's a present value and the future value is zero, and the payment
562/// is due at the end of the period, the formula is:
563/// > payment = ((present_value * (1 + rate)<sup>periods</sup>) * -rate) / ((1 + rate)<sup>periods</sup> - 1)
564///
565/// or with the more commonly used variables:
566/// > pmt = ((pv * (1 + r)<sup>n</sup>) * -r) / ((1 + r)<sup>n</sup> - 1)
567///
568/// Often the payment is shown as `A` and the present value is `P` for principal.
569///
570/// If there's a future value and the present value is zero, the formula is:
571/// > payment = (future_value * -rate) / ((1 + rate)<sup>periods</sup> - 1)
572///
573/// or:
574/// > pmt = (fv * -r) / ((1 + r)<sup>n</sup> - 1)
575///
576/// If both present value and future value are nonzero the formula is:
577/// > payment = (((present_value * (1 + rate)<sup>periods</sup>) + future_value) * -rate) / ((1 + rate)<sup>periods</sup> - 1)
578///
579/// or:
580/// > pmt = (((pv * (1 + r)<sup>n</sup>) + fv) * -r) / ((1 + r)<sup>n</sup> - 1)
581///
582/// If the payment is due at the beginning of the period, the only difference is that the payment
583/// is divided by (1 + rate). In our formulas this means multiplying the denominator by (1 + rate)
584/// so in the typical case where there's a present value and the future value is zero, the formula
585/// is:
586/// > payment = ((present_value * (1 + rate)<sup>periods</sup>) * -rate) / (((1 + rate)<sup>periods</sup> - 1) * (1 + rate))
587///
588/// or with the more commonly used variables:
589/// > pmt = ((pv * (1 + r)<sup>n</sup>) * -r) / (((1 + r)<sup>n</sup> - 1) * (1 + r))",
590///
591/// This is nearly the same formula as the one for payments due at the end of the period. The
592/// relationship between the two formulas is that:
593/// > payment_due(x) = payment(x).unwrap() / (1 + rate)
594///
595/// Thus the payment is slightly smaller if it's due at the beginning of the month since the
596/// principal is paid down a bit faster.
597///
598/// If there's a future value and the present value is zero, the formula is:
599/// > payment = (future_value * -rate) / (((1 + rate)<sup>periods</sup> - 1) * (1 + rate))
600///
601/// or:
602/// > pmt = (fv * -r) / (((1 + r)<sup>n</sup> - 1) * (1 + r))
603///
604/// If both present value and future value are nonzero the formula is:
605/// > payment = (((present_value * (1 + rate)<sup>periods</sup>) + future_value) * -rate) / (((1 + rate)<sup>periods</sup> - 1) * (1 + rate))
606///
607/// or:
608/// > pmt = (((pv * (1 + r)<sup>n</sup>) + fv) * -r) / (((1 + r)<sup>n</sup> - 1) * (1 + r))
609///
610/// # Arguments
611/// * `rate` - The interest rate per period, expressed as a floating point number. For instance
612/// 0.01 would mean 1% interest per period. The rate must match the period type. For instance if the
613/// periods are months and we're starting with an annual interest rate, the rate must be divided by
614/// 12 when calling the function as shown in the example below. The rate often appears as `r` or `i`
615/// (interest) in formulas.
616/// * `periods` - The number of periods such as quarters or periods. Often appears as `n` or `t`
617/// where `t` typically implies years.
618/// * `present_value` - In the case of an amortized loan this is the the principal. It may appear as
619/// `pv` in formulas, or `C` for cash flow or `P` for principal. Assuming that the future value is
620/// zero, the payment will be negative if the present value is positive and vice versa.
621/// * `future_value` - The value at the end of the last period. For a typical amortized loan this
622/// will be zero. It appears as `fv` in formulas.
623/// * `due_at_beginning` - True if the payment is due at the beginning of the period. Typically the
624/// payment will be due at the end of the period so this will be false.
625///
626/// # Errors
627/// Returns [`crate::FinanceError`] if `rate` is less than -1.0.
628///
629/// # Examples
630/// A simple amortized loan with the payment due at the end of the month.
631/// ```
632/// # use finance_solution::*;
633/// // The loan will be paid off in five years.
634/// let years = 5;
635///
636/// // The interest rate is 10% per year. Each period is one month so we need to divide the rate
637/// // by the number of months in a year.
638/// let rate = 0.10 / 12.0;
639///
640/// // Each period is one month so we need to multiply the
641/// // years by the number of months in a year.
642/// let periods = years * 12;
643///
644/// // The principal is $10,000.
645/// let present_value = 10_000;
646///
647/// // The loan will be fully paid off by the end of the last period.
648/// let future_value = 0;
649///
650/// let due_at_beginning = false;
651///
652/// let pmt = payment(rate, periods, present_value, future_value, due_at_beginning).unwrap();
653/// dbg!(pmt);
654///
655/// // The payment is $212.47/month. Since the principal/present value was positive the payment is
656/// // negative.
657/// assert_rounded_4(pmt, -212.4704);
658///
659///
660/// // As above except this time the payment is due at the beginning of the month. This will reduce
661/// // the payment slightly.
662/// let due_at_beginning = true;
663/// let pmt = payment(rate, periods, present_value, future_value, due_at_beginning).unwrap();
664/// dbg!(pmt);
665///
666/// // The payment is $210.7145, shown as negative since the present value was positive. It's
667/// // slightly smaller (that is, closer to zero) than the payment in the case above where the
668/// // payment was due at the end of the month.
669/// assert_rounded_4(pmt, -210.7145);
670///
671/// ```
672/// # Errors
673/// Returns [`FinanceError::InvalidRate`] if `rate <= -1.0`, [`FinanceError::NonFinite`] for
674/// non-finite amounts, or [`FinanceError::Unsolvable`] when periods/values cannot determine a
675/// payment.
676///
677/// # Examples
678///
679/// Handle invalid rates with a structured match:
680///
681/// ```
682/// use finance_solution::{payment, FinanceError};
683///
684/// match payment(0.01, 36, 10_000.0, 0.0, false) {
685///     Ok(pmt) => {
686///         assert!(pmt < 0.0); // positive principal → negative payment
687///         println!("monthly payment = {pmt:.2}");
688///     }
689///     Err(FinanceError::InvalidRate { rate }) => {
690///         eprintln!("rate {rate} is out of domain (must be > -1.0)");
691///     }
692///     Err(FinanceError::NonFinite { field, value }) => {
693///         eprintln!("{field} is not finite: {value}");
694///     }
695///     Err(e) => eprintln!("payment failed: {e}"),
696/// }
697/// ```
698///
699/// Reject a catastrophic rate without panicking:
700///
701/// ```
702/// use finance_solution::{payment, FinanceError};
703///
704/// let err = payment(-1.5, 12, 5_000.0, 0.0, false).unwrap_err();
705/// assert!(matches!(err, FinanceError::InvalidRate { .. }));
706/// assert!(err.to_string().contains("-1.5"));
707/// ```
708///
709/// Propagate with `?`:
710///
711/// ```
712/// use finance_solution::{payment, FinanceResult};
713///
714/// fn loan_payment(principal: f64) -> FinanceResult<f64> {
715///     payment(0.09 / 12.0, 60, principal, 0.0, false)
716/// }
717///
718/// assert!(loan_payment(20_000.0).is_ok());
719/// ```
720pub fn payment<P, F, T>(
721    rate: f64,
722    periods: u32,
723    present_value: P,
724    future_value: F,
725    timing: T,
726) -> crate::FinanceResult<f64>
727where
728    P: Into<f64> + Copy,
729    F: Into<f64> + Copy,
730    T: Into<crate::PaymentTiming>,
731{
732    let present_value = present_value.into();
733    let future_value = future_value.into();
734    let due_at_beginning = timing.into().is_beginning();
735    crate::util::error::require_rate_gt_minus_one(rate)?;
736    crate::util::error::require_finite("present_value", present_value)?;
737    crate::util::error::require_finite("future_value", future_value)?;
738    if rate > 1.0 {
739        warn!(
740            "You provided a periodic rate ({}) greater than 1. Are you sure you expect a {}% return?",
741            rate,
742            rate * 100.0
743        );
744    }
745    if periods == 0 && present_value + future_value != 0.0 {
746        return Err(crate::FinanceError::Unsolvable {
747            message: "no periods and present + future value is nonzero; cannot calculate payment",
748        });
749    }
750
751    if periods == 0 {
752        return Ok(0.0);
753    }
754
755    if rate == 0.0 {
756        return Ok((-present_value - future_value) / periods as f64);
757    }
758
759    let rate_mult = 1.0 + rate;
760    let num = ((present_value * rate_mult.powf(periods as f64)) + future_value) * -rate;
761    if !num.is_finite() {
762        return Err(crate::FinanceError::NonFinite {
763            field: "payment_numerator",
764            value: num,
765        });
766    }
767    let mut denom = rate_mult.powf(periods as f64) - 1.0;
768    if due_at_beginning {
769        denom *= rate_mult;
770    }
771    if !denom.is_finite() || denom == 0.0 {
772        return Err(crate::FinanceError::Unsolvable {
773            message: "payment denominator is zero or non-finite",
774        });
775    }
776    let payment = num / denom;
777    if payment.is_finite() {
778        Ok(payment)
779    } else {
780        Err(crate::FinanceError::NonFinite {
781            field: "payment",
782            value: payment,
783        })
784    }
785}
786
787/// Calculates the payment needed for each period for an amortized loan and creates a  struct
788/// showing the interest, the formula, and optionally the period-by-period values.
789///
790/// Related functions:
791/// * To calculate the payment as a simple number instead of a struct when the payment is due at the
792/// end of each period use [payment](./fn.payment.html).
793///
794/// In the typical case where there's a present value and the future value is zero, and the payment
795/// is due at the end of the period, the formula is:
796/// > payment = ((present_value * (1 + rate)<sup>periods</sup>) * -rate) / ((1 + rate)<sup>periods</sup> - 1)
797///
798/// or with the more commonly used variables:
799/// > pmt = ((pv * (1 + r)<sup>n</sup>) * -r) / ((1 + r)<sup>n</sup> - 1)
800///
801/// Often the payment is shown as `A` and the present value is `P` for principal.
802///
803/// If there's a future value and the present value is zero, the formula is:
804/// > payment = (future_value * -rate) / ((1 + rate)<sup>periods</sup> - 1)
805///
806/// or:
807/// > pmt = (fv * -r) / ((1 + r)<sup>n</sup> - 1)
808///
809/// If both present value and future value are nonzero the formula is:
810/// > payment = (((present_value * (1 + rate)<sup>periods</sup>) + future_value) * -rate) / ((1 + rate)<sup>periods</sup> - 1)
811///
812/// or:
813/// > pmt = (((pv * (1 + r)<sup>n</sup>) + fv) * -r) / ((1 + r)<sup>n</sup> - 1)
814///
815/// If the payment is due at the beginning of the period, the only difference is that the payment
816/// is divided by (1 + rate). In our formulas this means multiplying the denominator by (1 + rate)
817/// so in the typical case where there's a present value and the future value is zero, the formula
818/// is:
819/// > payment = ((present_value * (1 + rate)<sup>periods</sup>) * -rate) / (((1 + rate)<sup>periods</sup> - 1) * (1 + rate))
820///
821/// or with the more commonly used variables:
822/// > pmt = ((pv * (1 + r)<sup>n</sup>) * -r) / (((1 + r)<sup>n</sup> - 1) * (1 + r))",
823///
824/// This is nearly the same formula as the one for payments due at the end of the period. The
825/// relationship between the two formulas is that:
826/// > payment_due(x) = payment(x).unwrap() / (1 + rate)
827///
828/// Thus the payment is slightly smaller if it's due at the beginning of the month since the
829/// principal is paid down a bit faster.
830///
831/// If there's a future value and the present value is zero, the formula is:
832/// > payment = (future_value * -rate) / (((1 + rate)<sup>periods</sup> - 1) * (1 + rate))
833///
834/// or:
835/// > pmt = (fv * -r) / (((1 + r)<sup>n</sup> - 1) * (1 + r))
836///
837/// If both present value and future value are nonzero the formula is:
838/// > payment = (((present_value * (1 + rate)<sup>periods</sup>) + future_value) * -rate) / (((1 + rate)<sup>periods</sup> - 1) * (1 + rate))
839///
840/// or:
841/// > pmt = (((pv * (1 + r)<sup>n</sup>) + fv) * -r) / (((1 + r)<sup>n</sup> - 1) * (1 + r))
842///
843/// # Arguments
844/// * `rate` - The interest rate per period, expressed as a floating point number. For instance
845/// 0.01 would mean 1% interest per period. The rate must match the period type. For instance if the
846/// periods are months and we're starting with an annual interest rate, the rate must be divided by
847/// 12 when calling the function as shown in the example below. The rate often appears as `r` or `i`
848/// (interest) in formulas.
849/// * `periods` - The number of periods such as quarters or periods. Often appears as `n` or `t`
850/// where `t` typically implies years.
851/// * `present_value` - In the case of an amortized loan this is the the principal. It may appear as
852/// `pv` in formulas, or `C` for cash flow or `P` for principal. Assuming that the future value is
853/// zero, the payment will be negative if the present value is positive and vice versa.
854/// * `future_value` - The value at the end of the last period. For a typical amortized loan this
855/// will be zero. It appears as `fv` in formulas.
856/// * `due_at_beginning` - True if the payment is due at the beginning of the period. Typically the
857/// payment will be due at the end of the period so this will be false.
858///
859/// # Errors
860/// Returns [`crate::FinanceError`] if `rate` is less than -1.0.
861///
862/// # Examples
863/// Calculate the payment for a simple amortized loan with the payment due at the end of the month,
864/// then examine the formulas and the period-by-period details such as the amount of the payment
865/// that goes to principal and interest.
866/// ```
867/// # use finance_solution::*;
868/// // The interest rate is 11.75% per year. Each period is one month so we need to divide the rate
869/// // by the number of months in a year.
870/// let rate = 0.1175 / 12.0;
871///
872/// // The loan will be paid off in 48 months.
873/// let periods = 48;
874///
875/// // The principal is $12,500.50. Here we'll express it as a negative number so that the payment,
876/// // interest, and principal are all positive numbers for simplicity.
877/// let present_value = -12_500.5;
878///
879/// // The loan will be fully paid off by the end of the last period.
880/// let future_value = 0.0;
881///
882/// let due_at_beginning = false;
883///
884/// let solution = payment_solution(rate, periods, present_value, future_value, due_at_beginning).unwrap();
885/// // Display the inputs, payment amount, formulas, sum of interest, etc.
886/// dbg!(&solution);
887///
888/// // The payment is $327.65/month. Since the principal/present value was negative the payment is
889/// // positive.
890/// assert_rounded_4(solution.payment(), 327.6538);
891///
892/// // The sum of payments is simply the monthly payment times the number of months.
893/// assert_rounded_4(solution.sum_of_payments(), 15_727.3820);
894///
895/// // The sum of interest is the portion of the sum of payments that is over and above the original
896/// // loan amount. Here we add the present value since it has the opposite sign of the payments.
897/// assert_rounded_4(solution.sum_of_interest(), solution.sum_of_payments() + solution.present_value());
898/// assert_rounded_4(solution.sum_of_interest(), 3_226.8820);
899///
900/// // Examine the formulas. Since the future value is zero we expect to see a slightly simplified
901/// // formula.
902/// let formula = solution.formula();
903/// println!();
904/// dbg!(&formula);
905/// assert_eq!(formula, "327.6538 = (-12500.5000 * 1.009792^48 * -0.009792) / (1.009792^48 - 1)");
906/// let symbolic_formula = solution.symbolic_formula();
907/// println!();
908/// dbg!(&symbolic_formula);
909/// assert_eq!(symbolic_formula, "pmt = (pv * (1 + r)^n * -r) / ((1 + r)^n - 1)");
910///
911/// // Calculate the period-by-period values including the amount of the payment that goes toward
912/// // interest and principle as well as the running tally of the remaining amounts.
913/// let series = solution.series();
914/// // Note that all of the period-by-period values are shown as of the end of the period after that
915/// // period's payment has been made.
916/// println!();
917/// dbg!(&series);
918///
919/// // Print the period-by-period values in a table with two decimal places and the numbers aligned,
920/// // with Vietnamese formatting for the thousands and decimal separators. Show all columns
921/// // including running totals and remaining amounts.
922/// let locale = &num_format::Locale::vi;
923/// let include_running_totals = true;
924/// let include_remaining_amounts = true;
925/// println!();
926/// series.print_table_locale(include_running_totals, include_remaining_amounts, &locale, 2);
927///
928/// // Print a table with only the last period of each year, that is all of the periods that can be
929/// // divided by 12. Include the running totals columns but not remaining amounts. Also this time
930/// // use default formatting without specifying the locale or number of decimal places.
931/// let include_running_totals = true;
932/// let include_remaining_amounts = false;
933/// println!();
934/// series
935///     .filter(|entry| entry.period() % 12 == 0)
936///     .print_table(include_running_totals, include_remaining_amounts);
937///
938/// // Print a table starting at the first period where at least 95% of the interest has been paid
939/// // off, and round all dollar amounts to whole numbers by passing zero as the second argument to
940/// // print_table_locale(). Include the remanining amounts columns but not the running totals.
941/// let include_running_totals = false;
942/// let include_remaining_amounts = true;
943/// println!();
944/// series
945///     .filter(|entry| entry.interest_to_date() >= solution.sum_of_interest() * 0.95)
946///     .print_table_locale(include_running_totals, include_remaining_amounts, locale, 0);
947/// ```
948pub fn payment_solution<P, F, T>(
949    rate: f64,
950    periods: u32,
951    present_value: P,
952    future_value: F,
953    timing: T,
954) -> crate::FinanceResult<PaymentSolution>
955where
956    P: Into<f64> + Copy,
957    F: Into<f64> + Copy,
958    T: Into<crate::PaymentTiming>,
959{
960    let present_value = present_value.into();
961    let future_value = future_value.into();
962    let due_at_beginning = timing.into().is_beginning();
963    let payment = payment(rate, periods, present_value, future_value, due_at_beginning)?;
964    let (formula, symbolic_formula) = payment_formula(
965        rate,
966        periods,
967        present_value,
968        future_value,
969        due_at_beginning,
970        payment,
971    );
972    let solution = PaymentSolution::new(CashflowSolution::new(
973        CashflowVariable::Payment,
974        rate,
975        periods,
976        present_value,
977        future_value,
978        due_at_beginning,
979        payment,
980        &formula,
981        &symbolic_formula,
982    ));
983    if RUN_PAYMENT_INVARIANTS {
984        solution.invariant();
985    }
986    Ok(solution)
987}
988
989fn payment_formula(
990    rate: f64,
991    periods: u32,
992    present_value: f64,
993    future_value: f64,
994    due_at_beginning: bool,
995    payment: f64,
996) -> (String, String) {
997    let rate_multiplier = 1.0 + rate;
998    let (mut formula, mut symbolic_formula) = if periods == 0 {
999        (format!("{:.4}", 0.0), "0".to_string())
1000    } else if rate == 0.0 {
1001        // There is no interest so the payment is simply the total amount to be paid (the difference
1002        // between the present and future value) divided by the number of periods. We subtract
1003        // present value from future value because if present_value is higher than future value the
1004        // payments should be negative.
1005        if future_value == 0.0 {
1006            (
1007                format!("{:.4} / {}", -present_value, periods),
1008                "-pv / n".to_string(),
1009            )
1010        } else if present_value == 0.0 {
1011            (
1012                format!("{:.4} / {}", -future_value, periods),
1013                "-fv / n".to_string(),
1014            )
1015        } else {
1016            // We have both a present and future value.
1017            let add_future_value = if future_value > 0.0 {
1018                format!(" - {:.4}", future_value)
1019            } else {
1020                format!(" + {:.4}", -future_value)
1021            };
1022            let formula = format!("({:.4}{}) / {}", -present_value, add_future_value, periods);
1023            let symbolic_formula = "(-pv - fv) / n".to_string();
1024            (formula, symbolic_formula)
1025        }
1026    } else {
1027        let (formula_num, symbolic_formula_num) = if future_value == 0.0 {
1028            // We can slightly simplify the formula by not including the future value term.
1029            (
1030                format!(
1031                    "({:.4} * {:.6}^{} * {:.6})",
1032                    present_value, rate_multiplier, periods, -rate
1033                ),
1034                "(pv * (1 + r)^n * -r)".to_string(),
1035            )
1036        } else if present_value == 0.0 {
1037            // We can simplify the formula by not including the present value term.
1038            (
1039                format!("({:.4} * {:.6})", future_value, -rate),
1040                "(fv * -r)".to_string(),
1041            )
1042        } else {
1043            // We have both a present and future value.
1044            let add_future_value = if future_value > 0.0 {
1045                format!(" + {:.4}", future_value)
1046            } else {
1047                format!(" - {:.4}", 0.0 - future_value)
1048            };
1049            (
1050                format!(
1051                    "((({:.4} * {:.6}^{}){}) * {:.6})",
1052                    present_value, rate_multiplier, periods, add_future_value, -rate
1053                ),
1054                "(((pv * (1 + r)^n) + fv) * -r)".to_string(),
1055            )
1056        };
1057        let mut formula_denom = format!("({:.6}^{} - 1)", rate_multiplier, periods);
1058        let mut symbolic_formula_denom = "((1 + r)^n - 1)".to_string();
1059        if due_at_beginning {
1060            formula_denom = format!("({} * {:.6})", formula_denom, rate_multiplier);
1061            symbolic_formula_denom = format!("({} * (1 + r))", symbolic_formula_denom);
1062        }
1063        (
1064            format!("{} / {}", formula_num, formula_denom),
1065            format!("{} / {}", symbolic_formula_num, symbolic_formula_denom),
1066        )
1067    };
1068    formula = format!("{:.4} = {}", payment, formula);
1069    symbolic_formula = format!("pmt = {}", symbolic_formula);
1070    (formula, symbolic_formula)
1071}
1072
1073/*
1074fn check_payment_parameters(rate: f64, periods: u32, present_value: f64, future_value: f64) {
1075    assert!(rate.is_finite(), "The rate must be finite (not NaN or infinity)");
1076    assert!(rate >= -1.0, "The rate must be greater than or equal to -1.0 because a rate lower than -100% would mean the investment loses more than its full value in a period.");
1077    if rate.abs() > 1. {
1078        warn!("You provided a periodic rate ({}) greater than 1. Are you sure you expect a {}% return?", rate, rate * 100.0);
1079    }
1080    assert!(present_value.is_finite(), "The present value must be finite (not NaN or infinity)");
1081    assert!(future_value.is_finite(), "The future value must be finite (not NaN or infinity)");
1082    assert!(!(present_value == 0.0 && future_value != 0.0), "The present value is zero and the future value is nonzero so there's no way to solve for the payments.");
1083    assert!(!(present_value != 0.0 && future_value == 0.0 && rate != -1.0), "The present value is nonzero, the future value is zero, and the rate is not -100% so there's no way to solve for the payments.");
1084    assert!(!(present_value < 0.0 && future_value > 0.0), "The present value is negative and the future value is positive so there's no way to solve for the payments.");
1085    assert!(!(present_value > 0.0 && future_value < 0.0), "The present value is positive and the future value is negative so there's no way to solve for the payments.");
1086    assert!(!(present_value < 0.0 && future_value < present_value && rate <= 0.0), "The present value and future value are both negative, the future value is less than the present value, and the periodic rate is zero or negative. There's no way to solve for the payments.");
1087    assert!(!(present_value < 0.0 && future_value > present_value && rate >= 0.0), "The present value and future value are both negative, the future value is greater than the present value, and the periodic rate is zero or positive. There's no way to solve for the payments.");
1088    assert!(!(present_value > 0.0 && future_value > present_value && rate <= 0.0), "The present value and future value are both positive, the future value is greater than the present value, and the periodic rate is zero or negative. There's no way to solve for the payments.");
1089    assert!(!(present_value > 0.0 && future_value < present_value && rate >= 0.0), "The present value and future value are both positive, the future value is less than the present value, and the periodic rate is zero or positive. There's no way to solve for the payments.");
1090}
1091*/
1092
1093#[cfg(test)]
1094mod tests {
1095    use super::*;
1096    // use crate::*;
1097
1098    #[test]
1099    fn test_payment_due_at_end_nominal() {
1100        assert_approx_equal!(
1101            -11.9636085342686f64,
1102            payment(0.034, 10, 100.0, 0.0, false).unwrap()
1103        );
1104        assert_approx_equal!(
1105            -8.22683411973293f64,
1106            payment(-0.034, 10, 100.0, 0.0, false).unwrap()
1107        );
1108        assert_approx_equal!(
1109            11.9636085342686f64,
1110            payment(0.034, 10, -100.0, 0.0, false).unwrap()
1111        );
1112        assert_approx_equal!(
1113            -100.097751710655f64,
1114            payment(1.0, 10, 100.0, 0.0, false).unwrap()
1115        );
1116        assert_approx_equal!(
1117            -150.01573028944f64,
1118            payment(1.5, 10, 100.0, 0.0, false).unwrap()
1119        );
1120        assert_approx_equal!(-10f64, payment(0.0, 10, 100.0, 0.0, false).unwrap());
1121        assert_approx_equal!(
1122            -10.00055000825f64,
1123            payment(0.00001, 10, 100.0, 0.0, false).unwrap()
1124        );
1125        assert_approx_equal!(
1126            8.22683411973293f64,
1127            payment(-0.034, 10, -100.0, 0.0, false).unwrap()
1128        );
1129        assert_approx_equal!(
1130            9.82270640070143f64,
1131            payment(0.034, 10, -100.0, 25.0, false).unwrap()
1132        );
1133        assert_approx_equal!(
1134            14.1045106678357f64,
1135            payment(0.034, 10, -100.0, -25.0, false).unwrap()
1136        );
1137        assert_approx_equal!(-10f64, payment(0.0, 10, 100.0, 0.0, false).unwrap());
1138        assert_approx_equal!(-11f64, payment(0.0, 10, 100.0, 10.0, false).unwrap());
1139        assert_approx_equal!(-9f64, payment(0.0, 10, 100.0, -10.0, false).unwrap());
1140        assert_approx_equal!(-1f64, payment(0.0, 10, 10.0, 0.0, false).unwrap());
1141        assert_approx_equal!(-11f64, payment(0.0, 10, 10.0, 100.0, false).unwrap());
1142        assert_approx_equal!(9f64, payment(0.0, 10, 10.0, -100.0, false).unwrap());
1143        assert_approx_equal!(10f64, payment(0.0, 10, -100.0, 0.0, false).unwrap());
1144        assert_approx_equal!(9f64, payment(0.0, 10, -100.0, 10.0, false).unwrap());
1145        assert_approx_equal!(11f64, payment(0.0, 10, -100.0, -10.0, false).unwrap());
1146        assert_approx_equal!(1f64, payment(0.0, 10, -10.0, 0.0, false).unwrap());
1147        assert_approx_equal!(-9f64, payment(0.0, 10, -10.0, 100.0, false).unwrap());
1148        assert_approx_equal!(11f64, payment(0.0, 10, -10.0, -100.0, false).unwrap());
1149    }
1150
1151    /*
1152    #[test]
1153    fn test_payment_edge() {
1154        // Zero interest.
1155        assert_rounded_6!(-10.0, payment(0.0, 10, 100.0, 0.0).unwrap());
1156        // Zero periods but it's OK because the present and future value are equal.
1157        assert_rounded_6!(0.0, payment(0.05, 0, 100.0, 100.0).unwrap());
1158    }
1159    */
1160
1161    #[test]
1162    fn test_payment_due_at_beginning_nominal() {
1163        assert_approx_equal!(
1164            -11.5702210196021f64,
1165            payment(0.034, 10, 100.0, 0.0, true).unwrap()
1166        );
1167        assert_approx_equal!(
1168            -8.51639142829496f64,
1169            payment(-0.034, 10, 100.0, 0.0, true).unwrap()
1170        );
1171        assert_approx_equal!(
1172            -8.51639142829496f64,
1173            payment(-0.034, 10, 100.0, 0.0, true).unwrap()
1174        );
1175        assert_approx_equal!(
1176            -50.0488758553275f64,
1177            payment(1.0, 10, 100.0, 0.0, true).unwrap()
1178        );
1179        assert_approx_equal!(
1180            -60.0062921157762f64,
1181            payment(1.5, 10, 100.0, 0.0, true).unwrap()
1182        );
1183        assert_approx_equal!(-10f64, payment(0.0, 10, 100.0, 0.0, true).unwrap());
1184        assert_approx_equal!(
1185            -10.0004500037499f64,
1186            payment(0.00001, 10, 100.0, 0.0, true).unwrap()
1187        );
1188        assert_approx_equal!(
1189            8.51639142829496f64,
1190            payment(-0.034, 10, -100.0, 0.0, true).unwrap()
1191        );
1192        assert_approx_equal!(
1193            9.49971605483697f64,
1194            payment(0.034, 10, -100.0, 25.0, true).unwrap()
1195        );
1196        assert_approx_equal!(
1197            13.6407259843672f64,
1198            payment(0.034, 10, -100.0, -25.0, true).unwrap()
1199        );
1200        assert_approx_equal!(-10f64, payment(0.0, 10, 100.0, 0.0, true).unwrap());
1201        assert_approx_equal!(-11f64, payment(0.0, 10, 100.0, 10.0, true).unwrap());
1202        assert_approx_equal!(-9f64, payment(0.0, 10, 100.0, -10.0, true).unwrap());
1203        assert_approx_equal!(-1f64, payment(0.0, 10, 10.0, 0.0, true).unwrap());
1204        assert_approx_equal!(-11f64, payment(0.0, 10, 10.0, 100.0, true).unwrap());
1205        assert_approx_equal!(9f64, payment(0.0, 10, 10.0, -100.0, true).unwrap());
1206        assert_approx_equal!(10f64, payment(0.0, 10, -100.0, 0.0, true).unwrap());
1207        assert_approx_equal!(9f64, payment(0.0, 10, -100.0, 10.0, true).unwrap());
1208        assert_approx_equal!(11f64, payment(0.0, 10, -100.0, -10.0, true).unwrap());
1209        assert_approx_equal!(1f64, payment(0.0, 10, -10.0, 0.0, true).unwrap());
1210        assert_approx_equal!(-9f64, payment(0.0, 10, -10.0, 100.0, true).unwrap());
1211        assert_approx_equal!(11f64, payment(0.0, 10, -10.0, -100.0, true).unwrap());
1212    }
1213
1214    /*
1215    #[should_panic]
1216    #[test]
1217    fn test_future_value_error_rate_low() {
1218        future_value(-101.0, 5, 250_000.00);
1219    }
1220    */
1221
1222    /*
1223    #[test]
1224    fn test_combinations() {
1225        // let rates = vec![-0.99, -0.5, -0.05, -0.005, 0.0, 0.005, 0.05, 0.5, 1.0, 10.0, 100.0];
1226        let rates = vec![0.0, 0.005, 0.05, 0.5, 1.0, 10.0, 100.0];
1227        let periods: Vec<u32> = vec![0, 1, 2, 5, 10, 36, 100, 500];
1228        let values: Vec<f64> = vec![-1_000_000.0, -1_234.98, -1.0, 0.0, 5.55555, 99_999.99];
1229        for rate_one in rates.iter() {
1230            for periods_one in periods.iter() {
1231                for present_value_one in values.iter() {
1232                    for future_value_one in values.iter() {
1233                        for due_at_beginning_one in [false, true].iter() {
1234                            println!();
1235                            dbg!(rate_one, periods_one, present_value_one, future_value_one, due_at_beginning_one);
1236                            if !(*periods_one == 0 && *present_value_one + *future_value_one != 0.0) {
1237                                let solution = if *due_at_beginning_one {
1238                                    payment_solution(*rate_one, *periods_one, *present_value_one, *future_value_one).unwrap()
1239                                } else {
1240                                    payment_due_solution(*rate_one, *periods_one, *present_value_one, *future_value_one)
1241                                };
1242                                let series = solution.series();
1243                                //bg!(&solution, &series);
1244                                // If we're already calling the invariant functions at the end of
1245                                // payment_solution_internal() and payment_series() there's no point in
1246                                // running them again.
1247                                if !RUN_PAYMENT_INVARIANTS {
1248                                    run_payment_invariants(&solution, &series);
1249                                }
1250                            }
1251                        }
1252                    }
1253                }
1254            }
1255        }
1256    }
1257    */
1258
1259    fn run_payment_invariants(solution: &PaymentSolution, series: &PaymentSeries) {
1260        // Display the solution and series only if either one fails its invariant.
1261        let result = std::panic::catch_unwind(|| {
1262            solution.invariant();
1263            series.invariant(solution);
1264        });
1265        //bg!(&result);
1266        if result.is_err() {
1267            dbg!(&solution, &series);
1268            solution.invariant();
1269            series.invariant(solution);
1270        }
1271    }
1272
1273    #[test]
1274    fn test_against_excel_ipmt_month_1() {
1275        // Payments at the end of the period.
1276        let solution = payment_solution(0.0056, 12, 20000.0, 0.0, false).unwrap();
1277        assert_approx_equal!(-1727.95439349254, solution.payment());
1278        let series = solution.series();
1279        assert_approx_equal!(-112.0, series[0].interest());
1280        assert_approx_equal!(-102.950655396442, series[1].interest());
1281        assert_approx_equal!(-93.8506344631036, series[2].interest());
1282        assert_approx_equal!(-84.6996534125387, series[3].interest());
1283        assert_approx_equal!(-75.4974268680907, series[4].interest());
1284        assert_approx_equal!(-66.2436678549938, series[5].interest());
1285        assert_approx_equal!(-56.9380877914235, series[6].interest());
1286        assert_approx_equal!(-47.5803964794972, series[7].interest());
1287        assert_approx_equal!(-38.1703020962241, series[8].interest());
1288        assert_approx_equal!(-28.7075111844048, series[9].interest());
1289        assert_approx_equal!(-19.1917286434792, series[10].interest());
1290        assert_approx_equal!(-9.62265772032443, series[11].interest());
1291    }
1292
1293    #[test]
1294    fn test_against_excel_ipmt_month_2() {
1295        // Payments at the beginning of the period.
1296        let solution = payment_solution(0.0056, 12, 20000.0, 0.0, true).unwrap();
1297        assert_approx_equal!(-1718.33173577222, solution.payment());
1298        let series = solution.series();
1299        assert_approx_equal!(0.0, series[0].interest());
1300        assert_approx_equal!(-102.377342279676, series[1].interest());
1301        assert_approx_equal!(-93.3279976761173, series[2].interest());
1302        assert_approx_equal!(-84.2279767427791, series[3].interest());
1303        assert_approx_equal!(-75.0769956922143, series[4].interest());
1304        assert_approx_equal!(-65.8747691477663, series[5].interest());
1305        assert_approx_equal!(-56.6210101346693, series[6].interest());
1306        assert_approx_equal!(-47.315430071099, series[7].interest());
1307        assert_approx_equal!(-37.9577387591728, series[8].interest());
1308        assert_approx_equal!(-28.5476443758997, series[9].interest());
1309        assert_approx_equal!(-19.0848534640803, series[10].interest());
1310        assert_approx_equal!(-9.56907092315476, series[11].interest());
1311    }
1312
1313    #[test]
1314    fn test_against_excel_pmt_mod_5() {
1315        assert_approx_equal!(
1316            26063.0811111111f64,
1317            payment(-0.1, 1, -12345.67, -12345.67, true).unwrap()
1318        );
1319        assert_approx_equal!(
1320            11111.103f64,
1321            payment(-0.1, 1, -12345.67, 0.0, false).unwrap()
1322        );
1323        assert_approx_equal!(
1324            12208.4958888889f64,
1325            payment(-0.1, 1, -12345.67, 123.4567, true).unwrap()
1326        );
1327        assert_approx_equal!(
1328            234.56773f64,
1329            payment(-0.1, 1, -123.4567, -123.4567, false).unwrap()
1330        );
1331        assert_approx_equal!(123.4567f64, payment(-0.1, 1, -123.4567, 0.0, true).unwrap());
1332        assert_approx_equal!(
1333            -12234.55897f64,
1334            payment(-0.1, 1, -123.4567, 12345.67, false).unwrap()
1335        );
1336        assert_approx_equal!(
1337            138.408678111111f64,
1338            payment(-0.1, 1, -1.234567, -123.4567, true).unwrap()
1339        );
1340        assert_approx_equal!(
1341            -0.1234567f64,
1342            payment(-0.1, 1, -1.234567, 1.234567, false).unwrap()
1343        );
1344        assert_approx_equal!(
1345            -13716.1765441111f64,
1346            payment(-0.1, 1, -1.234567, 12345.67, true).unwrap()
1347        );
1348        assert_approx_equal!(
1349            1.234567f64,
1350            payment(-0.1, 1, 0.0, -1.234567, false).unwrap()
1351        );
1352        assert_approx_equal!(
1353            -1.37174111111111f64,
1354            payment(-0.1, 1, 0.0, 1.234567, true).unwrap()
1355        );
1356        assert_approx_equal!(
1357            12344.5588897f64,
1358            payment(-0.1, 1, 1.234567, -12345.67, false).unwrap()
1359        );
1360        assert_approx_equal!(
1361            0.137174111111111f64,
1362            payment(-0.1, 1, 1.234567, -1.234567, true).unwrap()
1363        );
1364        assert_approx_equal!(
1365            -124.5678103f64,
1366            payment(-0.1, 1, 1.234567, 123.4567, false).unwrap()
1367        );
1368        assert_approx_equal!(
1369            13593.9544111111f64,
1370            payment(-0.1, 1, 123.4567, -12345.67, true).unwrap()
1371        );
1372        assert_approx_equal!(
1373            -111.11103f64,
1374            payment(-0.1, 1, 123.4567, 0.0, false).unwrap()
1375        );
1376        assert_approx_equal!(
1377            -260.630811111111f64,
1378            payment(-0.1, 1, 123.4567, 123.4567, true).unwrap()
1379        );
1380        assert_approx_equal!(
1381            -10987.6463f64,
1382            payment(-0.1, 1, 12345.67, -123.4567, false).unwrap()
1383        );
1384        assert_approx_equal!(-12345.67f64, payment(-0.1, 1, 12345.67, 0.0, true).unwrap());
1385        assert_approx_equal!(
1386            -23456.773f64,
1387            payment(-0.1, 1, 12345.67, 12345.67, false).unwrap()
1388        );
1389        assert_approx_equal!(
1390            5920.14584795322f64,
1391            payment(-0.1, 2, -12345.67, -123.4567, true).unwrap()
1392        );
1393        assert_approx_equal!(
1394            5262.50428052632f64,
1395            payment(-0.1, 2, -12345.67, 1.234567, false).unwrap()
1396        );
1397        assert_approx_equal!(
1398            -1371.74111111111f64,
1399            payment(-0.1, 2, -12345.67, 12345.67, true).unwrap()
1400        );
1401        assert_approx_equal!(
1402            53.2813126315789f64,
1403            payment(-0.1, 2, -123.4567, -1.234567, false).unwrap()
1404        );
1405        assert_approx_equal!(
1406            57.7575204678363f64,
1407            payment(-0.1, 2, -123.4567, 1.234567, true).unwrap()
1408        );
1409        assert_approx_equal!(
1410            6498.24736803684f64,
1411            payment(-0.1, 2, -1.234567, -12345.67, false).unwrap()
1412        );
1413        assert_approx_equal!(
1414            1.3067639005848f64,
1415            payment(-0.1, 2, -1.234567, -1.234567, true).unwrap()
1416        );
1417        assert_approx_equal!(
1418            -64.4508951210526f64,
1419            payment(-0.1, 2, -1.234567, 123.4567, false).unwrap()
1420        );
1421        assert_approx_equal!(
1422            7219.69005847953f64,
1423            payment(-0.1, 2, 0.0, -12345.67, true).unwrap()
1424        );
1425        assert_approx_equal!(0f64, payment(-0.1, 2, 0.0, 0.0, false).unwrap());
1426        assert_approx_equal!(
1427            -72.1969005847953f64,
1428            payment(-0.1, 2, 0.0, 123.4567, true).unwrap()
1429        );
1430        assert_approx_equal!(
1431            64.4508951210526f64,
1432            payment(-0.1, 2, 1.234567, -123.4567, false).unwrap()
1433        );
1434        assert_approx_equal!(
1435            -0.584794894736842f64,
1436            payment(-0.1, 2, 1.234567, 0.0, true).unwrap()
1437        );
1438        assert_approx_equal!(
1439            -6498.24736803684f64,
1440            payment(-0.1, 2, 1.234567, 12345.67, false).unwrap()
1441        );
1442        assert_approx_equal!(
1443            13.7174111111111f64,
1444            payment(-0.1, 2, 123.4567, -123.4567, true).unwrap()
1445        );
1446        assert_approx_equal!(
1447            -53.2813126315789f64,
1448            payment(-0.1, 2, 123.4567, 1.234567, false).unwrap()
1449        );
1450        assert_approx_equal!(
1451            -7278.16954795322f64,
1452            payment(-0.1, 2, 123.4567, 12345.67, true).unwrap()
1453        );
1454        assert_approx_equal!(
1455            -5262.50428052632f64,
1456            payment(-0.1, 2, 12345.67, -1.234567, false).unwrap()
1457        );
1458        assert_approx_equal!(
1459            -5848.67091637427f64,
1460            payment(-0.1, 2, 12345.67, 1.234567, true).unwrap()
1461        );
1462        assert_approx_equal!(
1463            4794.91701748431f64,
1464            payment(-0.1, 5, -12345.67, -12345.67, false).unwrap()
1465        );
1466        assert_approx_equal!(
1467            1978.30720327003f64,
1468            payment(-0.1, 5, -12345.67, -1.234567, true).unwrap()
1469        );
1470        assert_approx_equal!(
1471            1750.02758865473f64,
1472            payment(-0.1, 5, -12345.67, 123.4567, false).unwrap()
1473        );
1474        assert_approx_equal!(
1475            3369.4930653662f64,
1476            payment(-0.1, 5, -123.4567, -12345.67, true).unwrap()
1477        );
1478        assert_approx_equal!(
1479            17.8017500874216f64,
1480            payment(-0.1, 5, -123.4567, 0.0, false).unwrap()
1481        );
1482        assert_approx_equal!(
1483            -13.7174111111111f64,
1484            payment(-0.1, 5, -123.4567, 123.4567, true).unwrap()
1485        );
1486        assert_approx_equal!(
1487            30.3254375882958f64,
1488            payment(-0.1, 5, -1.234567, -123.4567, false).unwrap()
1489        );
1490        assert_approx_equal!(
1491            0.197797223193573f64,
1492            payment(-0.1, 5, -1.234567, 0.0, true).unwrap()
1493        );
1494        assert_approx_equal!(
1495            -3014.56399124128f64,
1496            payment(-0.1, 5, -1.234567, 12345.67, false).unwrap()
1497        );
1498        assert_approx_equal!(
1499            33.4971334304684f64,
1500            payment(-0.1, 5, 0.0, -123.4567, true).unwrap()
1501        );
1502        assert_approx_equal!(
1503            -0.301474200874216f64,
1504            payment(-0.1, 5, 0.0, 1.234567, false).unwrap()
1505        );
1506        assert_approx_equal!(
1507            -3349.71334304684f64,
1508            payment(-0.1, 5, 0.0, 12345.67, true).unwrap()
1509        );
1510        assert_approx_equal!(
1511            0.1234567f64,
1512            payment(-0.1, 5, 1.234567, -1.234567, false).unwrap()
1513        );
1514        assert_approx_equal!(
1515            -0.532768557498257f64,
1516            payment(-0.1, 5, 1.234567, 1.234567, true).unwrap()
1517        );
1518        assert_approx_equal!(
1519            2996.94025865473f64,
1520            payment(-0.1, 5, 123.4567, -12345.67, false).unwrap()
1521        );
1522        assert_approx_equal!(
1523            -19.4447509850526f64,
1524            payment(-0.1, 5, 123.4567, -1.234567, true).unwrap()
1525        );
1526        assert_approx_equal!(
1527            -47.9491701748431f64,
1528            payment(-0.1, 5, 123.4567, 123.4567, false).unwrap()
1529        );
1530        assert_approx_equal!(
1531            1371.74111111111f64,
1532            payment(-0.1, 5, 12345.67, -12345.67, true).unwrap()
1533        );
1534        assert_approx_equal!(
1535            -1780.17500874216f64,
1536            payment(-0.1, 5, 12345.67, 0.0, false).unwrap()
1537        );
1538        assert_approx_equal!(
1539            -2011.4693653662f64,
1540            payment(-0.1, 5, 12345.67, 123.4567, true).unwrap()
1541        );
1542        assert_approx_equal!(
1543            679.867814949844f64,
1544            payment(-0.1, 10, -12345.67, -123.4567, false).unwrap()
1545        );
1546        assert_approx_equal!(
1547            734.34779422425f64,
1548            payment(-0.1, 10, -12345.67, 0.0, true).unwrap()
1549        );
1550        assert_approx_equal!(
1551            -1234.567f64,
1552            payment(-0.1, 10, -12345.67, 12345.67, false).unwrap()
1553        );
1554        assert_approx_equal!(
1555            28.4043669955961f64,
1556            payment(-0.1, 10, -123.4567, -123.4567, true).unwrap()
1557        );
1558        assert_approx_equal!(
1559            6.41958214653807f64,
1560            payment(-0.1, 10, -123.4567, 1.234567, false).unwrap()
1561        );
1562        assert_approx_equal!(
1563            -2098.74542739312f64,
1564            payment(-0.1, 10, -123.4567, 12345.67, true).unwrap()
1565        );
1566        assert_approx_equal!(
1567            0.255639302960365f64,
1568            payment(-0.1, 10, -1.234567, -1.234567, false).unwrap()
1569        );
1570        assert_approx_equal!(
1571            -0.137174111111111f64,
1572            payment(-0.1, 10, -1.234567, 1.234567, true).unwrap()
1573        );
1574        assert_approx_equal!(
1575            1895.48001480183f64,
1576            payment(-0.1, 10, 0.0, -12345.67, false).unwrap()
1577        );
1578        assert_approx_equal!(
1579            0.210608890533536f64,
1580            payment(-0.1, 10, 0.0, -1.234567, true).unwrap()
1581        );
1582        assert_approx_equal!(
1583            -18.9548001480183f64,
1584            payment(-0.1, 10, 0.0, 123.4567, false).unwrap()
1585        );
1586        assert_approx_equal!(
1587            2106.01547055594f64,
1588            payment(-0.1, 10, 1.234567, -12345.67, true).unwrap()
1589        );
1590        assert_approx_equal!(
1591            -0.0660913014801825f64,
1592            payment(-0.1, 10, 1.234567, 0.0, false).unwrap()
1593        );
1594        assert_approx_equal!(
1595            -21.134323832776f64,
1596            payment(-0.1, 10, 1.234567, 123.4567, true).unwrap()
1597        );
1598        assert_approx_equal!(
1599            12.34567f64,
1600            payment(-0.1, 10, 123.4567, -123.4567, false).unwrap()
1601        );
1602        assert_approx_equal!(
1603            -7.3434779422425f64,
1604            payment(-0.1, 10, 123.4567, 0.0, true).unwrap()
1605        );
1606        assert_approx_equal!(
1607            -1902.08914494984f64,
1608            payment(-0.1, 10, 123.4567, 12345.67, false).unwrap()
1609        );
1610        assert_approx_equal!(
1611            -713.286905170897f64,
1612            payment(-0.1, 10, 12345.67, -123.4567, true).unwrap()
1613        );
1614        assert_approx_equal!(
1615            -661.102562803305f64,
1616            payment(-0.1, 10, 12345.67, 1.234567, false).unwrap()
1617        );
1618        assert_approx_equal!(
1619            -2840.43669955961f64,
1620            payment(-0.1, 10, 12345.67, 12345.67, true).unwrap()
1621        );
1622        assert_approx_equal!(
1623            6.51973876437762f64,
1624            payment(-0.1, 50, -12345.67, -1.234567, false).unwrap()
1625        );
1626        assert_approx_equal!(
1627            6.96838470653066f64,
1628            payment(-0.1, 50, -12345.67, 1.234567, true).unwrap()
1629        );
1630        assert_approx_equal!(
1631            1241.02659892513f64,
1632            payment(-0.1, 50, -123.4567, -12345.67, false).unwrap()
1633        );
1634        assert_approx_equal!(
1635            0.208947432501432f64,
1636            payment(-0.1, 50, -123.4567, -1.234567, true).unwrap()
1637        );
1638        assert_approx_equal!(
1639            -12.34567f64,
1640            payment(-0.1, 50, -123.4567, 123.4567, false).unwrap()
1641        );
1642        assert_approx_equal!(
1643            1378.84809118264f64,
1644            payment(-0.1, 50, -1.234567, -12345.67, true).unwrap()
1645        );
1646        assert_approx_equal!(
1647            0.000639564250012761f64,
1648            payment(-0.1, 50, -1.234567, 0.0, false).unwrap()
1649        );
1650        assert_approx_equal!(
1651            -13.7877631786125f64,
1652            payment(-0.1, 50, -1.234567, 123.4567, true).unwrap()
1653        );
1654        assert_approx_equal!(
1655            12.4096264250013f64,
1656            payment(-0.1, 50, 0.0, -123.4567, false).unwrap()
1657        );
1658        assert_approx_equal!(0f64, payment(-0.1, 50, 0.0, 0.0, true).unwrap());
1659        assert_approx_equal!(
1660            -1240.96264250013f64,
1661            payment(-0.1, 50, 0.0, 12345.67, false).unwrap()
1662        );
1663        assert_approx_equal!(
1664            13.7877631786125f64,
1665            payment(-0.1, 50, 1.234567, -123.4567, true).unwrap()
1666        );
1667        assert_approx_equal!(
1668            -0.124735828500026f64,
1669            payment(-0.1, 50, 1.234567, 1.234567, false).unwrap()
1670        );
1671        assert_approx_equal!(
1672            -1378.84809118264f64,
1673            payment(-0.1, 50, 1.234567, 12345.67, true).unwrap()
1674        );
1675        assert_approx_equal!(
1676            0.0601398392487366f64,
1677            payment(-0.1, 50, 123.4567, -1.234567, false).unwrap()
1678        );
1679        assert_approx_equal!(
1680            -0.208947432501432f64,
1681            payment(-0.1, 50, 123.4567, 1.234567, true).unwrap()
1682        );
1683        assert_approx_equal!(
1684            1234.567f64,
1685            payment(-0.1, 50, 12345.67, -12345.67, false).unwrap()
1686        );
1687        assert_approx_equal!(
1688            -6.96838470653066f64,
1689            payment(-0.1, 50, 12345.67, -1.234567, true).unwrap()
1690        );
1691        assert_approx_equal!(
1692            -18.8052689251289f64,
1693            payment(-0.1, 50, 12345.67, 123.4567, false).unwrap()
1694        );
1695        assert_approx_equal!(
1696            1371.74111112109f64,
1697            payment(-0.1, 250, -12345.67, -12345.67, true).unwrap()
1698        );
1699        assert_approx_equal!(
1700            4.48892163617149E-09f64,
1701            payment(-0.1, 250, -12345.67, 0.0, false).unwrap()
1702        );
1703        assert_approx_equal!(
1704            -13.7174111061733f64,
1705            payment(-0.1, 250, -12345.67, 123.4567, true).unwrap()
1706        );
1707        assert_approx_equal!(
1708            12.3456700000898f64,
1709            payment(-0.1, 250, -123.4567, -123.4567, false).unwrap()
1710        );
1711        assert_approx_equal!(
1712            4.98769070685721E-11f64,
1713            payment(-0.1, 250, -123.4567, 0.0, true).unwrap()
1714        );
1715        assert_approx_equal!(
1716            -1234.56700000444f64,
1717            payment(-0.1, 250, -123.4567, 12345.67, false).unwrap()
1718        );
1719        assert_approx_equal!(
1720            13.7174111111615f64,
1721            payment(-0.1, 250, -1.234567, -123.4567, true).unwrap()
1722        );
1723        assert_approx_equal!(
1724            -0.1234567f64,
1725            payment(-0.1, 250, -1.234567, 1.234567, false).unwrap()
1726        );
1727        assert_approx_equal!(
1728            -1371.7411111161f64,
1729            payment(-0.1, 250, -1.234567, 12345.67, true).unwrap()
1730        );
1731        assert_approx_equal!(
1732            0.123456700000449f64,
1733            payment(-0.1, 250, 0.0, -1.234567, false).unwrap()
1734        );
1735        assert_approx_equal!(
1736            -0.13717411111161f64,
1737            payment(-0.1, 250, 0.0, 1.234567, true).unwrap()
1738        );
1739        assert_approx_equal!(
1740            1234.56700000449f64,
1741            payment(-0.1, 250, 1.234567, -12345.67, false).unwrap()
1742        );
1743        assert_approx_equal!(
1744            0.137174111111111f64,
1745            payment(-0.1, 250, 1.234567, -1.234567, true).unwrap()
1746        );
1747        assert_approx_equal!(
1748            -12.3456700000453f64,
1749            payment(-0.1, 250, 1.234567, 123.4567, false).unwrap()
1750        );
1751        assert_approx_equal!(
1752            1371.74111111605f64,
1753            payment(-0.1, 250, 123.4567, -12345.67, true).unwrap()
1754        );
1755        assert_approx_equal!(
1756            -4.48892163617149E-11f64,
1757            payment(-0.1, 250, 123.4567, 0.0, false).unwrap()
1758        );
1759        assert_approx_equal!(
1760            -13.7174111112109f64,
1761            payment(-0.1, 250, 123.4567, 123.4567, true).unwrap()
1762        );
1763        assert_approx_equal!(
1764            12.345669995556f64,
1765            payment(-0.1, 250, 12345.67, -123.4567, false).unwrap()
1766        );
1767        assert_approx_equal!(
1768            -4.98769070685721E-09f64,
1769            payment(-0.1, 250, 12345.67, 0.0, true).unwrap()
1770        );
1771        assert_approx_equal!(
1772            -1234.56700000898f64,
1773            payment(-0.1, 250, 12345.67, 12345.67, false).unwrap()
1774        );
1775        assert_approx_equal!(
1776            12223.447867f64,
1777            payment(-0.01, 1, -12345.67, -1.234567, false).unwrap()
1778        );
1779        assert_approx_equal!(
1780            12344.4229626263f64,
1781            payment(-0.01, 1, -12345.67, 1.234567, true).unwrap()
1782        );
1783        assert_approx_equal!(
1784            12467.892133f64,
1785            payment(-0.01, 1, -123.4567, -12345.67, false).unwrap()
1786        );
1787        assert_approx_equal!(
1788            124.703737373737f64,
1789            payment(-0.01, 1, -123.4567, -1.234567, true).unwrap()
1790        );
1791        assert_approx_equal!(
1792            -1.234567f64,
1793            payment(-0.01, 1, -123.4567, 123.4567, false).unwrap()
1794        );
1795        assert_approx_equal!(
1796            12471.6083043737f64,
1797            payment(-0.01, 1, -1.234567, -12345.67, true).unwrap()
1798        );
1799        assert_approx_equal!(
1800            1.22222133f64,
1801            payment(-0.01, 1, -1.234567, 0.0, false).unwrap()
1802        );
1803        assert_approx_equal!(
1804            -123.469170373737f64,
1805            payment(-0.01, 1, -1.234567, 123.4567, true).unwrap()
1806        );
1807        assert_approx_equal!(
1808            123.4567f64,
1809            payment(-0.01, 1, 0.0, -123.4567, false).unwrap()
1810        );
1811        assert_approx_equal!(0f64, payment(-0.01, 1, 0.0, 0.0, true).unwrap());
1812        assert_approx_equal!(
1813            -12345.67f64,
1814            payment(-0.01, 1, 0.0, 12345.67, false).unwrap()
1815        );
1816        assert_approx_equal!(
1817            123.469170373737f64,
1818            payment(-0.01, 1, 1.234567, -123.4567, true).unwrap()
1819        );
1820        assert_approx_equal!(
1821            -2.45678833f64,
1822            payment(-0.01, 1, 1.234567, 1.234567, false).unwrap()
1823        );
1824        assert_approx_equal!(
1825            -12471.6083043737f64,
1826            payment(-0.01, 1, 1.234567, 12345.67, true).unwrap()
1827        );
1828        assert_approx_equal!(
1829            -120.987566f64,
1830            payment(-0.01, 1, 123.4567, -1.234567, false).unwrap()
1831        );
1832        assert_approx_equal!(
1833            -124.703737373737f64,
1834            payment(-0.01, 1, 123.4567, 1.234567, true).unwrap()
1835        );
1836        assert_approx_equal!(
1837            123.4567f64,
1838            payment(-0.01, 1, 12345.67, -12345.67, false).unwrap()
1839        );
1840        assert_approx_equal!(
1841            -12344.4229626263f64,
1842            payment(-0.01, 1, 12345.67, -1.234567, true).unwrap()
1843        );
1844        assert_approx_equal!(
1845            -12345.67f64,
1846            payment(-0.01, 1, 12345.67, 123.4567, false).unwrap()
1847        );
1848        assert_approx_equal!(
1849            12408.3351946602f64,
1850            payment(-0.01, 2, -12345.67, -12345.67, true).unwrap()
1851        );
1852        assert_approx_equal!(
1853            6080.39757135678f64,
1854            payment(-0.01, 2, -12345.67, 0.0, false).unwrap()
1855        );
1856        assert_approx_equal!(
1857            6079.15053398305f64,
1858            payment(-0.01, 2, -12345.67, 123.4567, true).unwrap()
1859        );
1860        assert_approx_equal!(
1861            122.842518427136f64,
1862            payment(-0.01, 2, -123.4567, -123.4567, false).unwrap()
1863        );
1864        assert_approx_equal!(
1865            61.4181572864322f64,
1866            payment(-0.01, 2, -123.4567, 0.0, true).unwrap()
1867        );
1868        assert_approx_equal!(
1869            -6143.05029564322f64,
1870            payment(-0.01, 2, -123.4567, 12345.67, false).unwrap()
1871        );
1872        assert_approx_equal!(
1873            63.2793762330339f64,
1874            payment(-0.01, 2, -1.234567, -123.4567, true).unwrap()
1875        );
1876        assert_approx_equal!(
1877            -0.01234567f64,
1878            payment(-0.01, 2, -1.234567, 1.234567, false).unwrap()
1879        );
1880        assert_approx_equal!(
1881            -6265.90528444409f64,
1882            payment(-0.01, 2, -1.234567, 12345.67, true).unwrap()
1883        );
1884        assert_approx_equal!(
1885            0.620385427135678f64,
1886            payment(-0.01, 2, 0.0, -1.234567, false).unwrap()
1887        );
1888        assert_approx_equal!(
1889            -0.626651946601695f64,
1890            payment(-0.01, 2, 0.0, 1.234567, true).unwrap()
1891        );
1892        assert_approx_equal!(
1893            6203.24623159965f64,
1894            payment(-0.01, 2, 1.234567, -12345.67, false).unwrap()
1895        );
1896        assert_approx_equal!(
1897            0.0124703737373737f64,
1898            payment(-0.01, 2, 1.234567, -1.234567, true).unwrap()
1899        );
1900        assert_approx_equal!(
1901            -62.6465824707035f64,
1902            payment(-0.01, 2, 1.234567, 123.4567, false).unwrap()
1903        );
1904        assert_approx_equal!(
1905            6205.10130873052f64,
1906            payment(-0.01, 2, 123.4567, -12345.67, true).unwrap()
1907        );
1908        assert_approx_equal!(
1909            -60.8039757135678f64,
1910            payment(-0.01, 2, 123.4567, 0.0, false).unwrap()
1911        );
1912        assert_approx_equal!(
1913            -124.083351946602f64,
1914            payment(-0.01, 2, 123.4567, 123.4567, true).unwrap()
1915        );
1916        assert_approx_equal!(
1917            -6018.35902864322f64,
1918            payment(-0.01, 2, 12345.67, -123.4567, false).unwrap()
1919        );
1920        assert_approx_equal!(
1921            -6141.81572864322f64,
1922            payment(-0.01, 2, 12345.67, 0.0, true).unwrap()
1923        );
1924        assert_approx_equal!(
1925            -12284.2518427136f64,
1926            payment(-0.01, 2, 12345.67, 12345.67, false).unwrap()
1927        );
1928        assert_approx_equal!(
1929            2445.19838434817f64,
1930            payment(-0.01, 5, -12345.67, -123.4567, true).unwrap()
1931        );
1932        assert_approx_equal!(
1933            2395.30436949964f64,
1934            payment(-0.01, 5, -12345.67, 1.234567, false).unwrap()
1935        );
1936        assert_approx_equal!(
1937            -124.703737373737f64,
1938            payment(-0.01, 5, -12345.67, 12345.67, true).unwrap()
1939        );
1940        assert_approx_equal!(
1941            24.2074640050469f64,
1942            payment(-0.01, 5, -123.4567, -1.234567, false).unwrap()
1943        );
1944        assert_approx_equal!(
1945            23.9430923342298f64,
1946            payment(-0.01, 5, -123.4567, 1.234567, true).unwrap()
1947        );
1948        assert_approx_equal!(
1949            2519.2525264238f64,
1950            payment(-0.01, 5, -1.234567, -12345.67, false).unwrap()
1951        );
1952        assert_approx_equal!(
1953            0.496421135514489f64,
1954            payment(-0.01, 5, -1.234567, -1.234567, true).unwrap()
1955        );
1956        assert_approx_equal!(
1957            -24.9505740808875f64,
1958            payment(-0.01, 5, -1.234567, 123.4567, false).unwrap()
1959        );
1960        assert_approx_equal!(
1961            2544.45754625931f64,
1962            payment(-0.01, 5, 0.0, -12345.67, true).unwrap()
1963        );
1964        assert_approx_equal!(0f64, payment(-0.01, 5, 0.0, 0.0, false).unwrap());
1965        assert_approx_equal!(
1966            -25.4445754625931f64,
1967            payment(-0.01, 5, 0.0, 123.4567, true).unwrap()
1968        );
1969        assert_approx_equal!(
1970            24.9505740808875f64,
1971            payment(-0.01, 5, 1.234567, -123.4567, false).unwrap()
1972        );
1973        assert_approx_equal!(
1974            -0.241975380888558f64,
1975            payment(-0.01, 5, 1.234567, 0.0, true).unwrap()
1976        );
1977        assert_approx_equal!(
1978            -2519.2525264238f64,
1979            payment(-0.01, 5, 1.234567, 12345.67, false).unwrap()
1980        );
1981        assert_approx_equal!(
1982            1.24703737373737f64,
1983            payment(-0.01, 5, 123.4567, -123.4567, true).unwrap()
1984        );
1985        assert_approx_equal!(
1986            -24.2074640050469f64,
1987            payment(-0.01, 5, 123.4567, 1.234567, false).unwrap()
1988        );
1989        assert_approx_equal!(
1990            -2568.65508434817f64,
1991            payment(-0.01, 5, 123.4567, 12345.67, true).unwrap()
1992        );
1993        assert_approx_equal!(
1994            -2395.30436949964f64,
1995            payment(-0.01, 5, 12345.67, -1.234567, false).unwrap()
1996        );
1997        assert_approx_equal!(
1998            -2420.0082546402f64,
1999            payment(-0.01, 5, 12345.67, 1.234567, true).unwrap()
2000        );
2001        assert_approx_equal!(
2002            2458.83527112085f64,
2003            payment(-0.01, 10, -12345.67, -12345.67, false).unwrap()
2004        );
2005        assert_approx_equal!(
2006            1179.61454561513f64,
2007            payment(-0.01, 10, -12345.67, -1.234567, true).unwrap()
2008        );
2009        assert_approx_equal!(
2010            1154.77782570482f64,
2011            payment(-0.01, 10, -12345.67, 123.4567, false).unwrap()
2012        );
2013        assert_approx_equal!(
2014            1315.98270547074f64,
2015            payment(-0.01, 10, -123.4567, -12345.67, true).unwrap()
2016        );
2017        assert_approx_equal!(
2018            11.6768928556043f64,
2019            payment(-0.01, 10, -123.4567, 0.0, false).unwrap()
2020        );
2021        assert_approx_equal!(
2022            -1.24703737373737f64,
2023            payment(-0.01, 10, -123.4567, 123.4567, true).unwrap()
2024        );
2025        assert_approx_equal!(
2026            13.0282287841603f64,
2027            payment(-0.01, 10, -1.234567, -123.4567, false).unwrap()
2028        );
2029        assert_approx_equal!(
2030            0.117948412682871f64,
2031            payment(-0.01, 10, -1.234567, 0.0, true).unwrap()
2032        );
2033        assert_approx_equal!(
2034            -1291.02921663187f64,
2035            payment(-0.01, 10, -1.234567, 12345.67, false).unwrap()
2036        );
2037        assert_approx_equal!(
2038            13.0418786420245f64,
2039            payment(-0.01, 10, 0.0, -123.4567, true).unwrap()
2040        );
2041        assert_approx_equal!(
2042            -0.129114598556043f64,
2043            payment(-0.01, 10, 0.0, 1.234567, false).unwrap()
2044        );
2045        assert_approx_equal!(
2046            -1304.18786420245f64,
2047            payment(-0.01, 10, 0.0, 12345.67, true).unwrap()
2048        );
2049        assert_approx_equal!(
2050            0.01234567f64,
2051            payment(-0.01, 10, 1.234567, -1.234567, false).unwrap()
2052        );
2053        assert_approx_equal!(
2054            -0.248367199103116f64,
2055            payment(-0.01, 10, 1.234567, 1.234567, true).unwrap()
2056        );
2057        assert_approx_equal!(
2058            1279.46909270482f64,
2059            payment(-0.01, 10, 123.4567, -12345.67, false).unwrap()
2060        );
2061        assert_approx_equal!(
2062            -11.6644224818669f64,
2063            payment(-0.01, 10, 123.4567, -1.234567, true).unwrap()
2064        );
2065        assert_approx_equal!(
2066            -24.5883527112085f64,
2067            payment(-0.01, 10, 123.4567, 123.4567, false).unwrap()
2068        );
2069        assert_approx_equal!(
2070            124.703737373737f64,
2071            payment(-0.01, 10, 12345.67, -12345.67, true).unwrap()
2072        );
2073        assert_approx_equal!(
2074            -1167.68928556043f64,
2075            payment(-0.01, 10, 12345.67, 0.0, false).unwrap()
2076        );
2077        assert_approx_equal!(
2078            -1192.52600547074f64,
2079            payment(-0.01, 10, 12345.67, 123.4567, true).unwrap()
2080        );
2081        assert_approx_equal!(
2082            192.222242449522f64,
2083            payment(-0.01, 50, -12345.67, -123.4567, false).unwrap()
2084        );
2085        assert_approx_equal!(
2086            191.006776127135f64,
2087            payment(-0.01, 50, -12345.67, 0.0, true).unwrap()
2088        );
2089        assert_approx_equal!(
2090            -123.4567f64,
2091            payment(-0.01, 50, -12345.67, 12345.67, false).unwrap()
2092        );
2093        assert_approx_equal!(
2094            5.06717289628007f64,
2095            payment(-0.01, 50, -123.4567, -123.4567, true).unwrap()
2096        );
2097        assert_approx_equal!(
2098            1.85971174282205f64,
2099            payment(-0.01, 50, -123.4567, 1.234567, false).unwrap()
2100        );
2101        assert_approx_equal!(
2102            -313.800445739601f64,
2103            payment(-0.01, 50, -123.4567, 12345.67, true).unwrap()
2104        );
2105        assert_approx_equal!(
2106            0.0501650116731727f64,
2107            payment(-0.01, 50, -1.234567, -1.234567, false).unwrap()
2108        );
2109        assert_approx_equal!(
2110            -0.0124703737373737f64,
2111            payment(-0.01, 50, -1.234567, 1.234567, true).unwrap()
2112        );
2113        assert_approx_equal!(
2114            312.553408365864f64,
2115            payment(-0.01, 50, 0.0, -12345.67, false).unwrap()
2116        );
2117        assert_approx_equal!(
2118            0.0315710513500872f64,
2119            payment(-0.01, 50, 0.0, -1.234567, true).unwrap()
2120        );
2121        assert_approx_equal!(
2122            -3.12553408365864f64,
2123            payment(-0.01, 50, 0.0, 123.4567, false).unwrap()
2124        );
2125        assert_approx_equal!(
2126            315.69141282326f64,
2127            payment(-0.01, 50, 1.234567, -12345.67, true).unwrap()
2128        );
2129        assert_approx_equal!(
2130            -0.0189096708365864f64,
2131            payment(-0.01, 50, 1.234567, 0.0, false).unwrap()
2132        );
2133        assert_approx_equal!(
2134            -3.17620581262144f64,
2135            payment(-0.01, 50, 1.234567, 123.4567, true).unwrap()
2136        );
2137        assert_approx_equal!(
2138            1.234567f64,
2139            payment(-0.01, 50, 123.4567, -123.4567, false).unwrap()
2140        );
2141        assert_approx_equal!(
2142            -1.91006776127135f64,
2143            payment(-0.01, 50, 123.4567, 0.0, true).unwrap()
2144        );
2145        assert_approx_equal!(
2146            -314.444375449522f64,
2147            payment(-0.01, 50, 123.4567, 12345.67, false).unwrap()
2148        );
2149        assert_approx_equal!(
2150            -187.849670992126f64,
2151            payment(-0.01, 50, 12345.67, -123.4567, true).unwrap()
2152        );
2153        assert_approx_equal!(
2154            -189.1279637067f64,
2155            payment(-0.01, 50, 12345.67, 1.234567, false).unwrap()
2156        );
2157        assert_approx_equal!(
2158            -506.717289628007f64,
2159            payment(-0.01, 50, 12345.67, 12345.67, true).unwrap()
2160        );
2161        assert_approx_equal!(
2162            10.9033738910495f64,
2163            payment(-0.01, 250, -12345.67, -1.234567, false).unwrap()
2164        );
2165        assert_approx_equal!(
2166            10.9863682456607f64,
2167            payment(-0.01, 250, -12345.67, 1.234567, true).unwrap()
2168        );
2169        assert_approx_equal!(
2170            134.455538619398f64,
2171            payment(-0.01, 250, -123.4567, -12345.67, false).unwrap()
2172        );
2173        assert_approx_equal!(
2174            0.123569753731294f64,
2175            payment(-0.01, 250, -123.4567, -1.234567, true).unwrap()
2176        );
2177        assert_approx_equal!(
2178            -1.234567f64,
2179            payment(-0.01, 250, -123.4567, 123.4567, false).unwrap()
2180        );
2181        assert_approx_equal!(
2182            135.704775980858f64,
2183            payment(-0.01, 250, -1.234567, -12345.67, true).unwrap()
2184        );
2185        assert_approx_equal!(
2186            0.00108899392271268f64,
2187            payment(-0.01, 250, -1.234567, 0.0, false).unwrap()
2188        );
2189        assert_approx_equal!(
2190            -1.35593676600864f64,
2191            payment(-0.01, 250, -1.234567, 123.4567, true).unwrap()
2192        );
2193        assert_approx_equal!(
2194            1.34346639227127f64,
2195            payment(-0.01, 250, 0.0, -123.4567, false).unwrap()
2196        );
2197        assert_approx_equal!(0f64, payment(-0.01, 250, 0.0, 0.0, true).unwrap());
2198        assert_approx_equal!(
2199            -134.346639227127f64,
2200            payment(-0.01, 250, 0.0, 12345.67, false).unwrap()
2201        );
2202        assert_approx_equal!(
2203            1.35593676600864f64,
2204            payment(-0.01, 250, 1.234567, -123.4567, true).unwrap()
2205        );
2206        assert_approx_equal!(
2207            -0.0145236578454254f64,
2208            payment(-0.01, 250, 1.234567, 1.234567, false).unwrap()
2209        );
2210        assert_approx_equal!(
2211            -135.704775980858f64,
2212            payment(-0.01, 250, 1.234567, 12345.67, true).unwrap()
2213        );
2214        assert_approx_equal!(
2215            -0.0954647283485555f64,
2216            payment(-0.01, 250, 123.4567, -1.234567, false).unwrap()
2217        );
2218        assert_approx_equal!(
2219            -0.123569753731294f64,
2220            payment(-0.01, 250, 123.4567, 1.234567, true).unwrap()
2221        );
2222        assert_approx_equal!(
2223            123.4567f64,
2224            payment(-0.01, 250, 12345.67, -12345.67, false).unwrap()
2225        );
2226        assert_approx_equal!(
2227            -10.9863682456607f64,
2228            payment(-0.01, 250, 12345.67, -1.234567, true).unwrap()
2229        );
2230        assert_approx_equal!(
2231            -12.2334056193981f64,
2232            payment(-0.01, 250, 12345.67, 123.4567, false).unwrap()
2233        );
2234        assert_approx_equal!(
2235            12456.78103f64,
2236            payment(-0.001, 1, -12345.67, -123.4567, false).unwrap()
2237        );
2238        assert_approx_equal!(
2239            12345.67f64,
2240            payment(-0.001, 1, -12345.67, 0.0, true).unwrap()
2241        );
2242        assert_approx_equal!(
2243            -12.34567f64,
2244            payment(-0.001, 1, -12345.67, 12345.67, false).unwrap()
2245        );
2246        assert_approx_equal!(
2247            247.03698028028f64,
2248            payment(-0.001, 1, -123.4567, -123.4567, true).unwrap()
2249        );
2250        assert_approx_equal!(
2251            122.0986763f64,
2252            payment(-0.001, 1, -123.4567, 1.234567, false).unwrap()
2253        );
2254        assert_approx_equal!(
2255            -12234.571328028f64,
2256            payment(-0.001, 1, -123.4567, 12345.67, true).unwrap()
2257        );
2258        assert_approx_equal!(
2259            2.467899433f64,
2260            payment(-0.001, 1, -1.234567, -1.234567, false).unwrap()
2261        );
2262        assert_approx_equal!(
2263            -0.0012358028028028f64,
2264            payment(-0.001, 1, -1.234567, 1.234567, true).unwrap()
2265        );
2266        assert_approx_equal!(
2267            12345.67f64,
2268            payment(-0.001, 1, 0.0, -12345.67, false).unwrap()
2269        );
2270        assert_approx_equal!(
2271            1.2358028028028f64,
2272            payment(-0.001, 1, 0.0, -1.234567, true).unwrap()
2273        );
2274        assert_approx_equal!(
2275            -123.4567f64,
2276            payment(-0.001, 1, 0.0, 123.4567, false).unwrap()
2277        );
2278        assert_approx_equal!(
2279            12356.793461028f64,
2280            payment(-0.001, 1, 1.234567, -12345.67, true).unwrap()
2281        );
2282        assert_approx_equal!(
2283            -1.233332433f64,
2284            payment(-0.001, 1, 1.234567, 0.0, false).unwrap()
2285        );
2286        assert_approx_equal!(
2287            -124.81484728028f64,
2288            payment(-0.001, 1, 1.234567, 123.4567, true).unwrap()
2289        );
2290        assert_approx_equal!(
2291            0.1234567f64,
2292            payment(-0.001, 1, 123.4567, -123.4567, false).unwrap()
2293        );
2294        assert_approx_equal!(
2295            -123.4567f64,
2296            payment(-0.001, 1, 123.4567, 0.0, true).unwrap()
2297        );
2298        assert_approx_equal!(
2299            -12469.0032433f64,
2300            payment(-0.001, 1, 123.4567, 12345.67, false).unwrap()
2301        );
2302        assert_approx_equal!(
2303            -12222.0897197197f64,
2304            payment(-0.001, 1, 12345.67, -123.4567, true).unwrap()
2305        );
2306        assert_approx_equal!(
2307            -12334.558897f64,
2308            payment(-0.001, 1, 12345.67, 1.234567, false).unwrap()
2309        );
2310        assert_approx_equal!(
2311            -24703.698028028f64,
2312            payment(-0.001, 1, 12345.67, 12345.67, true).unwrap()
2313        );
2314        assert_approx_equal!(
2315            6164.19488377689f64,
2316            payment(-0.001, 2, -12345.67, -1.234567, false).unwrap()
2317        );
2318        assert_approx_equal!(
2319            6169.12882801261f64,
2320            payment(-0.001, 2, -12345.67, 1.234567, true).unwrap()
2321        );
2322        assert_approx_equal!(
2323            6237.55873439555f64,
2324            payment(-0.001, 2, -123.4567, -12345.67, false).unwrap()
2325        );
2326        assert_approx_equal!(
2327            62.3156808918473f64,
2328            payment(-0.001, 2, -123.4567, -1.234567, true).unwrap()
2329        );
2330        assert_approx_equal!(
2331            -0.1234567f64,
2332            payment(-0.001, 2, -123.4567, 123.4567, false).unwrap()
2333        );
2334        assert_approx_equal!(
2335            6182.72204125114f64,
2336            payment(-0.001, 2, -1.234567, -12345.67, true).unwrap()
2337        );
2338        assert_approx_equal!(
2339            0.616357729148074f64,
2340            payment(-0.001, 2, -1.234567, 0.0, false).unwrap()
2341        );
2342        assert_approx_equal!(
2343            -61.204075961621f64,
2344            payment(-0.001, 2, -1.234567, 123.4567, true).unwrap()
2345        );
2346        assert_approx_equal!(
2347            61.7592296148074f64,
2348            payment(-0.001, 2, 0.0, -123.4567, false).unwrap()
2349        );
2350        assert_approx_equal!(0f64, payment(-0.001, 2, 0.0, 0.0, true).unwrap());
2351        assert_approx_equal!(
2352            -6175.92296148074f64,
2353            payment(-0.001, 2, 0.0, 12345.67, false).unwrap()
2354        );
2355        assert_approx_equal!(
2356            61.204075961621f64,
2357            payment(-0.001, 2, 1.234567, -123.4567, true).unwrap()
2358        );
2359        assert_approx_equal!(
2360            -1.23395002529615f64,
2361            payment(-0.001, 2, 1.234567, 1.234567, false).unwrap()
2362        );
2363        assert_approx_equal!(
2364            -6182.72204125114f64,
2365            payment(-0.001, 2, 1.234567, 12345.67, true).unwrap()
2366        );
2367        assert_approx_equal!(
2368            -61.0181806186593f64,
2369            payment(-0.001, 2, 123.4567, -1.234567, false).unwrap()
2370        );
2371        assert_approx_equal!(
2372            -62.3156808918473f64,
2373            payment(-0.001, 2, 123.4567, 1.234567, true).unwrap()
2374        );
2375        assert_approx_equal!(
2376            12.34567f64,
2377            payment(-0.001, 2, 12345.67, -12345.67, false).unwrap()
2378        );
2379        assert_approx_equal!(
2380            -6169.12882801261f64,
2381            payment(-0.001, 2, 12345.67, -1.234567, true).unwrap()
2382        );
2383        assert_approx_equal!(
2384            -6225.33652109555f64,
2385            payment(-0.001, 2, 12345.67, 123.4567, false).unwrap()
2386        );
2387        assert_approx_equal!(
2388            4940.74949697025f64,
2389            payment(-0.001, 5, -12345.67, -12345.67, true).unwrap()
2390        );
2391        assert_approx_equal!(
2392            2461.73153873664f64,
2393            payment(-0.001, 5, -12345.67, 0.0, false).unwrap()
2394        );
2395        assert_approx_equal!(
2396            2439.43019684612f64,
2397            payment(-0.001, 5, -12345.67, 123.4567, true).unwrap()
2398        );
2399        assert_approx_equal!(
2400            49.3580874747328f64,
2401            payment(-0.001, 5, -123.4567, -123.4567, false).unwrap()
2402        );
2403        assert_approx_equal!(
2404            24.6419573447111f64,
2405            payment(-0.001, 5, -123.4567, 0.0, true).unwrap()
2406        );
2407        assert_approx_equal!(
2408            -2449.45989334927f64,
2409            payment(-0.001, 5, -123.4567, 12345.67, false).unwrap()
2410        );
2411        assert_approx_equal!(
2412            25.0119571984385f64,
2413            payment(-0.001, 5, -1.234567, -123.4567, true).unwrap()
2414        );
2415        assert_approx_equal!(
2416            -0.001234567f64,
2417            payment(-0.001, 5, -1.234567, 1.234567, false).unwrap()
2418        );
2419        assert_approx_equal!(
2420            -2476.30734292569f64,
2421            payment(-0.001, 5, -1.234567, 12345.67, true).unwrap()
2422        );
2423        assert_approx_equal!(
2424            0.247407720873664f64,
2425            payment(-0.001, 5, 0.0, -1.234567, false).unwrap()
2426        );
2427        assert_approx_equal!(
2428            -0.247655376249914f64,
2429            payment(-0.001, 5, 0.0, 1.234567, true).unwrap()
2430        );
2431        assert_approx_equal!(
2432            2473.83103558276f64,
2433            payment(-0.001, 5, 1.234567, -12345.67, false).unwrap()
2434        );
2435        assert_approx_equal!(
2436            0.0012358028028028f64,
2437            payment(-0.001, 5, 1.234567, -1.234567, true).unwrap()
2438        );
2439        assert_approx_equal!(
2440            -24.98694524124f64,
2441            payment(-0.001, 5, 1.234567, 123.4567, false).unwrap()
2442        );
2443        assert_approx_equal!(
2444            2451.91180515443f64,
2445            payment(-0.001, 5, 123.4567, -12345.67, true).unwrap()
2446        );
2447        assert_approx_equal!(
2448            -24.6173153873664f64,
2449            payment(-0.001, 5, 123.4567, 0.0, false).unwrap()
2450        );
2451        assert_approx_equal!(
2452            -49.4074949697025f64,
2453            payment(-0.001, 5, 123.4567, 123.4567, true).unwrap()
2454        );
2455        assert_approx_equal!(
2456            -2436.99076664927f64,
2457            payment(-0.001, 5, 12345.67, -123.4567, false).unwrap()
2458        );
2459        assert_approx_equal!(
2460            -2464.19573447111f64,
2461            payment(-0.001, 5, 12345.67, 0.0, true).unwrap()
2462        );
2463        assert_approx_equal!(
2464            -4935.80874747328f64,
2465            payment(-0.001, 5, 12345.67, 12345.67, false).unwrap()
2466        );
2467        assert_approx_equal!(
2468            1241.42982900313f64,
2469            payment(-0.001, 10, -12345.67, -123.4567, true).unwrap()
2470        );
2471        assert_approx_equal!(
2472            1227.66305848239f64,
2473            payment(-0.001, 10, -12345.67, 1.234567, false).unwrap()
2474        );
2475        assert_approx_equal!(
2476            -12.358028028028f64,
2477            payment(-0.001, 10, -12345.67, 12345.67, true).unwrap()
2478        );
2479        assert_approx_equal!(
2480            12.4018839917413f64,
2481            payment(-0.001, 10, -123.4567, -1.234567, false).unwrap()
2482        );
2483        assert_approx_equal!(
2484            12.1660234668569f64,
2485            payment(-0.001, 10, -123.4567, 1.234567, true).unwrap()
2486        );
2487        assert_approx_equal!(
2488            1240.25552046374f64,
2489            payment(-0.001, 10, -1.234567, -12345.67, false).unwrap()
2490        );
2491        assert_approx_equal!(
2492            0.247039020371685f64,
2493            payment(-0.001, 10, -1.234567, -1.234567, true).unwrap()
2494        );
2495        assert_approx_equal!(
2496            -12.27854871039f64,
2497            payment(-0.001, 10, -1.234567, 123.4567, false).unwrap()
2498        );
2499        assert_approx_equal!(
2500            1241.37411587244f64,
2501            payment(-0.001, 10, 0.0, -12345.67, true).unwrap()
2502        );
2503        assert_approx_equal!(0f64, payment(-0.001, 10, 0.0, 0.0, false).unwrap());
2504        assert_approx_equal!(
2505            -12.4137411587244f64,
2506            payment(-0.001, 10, 0.0, 123.4567, true).unwrap()
2507        );
2508        assert_approx_equal!(
2509            12.27854871039f64,
2510            payment(-0.001, 10, 1.234567, -123.4567, false).unwrap()
2511        );
2512        assert_approx_equal!(
2513            -0.122901608784441f64,
2514            payment(-0.001, 10, 1.234567, 0.0, true).unwrap()
2515        );
2516        assert_approx_equal!(
2517            -1240.25552046374f64,
2518            payment(-0.001, 10, 1.234567, 12345.67, false).unwrap()
2519        );
2520        assert_approx_equal!(
2521            0.12358028028028f64,
2522            payment(-0.001, 10, 123.4567, -123.4567, true).unwrap()
2523        );
2524        assert_approx_equal!(
2525            -12.4018839917413f64,
2526            payment(-0.001, 10, 123.4567, 1.234567, false).unwrap()
2527        );
2528        assert_approx_equal!(
2529            -1253.66427675088f64,
2530            payment(-0.001, 10, 123.4567, 12345.67, true).unwrap()
2531        );
2532        assert_approx_equal!(
2533            -1227.66305848239f64,
2534            payment(-0.001, 10, 12345.67, -1.234567, false).unwrap()
2535        );
2536        assert_approx_equal!(
2537            -1229.140225256f64,
2538            payment(-0.001, 10, 12345.67, 1.234567, true).unwrap()
2539        );
2540        assert_approx_equal!(
2541            493.682773192249f64,
2542            payment(-0.001, 50, -12345.67, -12345.67, false).unwrap()
2543        );
2544        assert_approx_equal!(
2545            240.93478780609f64,
2546            payment(-0.001, 50, -12345.67, -1.234567, true).unwrap()
2547        );
2548        assert_approx_equal!(
2549            238.138409380163f64,
2550            payment(-0.001, 50, -12345.67, 123.4567, false).unwrap()
2551        );
2552        assert_approx_equal!(
2553            255.676583695782f64,
2554            payment(-0.001, 50, -123.4567, -12345.67, true).unwrap()
2555        );
2556        assert_approx_equal!(
2557            2.40668551596125f64,
2558            payment(-0.001, 50, -123.4567, 0.0, false).unwrap()
2559        );
2560        assert_approx_equal!(
2561            -0.12358028028028f64,
2562            payment(-0.001, 50, -123.4567, 123.4567, true).unwrap()
2563        );
2564        assert_approx_equal!(
2565            2.55420907112086f64,
2566            payment(-0.001, 50, -1.234567, -123.4567, false).unwrap()
2567        );
2568        assert_approx_equal!(
2569            0.0240909461057182f64,
2570            payment(-0.001, 50, -1.234567, 0.0, true).unwrap()
2571        );
2572        assert_approx_equal!(
2573            -252.990154740965f64,
2574            payment(-0.001, 50, -1.234567, 12345.67, false).unwrap()
2575        );
2576        assert_approx_equal!(
2577            2.5326748908521f64,
2578            payment(-0.001, 50, 0.0, -123.4567, true).unwrap()
2579        );
2580        assert_approx_equal!(
2581            -0.0253014221596125f64,
2582            payment(-0.001, 50, 0.0, 1.234567, false).unwrap()
2583        );
2584        assert_approx_equal!(
2585            -253.26748908521f64,
2586            payment(-0.001, 50, 0.0, 12345.67, true).unwrap()
2587        );
2588        assert_approx_equal!(
2589            0.001234567f64,
2590            payment(-0.001, 50, 1.234567, -1.234567, false).unwrap()
2591        );
2592        assert_approx_equal!(
2593            -0.0494176950142391f64,
2594            payment(-0.001, 50, 1.234567, 1.234567, true).unwrap()
2595        );
2596        assert_approx_equal!(
2597            250.607536080163f64,
2598            payment(-0.001, 50, 123.4567, -12345.67, false).unwrap()
2599        );
2600        assert_approx_equal!(
2601            -2.3837678616633f64,
2602            payment(-0.001, 50, 123.4567, -1.234567, true).unwrap()
2603        );
2604        assert_approx_equal!(
2605            -4.93682773192249f64,
2606            payment(-0.001, 50, 123.4567, 123.4567, false).unwrap()
2607        );
2608        assert_approx_equal!(
2609            12.358028028028f64,
2610            payment(-0.001, 50, 12345.67, -12345.67, true).unwrap()
2611        );
2612        assert_approx_equal!(
2613            -240.668551596125f64,
2614            payment(-0.001, 50, 12345.67, 0.0, false).unwrap()
2615        );
2616        assert_approx_equal!(
2617            -243.442135948034f64,
2618            payment(-0.001, 50, 12345.67, 123.4567, true).unwrap()
2619        );
2620        assert_approx_equal!(
2621            44.0000905837691f64,
2622            payment(-0.001, 250, -12345.67, -123.4567, false).unwrap()
2623        );
2624        assert_approx_equal!(
2625            43.4856974635716f64,
2626            payment(-0.001, 250, -12345.67, 0.0, true).unwrap()
2627        );
2628        assert_approx_equal!(
2629            -12.34567f64,
2630            payment(-0.001, 250, -12345.67, 12345.67, false).unwrap()
2631        );
2632        assert_approx_equal!(
2633            0.993294229551712f64,
2634            payment(-0.001, 250, -123.4567, -123.4567, true).unwrap()
2635        );
2636        assert_approx_equal!(
2637            0.42884332948447f64,
2638            payment(-0.001, 250, -123.4567, 1.234567, false).unwrap()
2639        );
2640        assert_approx_equal!(
2641            -55.4088685169639f64,
2642            payment(-0.001, 250, -123.4567, 12345.67, true).unwrap()
2643        );
2644        assert_approx_equal!(
2645            0.00992300935322161f64,
2646            payment(-0.001, 250, -1.234567, -1.234567, false).unwrap()
2647        );
2648        assert_approx_equal!(
2649            -0.0012358028028028f64,
2650            payment(-0.001, 250, -1.234567, 1.234567, true).unwrap()
2651        );
2652        assert_approx_equal!(
2653            55.787881766108f64,
2654            payment(-0.001, 250, 0.0, -12345.67, false).unwrap()
2655        );
2656        assert_approx_equal!(
2657            0.00558437254915996f64,
2658            payment(-0.001, 250, 0.0, -1.234567, true).unwrap()
2659        );
2660        assert_approx_equal!(
2661            -0.55787881766108f64,
2662            payment(-0.001, 250, 0.0, 123.4567, false).unwrap()
2663        );
2664        assert_approx_equal!(
2665            55.8393769218533f64,
2666            payment(-0.001, 250, 1.234567, -12345.67, true).unwrap()
2667        );
2668        assert_approx_equal!(
2669            -0.0043442211766108f64,
2670            payment(-0.001, 250, 1.234567, 0.0, false).unwrap()
2671        );
2672        assert_approx_equal!(
2673            -0.562785824662353f64,
2674            payment(-0.001, 250, 1.234567, 123.4567, true).unwrap()
2675        );
2676        assert_approx_equal!(
2677            0.1234567f64,
2678            payment(-0.001, 250, 123.4567, -123.4567, false).unwrap()
2679        );
2680        assert_approx_equal!(
2681            -0.434856974635716f64,
2682            payment(-0.001, 250, 123.4567, 0.0, true).unwrap()
2683        );
2684        assert_approx_equal!(
2685            -56.2223038837691f64,
2686            payment(-0.001, 250, 123.4567, 12345.67, false).unwrap()
2687        );
2688        assert_approx_equal!(
2689            -42.9272602086556f64,
2690            payment(-0.001, 250, 12345.67, -123.4567, true).unwrap()
2691        );
2692        assert_approx_equal!(
2693            -43.4477905542846f64,
2694            payment(-0.001, 250, 12345.67, 1.234567, false).unwrap()
2695        );
2696        assert_approx_equal!(
2697            -99.3294229551712f64,
2698            payment(-0.001, 250, 12345.67, 12345.67, true).unwrap()
2699        );
2700        assert_approx_equal!(
2701            24691.34f64,
2702            payment(0.0, 1, -12345.67, -12345.67, false).unwrap()
2703        );
2704        assert_approx_equal!(
2705            12346.904567f64,
2706            payment(0.0, 1, -12345.67, -1.234567, true).unwrap()
2707        );
2708        assert_approx_equal!(
2709            12222.2133f64,
2710            payment(0.0, 1, -12345.67, 123.4567, false).unwrap()
2711        );
2712        assert_approx_equal!(
2713            12469.1267f64,
2714            payment(0.0, 1, -123.4567, -12345.67, true).unwrap()
2715        );
2716        assert_approx_equal!(123.4567f64, payment(0.0, 1, -123.4567, 0.0, false).unwrap());
2717        assert_approx_equal!(0f64, payment(0.0, 1, -123.4567, 123.4567, true).unwrap());
2718        assert_approx_equal!(
2719            124.691267f64,
2720            payment(0.0, 1, -1.234567, -123.4567, false).unwrap()
2721        );
2722        assert_approx_equal!(1.234567f64, payment(0.0, 1, -1.234567, 0.0, true).unwrap());
2723        assert_approx_equal!(
2724            -12344.435433f64,
2725            payment(0.0, 1, -1.234567, 12345.67, false).unwrap()
2726        );
2727        assert_approx_equal!(123.4567f64, payment(0.0, 1, 0.0, -123.4567, true).unwrap());
2728        assert_approx_equal!(-1.234567f64, payment(0.0, 1, 0.0, 1.234567, false).unwrap());
2729        assert_approx_equal!(-12345.67f64, payment(0.0, 1, 0.0, 12345.67, true).unwrap());
2730        assert_approx_equal!(0f64, payment(0.0, 1, 1.234567, -1.234567, false).unwrap());
2731        assert_approx_equal!(
2732            -2.469134f64,
2733            payment(0.0, 1, 1.234567, 1.234567, true).unwrap()
2734        );
2735        assert_approx_equal!(
2736            12222.2133f64,
2737            payment(0.0, 1, 123.4567, -12345.67, false).unwrap()
2738        );
2739        assert_approx_equal!(
2740            -122.222133f64,
2741            payment(0.0, 1, 123.4567, -1.234567, true).unwrap()
2742        );
2743        assert_approx_equal!(
2744            -246.9134f64,
2745            payment(0.0, 1, 123.4567, 123.4567, false).unwrap()
2746        );
2747        assert_approx_equal!(0f64, payment(0.0, 1, 12345.67, -12345.67, true).unwrap());
2748        assert_approx_equal!(-12345.67f64, payment(0.0, 1, 12345.67, 0.0, false).unwrap());
2749        assert_approx_equal!(
2750            -12469.1267f64,
2751            payment(0.0, 1, 12345.67, 123.4567, true).unwrap()
2752        );
2753        assert_approx_equal!(
2754            6234.56335f64,
2755            payment(0.0, 2, -12345.67, -123.4567, false).unwrap()
2756        );
2757        assert_approx_equal!(6172.835f64, payment(0.0, 2, -12345.67, 0.0, true).unwrap());
2758        assert_approx_equal!(0f64, payment(0.0, 2, -12345.67, 12345.67, false).unwrap());
2759        assert_approx_equal!(
2760            123.4567f64,
2761            payment(0.0, 2, -123.4567, -123.4567, true).unwrap()
2762        );
2763        assert_approx_equal!(
2764            61.1110665f64,
2765            payment(0.0, 2, -123.4567, 1.234567, false).unwrap()
2766        );
2767        assert_approx_equal!(
2768            -6111.10665f64,
2769            payment(0.0, 2, -123.4567, 12345.67, true).unwrap()
2770        );
2771        assert_approx_equal!(
2772            1.234567f64,
2773            payment(0.0, 2, -1.234567, -1.234567, false).unwrap()
2774        );
2775        assert_approx_equal!(0f64, payment(0.0, 2, -1.234567, 1.234567, true).unwrap());
2776        assert_approx_equal!(6172.835f64, payment(0.0, 2, 0.0, -12345.67, false).unwrap());
2777        assert_approx_equal!(0.6172835f64, payment(0.0, 2, 0.0, -1.234567, true).unwrap());
2778        assert_approx_equal!(-61.72835f64, payment(0.0, 2, 0.0, 123.4567, false).unwrap());
2779        assert_approx_equal!(
2780            6172.2177165f64,
2781            payment(0.0, 2, 1.234567, -12345.67, true).unwrap()
2782        );
2783        assert_approx_equal!(
2784            -0.6172835f64,
2785            payment(0.0, 2, 1.234567, 0.0, false).unwrap()
2786        );
2787        assert_approx_equal!(
2788            -62.3456335f64,
2789            payment(0.0, 2, 1.234567, 123.4567, true).unwrap()
2790        );
2791        assert_approx_equal!(0f64, payment(0.0, 2, 123.4567, -123.4567, false).unwrap());
2792        assert_approx_equal!(-61.72835f64, payment(0.0, 2, 123.4567, 0.0, true).unwrap());
2793        assert_approx_equal!(
2794            -6234.56335f64,
2795            payment(0.0, 2, 123.4567, 12345.67, false).unwrap()
2796        );
2797        assert_approx_equal!(
2798            -6111.10665f64,
2799            payment(0.0, 2, 12345.67, -123.4567, true).unwrap()
2800        );
2801        assert_approx_equal!(
2802            -6173.4522835f64,
2803            payment(0.0, 2, 12345.67, 1.234567, false).unwrap()
2804        );
2805        assert_approx_equal!(
2806            -12345.67f64,
2807            payment(0.0, 2, 12345.67, 12345.67, true).unwrap()
2808        );
2809        assert_approx_equal!(
2810            2469.3809134f64,
2811            payment(0.0, 5, -12345.67, -1.234567, false).unwrap()
2812        );
2813        assert_approx_equal!(
2814            2468.8870866f64,
2815            payment(0.0, 5, -12345.67, 1.234567, true).unwrap()
2816        );
2817        assert_approx_equal!(
2818            2493.82534f64,
2819            payment(0.0, 5, -123.4567, -12345.67, false).unwrap()
2820        );
2821        assert_approx_equal!(
2822            24.9382534f64,
2823            payment(0.0, 5, -123.4567, -1.234567, true).unwrap()
2824        );
2825        assert_approx_equal!(0f64, payment(0.0, 5, -123.4567, 123.4567, false).unwrap());
2826        assert_approx_equal!(
2827            2469.3809134f64,
2828            payment(0.0, 5, -1.234567, -12345.67, true).unwrap()
2829        );
2830        assert_approx_equal!(
2831            0.2469134f64,
2832            payment(0.0, 5, -1.234567, 0.0, false).unwrap()
2833        );
2834        assert_approx_equal!(
2835            -24.4444266f64,
2836            payment(0.0, 5, -1.234567, 123.4567, true).unwrap()
2837        );
2838        assert_approx_equal!(24.69134f64, payment(0.0, 5, 0.0, -123.4567, false).unwrap());
2839        assert_approx_equal!(0f64, payment(0.0, 5, 0.0, 0.0, true).unwrap());
2840        assert_approx_equal!(-2469.134f64, payment(0.0, 5, 0.0, 12345.67, false).unwrap());
2841        assert_approx_equal!(
2842            24.4444266f64,
2843            payment(0.0, 5, 1.234567, -123.4567, true).unwrap()
2844        );
2845        assert_approx_equal!(
2846            -0.4938268f64,
2847            payment(0.0, 5, 1.234567, 1.234567, false).unwrap()
2848        );
2849        assert_approx_equal!(
2850            -2469.3809134f64,
2851            payment(0.0, 5, 1.234567, 12345.67, true).unwrap()
2852        );
2853        assert_approx_equal!(
2854            -24.4444266f64,
2855            payment(0.0, 5, 123.4567, -1.234567, false).unwrap()
2856        );
2857        assert_approx_equal!(
2858            -24.9382534f64,
2859            payment(0.0, 5, 123.4567, 1.234567, true).unwrap()
2860        );
2861        assert_approx_equal!(0f64, payment(0.0, 5, 12345.67, -12345.67, false).unwrap());
2862        assert_approx_equal!(
2863            -2468.8870866f64,
2864            payment(0.0, 5, 12345.67, -1.234567, true).unwrap()
2865        );
2866        assert_approx_equal!(
2867            -2493.82534f64,
2868            payment(0.0, 5, 12345.67, 123.4567, false).unwrap()
2869        );
2870        assert_approx_equal!(
2871            2469.134f64,
2872            payment(0.0, 10, -12345.67, -12345.67, true).unwrap()
2873        );
2874        assert_approx_equal!(
2875            1234.567f64,
2876            payment(0.0, 10, -12345.67, 0.0, false).unwrap()
2877        );
2878        assert_approx_equal!(
2879            1222.22133f64,
2880            payment(0.0, 10, -12345.67, 123.4567, true).unwrap()
2881        );
2882        assert_approx_equal!(
2883            24.69134f64,
2884            payment(0.0, 10, -123.4567, -123.4567, false).unwrap()
2885        );
2886        assert_approx_equal!(12.34567f64, payment(0.0, 10, -123.4567, 0.0, true).unwrap());
2887        assert_approx_equal!(
2888            -1222.22133f64,
2889            payment(0.0, 10, -123.4567, 12345.67, false).unwrap()
2890        );
2891        assert_approx_equal!(
2892            12.4691267f64,
2893            payment(0.0, 10, -1.234567, -123.4567, true).unwrap()
2894        );
2895        assert_approx_equal!(0f64, payment(0.0, 10, -1.234567, 1.234567, false).unwrap());
2896        assert_approx_equal!(
2897            -1234.4435433f64,
2898            payment(0.0, 10, -1.234567, 12345.67, true).unwrap()
2899        );
2900        assert_approx_equal!(
2901            0.1234567f64,
2902            payment(0.0, 10, 0.0, -1.234567, false).unwrap()
2903        );
2904        assert_approx_equal!(
2905            -0.1234567f64,
2906            payment(0.0, 10, 0.0, 1.234567, true).unwrap()
2907        );
2908        assert_approx_equal!(
2909            1234.4435433f64,
2910            payment(0.0, 10, 1.234567, -12345.67, false).unwrap()
2911        );
2912        assert_approx_equal!(0f64, payment(0.0, 10, 1.234567, -1.234567, true).unwrap());
2913        assert_approx_equal!(
2914            -12.4691267f64,
2915            payment(0.0, 10, 1.234567, 123.4567, false).unwrap()
2916        );
2917        assert_approx_equal!(
2918            1222.22133f64,
2919            payment(0.0, 10, 123.4567, -12345.67, true).unwrap()
2920        );
2921        assert_approx_equal!(
2922            -12.34567f64,
2923            payment(0.0, 10, 123.4567, 0.0, false).unwrap()
2924        );
2925        assert_approx_equal!(
2926            -24.69134f64,
2927            payment(0.0, 10, 123.4567, 123.4567, true).unwrap()
2928        );
2929        assert_approx_equal!(
2930            -1222.22133f64,
2931            payment(0.0, 10, 12345.67, -123.4567, false).unwrap()
2932        );
2933        assert_approx_equal!(-1234.567f64, payment(0.0, 10, 12345.67, 0.0, true).unwrap());
2934        assert_approx_equal!(
2935            -2469.134f64,
2936            payment(0.0, 10, 12345.67, 12345.67, false).unwrap()
2937        );
2938        assert_approx_equal!(
2939            249.382534f64,
2940            payment(0.0, 50, -12345.67, -123.4567, true).unwrap()
2941        );
2942        assert_approx_equal!(
2943            246.88870866f64,
2944            payment(0.0, 50, -12345.67, 1.234567, false).unwrap()
2945        );
2946        assert_approx_equal!(0f64, payment(0.0, 50, -12345.67, 12345.67, true).unwrap());
2947        assert_approx_equal!(
2948            2.49382534f64,
2949            payment(0.0, 50, -123.4567, -1.234567, false).unwrap()
2950        );
2951        assert_approx_equal!(
2952            2.44444266f64,
2953            payment(0.0, 50, -123.4567, 1.234567, true).unwrap()
2954        );
2955        assert_approx_equal!(
2956            246.93809134f64,
2957            payment(0.0, 50, -1.234567, -12345.67, false).unwrap()
2958        );
2959        assert_approx_equal!(
2960            0.04938268f64,
2961            payment(0.0, 50, -1.234567, -1.234567, true).unwrap()
2962        );
2963        assert_approx_equal!(
2964            -2.44444266f64,
2965            payment(0.0, 50, -1.234567, 123.4567, false).unwrap()
2966        );
2967        assert_approx_equal!(246.9134f64, payment(0.0, 50, 0.0, -12345.67, true).unwrap());
2968        assert_approx_equal!(0f64, payment(0.0, 50, 0.0, 0.0, false).unwrap());
2969        assert_approx_equal!(-2.469134f64, payment(0.0, 50, 0.0, 123.4567, true).unwrap());
2970        assert_approx_equal!(
2971            2.44444266f64,
2972            payment(0.0, 50, 1.234567, -123.4567, false).unwrap()
2973        );
2974        assert_approx_equal!(
2975            -0.02469134f64,
2976            payment(0.0, 50, 1.234567, 0.0, true).unwrap()
2977        );
2978        assert_approx_equal!(
2979            -246.93809134f64,
2980            payment(0.0, 50, 1.234567, 12345.67, false).unwrap()
2981        );
2982        assert_approx_equal!(0f64, payment(0.0, 50, 123.4567, -123.4567, true).unwrap());
2983        assert_approx_equal!(
2984            -2.49382534f64,
2985            payment(0.0, 50, 123.4567, 1.234567, false).unwrap()
2986        );
2987        assert_approx_equal!(
2988            -249.382534f64,
2989            payment(0.0, 50, 123.4567, 12345.67, true).unwrap()
2990        );
2991        assert_approx_equal!(
2992            -246.88870866f64,
2993            payment(0.0, 50, 12345.67, -1.234567, false).unwrap()
2994        );
2995        assert_approx_equal!(
2996            -246.93809134f64,
2997            payment(0.0, 50, 12345.67, 1.234567, true).unwrap()
2998        );
2999        assert_approx_equal!(
3000            98.76536f64,
3001            payment(0.0, 250, -12345.67, -12345.67, false).unwrap()
3002        );
3003        assert_approx_equal!(
3004            49.387618268f64,
3005            payment(0.0, 250, -12345.67, -1.234567, true).unwrap()
3006        );
3007        assert_approx_equal!(
3008            48.8888532f64,
3009            payment(0.0, 250, -12345.67, 123.4567, false).unwrap()
3010        );
3011        assert_approx_equal!(
3012            49.8765068f64,
3013            payment(0.0, 250, -123.4567, -12345.67, true).unwrap()
3014        );
3015        assert_approx_equal!(
3016            0.4938268f64,
3017            payment(0.0, 250, -123.4567, 0.0, false).unwrap()
3018        );
3019        assert_approx_equal!(0f64, payment(0.0, 250, -123.4567, 123.4567, true).unwrap());
3020        assert_approx_equal!(
3021            0.498765068f64,
3022            payment(0.0, 250, -1.234567, -123.4567, false).unwrap()
3023        );
3024        assert_approx_equal!(
3025            0.004938268f64,
3026            payment(0.0, 250, -1.234567, 0.0, true).unwrap()
3027        );
3028        assert_approx_equal!(
3029            -49.377741732f64,
3030            payment(0.0, 250, -1.234567, 12345.67, false).unwrap()
3031        );
3032        assert_approx_equal!(
3033            0.4938268f64,
3034            payment(0.0, 250, 0.0, -123.4567, true).unwrap()
3035        );
3036        assert_approx_equal!(
3037            -0.004938268f64,
3038            payment(0.0, 250, 0.0, 1.234567, false).unwrap()
3039        );
3040        assert_approx_equal!(
3041            -49.38268f64,
3042            payment(0.0, 250, 0.0, 12345.67, true).unwrap()
3043        );
3044        assert_approx_equal!(0f64, payment(0.0, 250, 1.234567, -1.234567, false).unwrap());
3045        assert_approx_equal!(
3046            -0.009876536f64,
3047            payment(0.0, 250, 1.234567, 1.234567, true).unwrap()
3048        );
3049        assert_approx_equal!(
3050            48.8888532f64,
3051            payment(0.0, 250, 123.4567, -12345.67, false).unwrap()
3052        );
3053        assert_approx_equal!(
3054            -0.488888532f64,
3055            payment(0.0, 250, 123.4567, -1.234567, true).unwrap()
3056        );
3057        assert_approx_equal!(
3058            -0.9876536f64,
3059            payment(0.0, 250, 123.4567, 123.4567, false).unwrap()
3060        );
3061        assert_approx_equal!(0f64, payment(0.0, 250, 12345.67, -12345.67, true).unwrap());
3062        assert_approx_equal!(
3063            -49.38268f64,
3064            payment(0.0, 250, 12345.67, 0.0, false).unwrap()
3065        );
3066        assert_approx_equal!(
3067            -49.8765068f64,
3068            payment(0.0, 250, 12345.67, 123.4567, true).unwrap()
3069        );
3070        assert_approx_equal!(
3071            12468.8434011773f64,
3072            payment(0.0023, 1, -12345.67, -123.4567, true).unwrap()
3073        );
3074        assert_approx_equal!(
3075            12372.830474f64,
3076            payment(0.0023, 1, -12345.67, 1.234567, false).unwrap()
3077        );
3078        assert_approx_equal!(
3079            28.3298822707772f64,
3080            payment(0.0023, 1, -12345.67, 12345.67, true).unwrap()
3081        );
3082        assert_approx_equal!(
3083            124.97521741f64,
3084            payment(0.0023, 1, -123.4567, -1.234567, false).unwrap()
3085        );
3086        assert_approx_equal!(
3087            122.224965988227f64,
3088            payment(0.0023, 1, -123.4567, 1.234567, true).unwrap()
3089        );
3090        assert_approx_equal!(
3091            12346.9074065041f64,
3092            payment(0.0023, 1, -1.234567, -12345.67, false).unwrap()
3093        );
3094        assert_approx_equal!(
3095            2.46630101177292f64,
3096            payment(0.0023, 1, -1.234567, -1.234567, true).unwrap()
3097        );
3098        assert_approx_equal!(
3099            -122.2192934959f64,
3100            payment(0.0023, 1, -1.234567, 123.4567, false).unwrap()
3101        );
3102        assert_approx_equal!(
3103            12317.3401177292f64,
3104            payment(0.0023, 1, 0.0, -12345.67, true).unwrap()
3105        );
3106        assert_approx_equal!(0f64, payment(0.0023, 1, 0.0, 0.0, false).unwrap());
3107        assert_approx_equal!(
3108            -123.173401177292f64,
3109            payment(0.0023, 1, 0.0, 123.4567, true).unwrap()
3110        );
3111        assert_approx_equal!(
3112            122.2192934959f64,
3113            payment(0.0023, 1, 1.234567, -123.4567, false).unwrap()
3114        );
3115        assert_approx_equal!(
3116            -1.234567f64,
3117            payment(0.0023, 1, 1.234567, 0.0, true).unwrap()
3118        );
3119        assert_approx_equal!(
3120            -12346.9074065041f64,
3121            payment(0.0023, 1, 1.234567, 12345.67, false).unwrap()
3122        );
3123        assert_approx_equal!(
3124            -0.283298822707772f64,
3125            payment(0.0023, 1, 123.4567, -123.4567, true).unwrap()
3126        );
3127        assert_approx_equal!(
3128            -124.97521741f64,
3129            payment(0.0023, 1, 123.4567, 1.234567, false).unwrap()
3130        );
3131        assert_approx_equal!(
3132            -12440.7968177292f64,
3133            payment(0.0023, 1, 123.4567, 12345.67, true).unwrap()
3134        );
3135        assert_approx_equal!(
3136            -12372.830474f64,
3137            payment(0.0023, 1, 12345.67, -1.234567, false).unwrap()
3138        );
3139        assert_approx_equal!(
3140            -12346.9017340118f64,
3141            payment(0.0023, 1, 12345.67, 1.234567, true).unwrap()
3142        );
3143        assert_approx_equal!(
3144            12359.8838288939f64,
3145            payment(0.0023, 2, -12345.67, -12345.67, false).unwrap()
3146        );
3147        assert_approx_equal!(
3148            6180.54076562542f64,
3149            payment(0.0023, 2, -12345.67, -1.234567, true).unwrap()
3150        );
3151        assert_approx_equal!(
3152            6132.48199100749f64,
3153            payment(0.0023, 2, -12345.67, 123.4567, false).unwrap()
3154        );
3155        assert_approx_equal!(
3156            6213.39497984279f64,
3157            payment(0.0023, 2, -123.4567, -12345.67, true).unwrap()
3158        );
3159        assert_approx_equal!(
3160            61.9413943494696f64,
3161            payment(0.0023, 2, -123.4567, 0.0, false).unwrap()
3162        );
3163        assert_approx_equal!(
3164            0.283298822707772f64,
3165            payment(0.0023, 2, -123.4567, 123.4567, true).unwrap()
3166        );
3167        assert_approx_equal!(
3168            62.2768578829643f64,
3169            payment(0.0023, 2, -1.234567, -123.4567, false).unwrap()
3170        );
3171        assert_approx_equal!(
3172            0.617992560605304f64,
3173            payment(0.0023, 2, -1.234567, 0.0, true).unwrap()
3174        );
3175        assert_approx_equal!(
3176            -6165.12498000346f64,
3177            payment(0.0023, 2, -1.234567, 12345.67, false).unwrap()
3178        );
3179        assert_approx_equal!(
3180            61.5159572378226f64,
3181            payment(0.0023, 2, 0.0, -123.4567, true).unwrap()
3182        );
3183        assert_approx_equal!(
3184            -0.616574439394696f64,
3185            payment(0.0023, 2, 0.0, 1.234567, false).unwrap()
3186        );
3187        assert_approx_equal!(
3188            -6151.59572378226f64,
3189            payment(0.0023, 2, 0.0, 12345.67, true).unwrap()
3190        );
3191        assert_approx_equal!(
3192            -0.0028395041f64,
3193            payment(0.0023, 2, 1.234567, -1.234567, false).unwrap()
3194        );
3195        assert_approx_equal!(
3196            -1.23315213298353f64,
3197            payment(0.0023, 2, 1.234567, 1.234567, true).unwrap()
3198        );
3199        assert_approx_equal!(
3200            6103.80299959749f64,
3201            payment(0.0023, 2, 123.4567, -12345.67, false).unwrap()
3202        );
3203        assert_approx_equal!(
3204            -61.1840964881522f64,
3205            payment(0.0023, 2, 123.4567, -1.234567, true).unwrap()
3206        );
3207        assert_approx_equal!(
3208            -123.598838288939f64,
3209            payment(0.0023, 2, 123.4567, 123.4567, false).unwrap()
3210        );
3211        assert_approx_equal!(
3212            -28.3298822707772f64,
3213            payment(0.0023, 2, 12345.67, -12345.67, true).unwrap()
3214        );
3215        assert_approx_equal!(
3216            -6194.13943494696f64,
3217            payment(0.0023, 2, 12345.67, 0.0, false).unwrap()
3218        );
3219        assert_approx_equal!(
3220            -6241.44156329086f64,
3221            payment(0.0023, 2, 12345.67, 123.4567, true).unwrap()
3222        );
3223        assert_approx_equal!(
3224            2510.7751387519f64,
3225            payment(0.0023, 5, -12345.67, -123.4567, false).unwrap()
3226        );
3227        assert_approx_equal!(
3228            2480.49198641332f64,
3229            payment(0.0023, 5, -12345.67, 0.0, true).unwrap()
3230        );
3231        assert_approx_equal!(
3232            28.395041f64,
3233            payment(0.0023, 5, -12345.67, 12345.67, false).unwrap()
3234        );
3235        assert_approx_equal!(
3236            49.3265409055587f64,
3237            payment(0.0023, 5, -123.4567, -123.4567, true).unwrap()
3238        );
3239        assert_approx_equal!(
3240            24.6161909721225f64,
3241            payment(0.0023, 5, -123.4567, 1.234567, false).unwrap()
3242        );
3243        assert_approx_equal!(
3244            -2427.35718427841f64,
3245            payment(0.0023, 5, -123.4567, 12345.67, true).unwrap()
3246        );
3247        assert_approx_equal!(
3248            0.494399919496415f64,
3249            payment(0.0023, 5, -1.234567, -1.234567, false).unwrap()
3250        );
3251        assert_approx_equal!(
3252            0.00283298822707772f64,
3253            payment(0.0023, 5, -1.234567, 1.234567, true).unwrap()
3254        );
3255        assert_approx_equal!(
3256            2457.80207698207f64,
3257            payment(0.0023, 5, 0.0, -12345.67, false).unwrap()
3258        );
3259        assert_approx_equal!(
3260            0.245216210414255f64,
3261            payment(0.0023, 5, 0.0, -1.234567, true).unwrap()
3262        );
3263        assert_approx_equal!(
3264            -24.5780207698207f64,
3265            payment(0.0023, 5, 0.0, 123.4567, false).unwrap()
3266        );
3267        assert_approx_equal!(
3268            2451.91405494391f64,
3269            payment(0.0023, 5, 1.234567, -12345.67, true).unwrap()
3270        );
3271        assert_approx_equal!(
3272            -0.248619711798207f64,
3273            payment(0.0023, 5, 1.234567, 0.0, false).unwrap()
3274        );
3275        assert_approx_equal!(
3276            -24.7696702400668f64,
3277            payment(0.0023, 5, 1.234567, 123.4567, true).unwrap()
3278        );
3279        assert_approx_equal!(
3280            -0.28395041f64,
3281            payment(0.0023, 5, 123.4567, -123.4567, false).unwrap()
3282        );
3283        assert_approx_equal!(
3284            -24.8049198641332f64,
3285            payment(0.0023, 5, 123.4567, 0.0, true).unwrap()
3286        );
3287        assert_approx_equal!(
3288            -2482.6640481619f64,
3289            payment(0.0023, 5, 123.4567, 12345.67, false).unwrap()
3290        );
3291        assert_approx_equal!(
3292            -2455.9703653719f64,
3293            payment(0.0023, 5, 12345.67, -123.4567, true).unwrap()
3294        );
3295        assert_approx_equal!(
3296            -2486.44289818977f64,
3297            payment(0.0023, 5, 12345.67, 1.234567, false).unwrap()
3298        );
3299        assert_approx_equal!(
3300            -4932.65409055587f64,
3301            payment(0.0023, 5, 12345.67, 12345.67, true).unwrap()
3302        );
3303        assert_approx_equal!(
3304            1250.36027410036f64,
3305            payment(0.0023, 10, -12345.67, -1.234567, false).unwrap()
3306        );
3307        assert_approx_equal!(
3308            1247.24723684586f64,
3309            payment(0.0023, 10, -12345.67, 1.234567, true).unwrap()
3310        );
3311        assert_approx_equal!(
3312            1234.34542969344f64,
3313            payment(0.0023, 10, -123.4567, -12345.67, false).unwrap()
3314        );
3315        assert_approx_equal!(
3316            12.5955953335671f64,
3317            payment(0.0023, 10, -123.4567, -1.234567, true).unwrap()
3318        );
3319        assert_approx_equal!(
3320            0.28395041f64,
3321            payment(0.0023, 10, -123.4567, 123.4567, false).unwrap()
3322        );
3323        assert_approx_equal!(
3324            1219.16399541501f64,
3325            payment(0.0023, 10, -1.234567, -12345.67, true).unwrap()
3326        );
3327        assert_approx_equal!(
3328            0.125023808979548f64,
3329            payment(0.0023, 10, -1.234567, 0.0, false).unwrap()
3330        );
3331        assert_approx_equal!(
3332            -12.0656556709321f64,
3333            payment(0.0023, 10, -1.234567, 123.4567, true).unwrap()
3334        );
3335        assert_approx_equal!(
3336            12.2184304879548f64,
3337            payment(0.0023, 10, 0.0, -123.4567, false).unwrap()
3338        );
3339        assert_approx_equal!(0f64, payment(0.0023, 10, 0.0, 0.0, true).unwrap());
3340        assert_approx_equal!(
3341            -1221.84304879548f64,
3342            payment(0.0023, 10, 0.0, 12345.67, false).unwrap()
3343        );
3344        assert_approx_equal!(
3345            12.0656556709321f64,
3346            payment(0.0023, 10, 1.234567, -123.4567, true).unwrap()
3347        );
3348        assert_approx_equal!(
3349            -0.247208113859096f64,
3350            payment(0.0023, 10, 1.234567, 1.234567, false).unwrap()
3351        );
3352        assert_approx_equal!(
3353            -1219.16399541501f64,
3354            payment(0.0023, 10, 1.234567, 12345.67, true).unwrap()
3355        );
3356        assert_approx_equal!(
3357            -12.3801965930753f64,
3358            payment(0.0023, 10, 123.4567, -1.234567, false).unwrap()
3359        );
3360        assert_approx_equal!(
3361            -12.5955953335671f64,
3362            payment(0.0023, 10, 123.4567, 1.234567, true).unwrap()
3363        );
3364        assert_approx_equal!(
3365            -28.395041f64,
3366            payment(0.0023, 10, 12345.67, -12345.67, false).unwrap()
3367        );
3368        assert_approx_equal!(
3369            -1247.24723684586f64,
3370            payment(0.0023, 10, 12345.67, -1.234567, true).unwrap()
3371        );
3372        assert_approx_equal!(
3373            -1262.45652028344f64,
3374            payment(0.0023, 10, 12345.67, 123.4567, false).unwrap()
3375        );
3376        assert_approx_equal!(
3377            493.80223210177f64,
3378            payment(0.0023, 50, -12345.67, -12345.67, true).unwrap()
3379        );
3380        assert_approx_equal!(
3381            261.666509117802f64,
3382            payment(0.0023, 50, -12345.67, 0.0, false).unwrap()
3383        );
3384        assert_approx_equal!(
3385            258.738695437118f64,
3386            payment(0.0023, 50, -12345.67, 123.4567, true).unwrap()
3387        );
3388        assert_approx_equal!(
3389            4.94937977235604f64,
3390            payment(0.0023, 50, -123.4567, -123.4567, false).unwrap()
3391        );
3392        assert_approx_equal!(
3393            2.61066057186273f64,
3394            payment(0.0023, 50, -123.4567, 0.0, true).unwrap()
3395        );
3396        assert_approx_equal!(
3397            -230.654803026624f64,
3398            payment(0.0023, 50, -123.4567, 12345.67, false).unwrap()
3399        );
3400        assert_approx_equal!(
3401            2.35346835487359f64,
3402            payment(0.0023, 50, -1.234567, -123.4567, true).unwrap()
3403        );
3404        assert_approx_equal!(
3405            0.0028395041f64,
3406            payment(0.0023, 50, -1.234567, 1.234567, false).unwrap()
3407        );
3408        assert_approx_equal!(
3409            -232.710068309778f64,
3410            payment(0.0023, 50, -1.234567, 12345.67, true).unwrap()
3411        );
3412        assert_approx_equal!(
3413            0.0233271468117802f64,
3414            payment(0.0023, 50, 0.0, -1.234567, false).unwrap()
3415        );
3416        assert_approx_equal!(
3417            -0.0232736174915496f64,
3418            payment(0.0023, 50, 0.0, 1.234567, true).unwrap()
3419        );
3420        assert_approx_equal!(
3421            233.24530146689f64,
3422            payment(0.0023, 50, 1.234567, -12345.67, false).unwrap()
3423        );
3424        assert_approx_equal!(
3425            -0.00283298822707772f64,
3426            payment(0.0023, 50, 1.234567, -1.234567, true).unwrap()
3427        );
3428        assert_approx_equal!(
3429            -2.3588813320898f64,
3430            payment(0.0023, 50, 1.234567, 123.4567, false).unwrap()
3431        );
3432        assert_approx_equal!(
3433            230.125514343633f64,
3434            payment(0.0023, 50, 123.4567, -12345.67, true).unwrap()
3435        );
3436        assert_approx_equal!(
3437            -2.61666509117802f64,
3438            payment(0.0023, 50, 123.4567, 0.0, false).unwrap()
3439        );
3440        assert_approx_equal!(
3441            -4.9380223210177f64,
3442            payment(0.0023, 50, 123.4567, 123.4567, true).unwrap()
3443        );
3444        assert_approx_equal!(
3445            -259.333794436624f64,
3446            payment(0.0023, 50, 12345.67, -123.4567, false).unwrap()
3447        );
3448        assert_approx_equal!(
3449            -261.066057186273f64,
3450            payment(0.0023, 50, 12345.67, 0.0, true).unwrap()
3451        );
3452        assert_approx_equal!(
3453            -494.937977235604f64,
3454            payment(0.0023, 50, 12345.67, 12345.67, false).unwrap()
3455        );
3456        assert_approx_equal!(
3457            65.204553816131f64,
3458            payment(0.0023, 250, -12345.67, -123.4567, true).unwrap()
3459        );
3460        assert_approx_equal!(
3461            64.984929457009f64,
3462            payment(0.0023, 250, -12345.67, 1.234567, false).unwrap()
3463        );
3464        assert_approx_equal!(
3465            28.3298822707772f64,
3466            payment(0.0023, 250, -12345.67, 12345.67, true).unwrap()
3467        );
3468        assert_approx_equal!(
3469            0.653545242899081f64,
3470            payment(0.0023, 250, -123.4567, -1.234567, false).unwrap()
3471        );
3472        assert_approx_equal!(
3473            0.644743623003814f64,
3474            payment(0.0023, 250, -123.4567, 1.234567, true).unwrap()
3475        );
3476        assert_approx_equal!(
3477            36.6000466706714f64,
3478            payment(0.0023, 250, -1.234567, -12345.67, false).unwrap()
3479        );
3480        assert_approx_equal!(
3481            0.0101349033845735f64,
3482            payment(0.0023, 250, -1.234567, -1.234567, true).unwrap()
3483        );
3484        assert_approx_equal!(
3485            -0.359436619236723f64,
3486            payment(0.0023, 250, -1.234567, 123.4567, false).unwrap()
3487        );
3488        assert_approx_equal!(
3489            36.509575787479f64,
3490            payment(0.0023, 250, 0.0, -12345.67, true).unwrap()
3491        );
3492        assert_approx_equal!(0f64, payment(0.0023, 250, 0.0, 0.0, false).unwrap());
3493        assert_approx_equal!(
3494            -0.36509575787479f64,
3495            payment(0.0023, 250, 0.0, 123.4567, true).unwrap()
3496        );
3497        assert_approx_equal!(
3498            0.359436619236723f64,
3499            payment(0.0023, 250, 1.234567, -123.4567, false).unwrap()
3500        );
3501        assert_approx_equal!(
3502            -0.00648394580582562f64,
3503            payment(0.0023, 250, 1.234567, 0.0, true).unwrap()
3504        );
3505        assert_approx_equal!(
3506            -36.6000466706714f64,
3507            payment(0.0023, 250, 1.234567, 12345.67, false).unwrap()
3508        );
3509        assert_approx_equal!(
3510            -0.283298822707772f64,
3511            payment(0.0023, 250, 123.4567, -123.4567, true).unwrap()
3512        );
3513        assert_approx_equal!(
3514            -0.653545242899081f64,
3515            payment(0.0023, 250, 123.4567, 1.234567, false).unwrap()
3516        );
3517        assert_approx_equal!(
3518            -37.1579703680616f64,
3519            payment(0.0023, 250, 123.4567, 12345.67, true).unwrap()
3520        );
3521        assert_approx_equal!(
3522            -64.984929457009f64,
3523            payment(0.0023, 250, 12345.67, -1.234567, false).unwrap()
3524        );
3525        assert_approx_equal!(
3526            -64.843109015835f64,
3527            payment(0.0023, 250, 12345.67, 1.234567, true).unwrap()
3528        );
3529        assert_approx_equal!(
3530            24413.7736168133f64,
3531            payment(0.023, 1, -12345.67, -12345.67, true).unwrap()
3532        );
3533        assert_approx_equal!(
3534            12629.62041f64,
3535            payment(0.023, 1, -12345.67, 0.0, false).unwrap()
3536        );
3537        assert_approx_equal!(
3538            12224.9889638319f64,
3539            payment(0.023, 1, -12345.67, 123.4567, true).unwrap()
3540        );
3541        assert_approx_equal!(
3542            249.7529041f64,
3543            payment(0.023, 1, -123.4567, -123.4567, false).unwrap()
3544        );
3545        assert_approx_equal!(
3546            123.4567f64,
3547            payment(0.023, 1, -123.4567, 0.0, true).unwrap()
3548        );
3549        assert_approx_equal!(
3550            -12219.3737959f64,
3551            payment(0.023, 1, -123.4567, 12345.67, false).unwrap()
3552        );
3553        assert_approx_equal!(
3554            121.915603168133f64,
3555            payment(0.023, 1, -1.234567, -123.4567, true).unwrap()
3556        );
3557        assert_approx_equal!(
3558            0.028395041f64,
3559            payment(0.023, 1, -1.234567, 1.234567, false).unwrap()
3560        );
3561        assert_approx_equal!(
3562            -12066.8690498133f64,
3563            payment(0.023, 1, -1.234567, 12345.67, true).unwrap()
3564        );
3565        assert_approx_equal!(
3566            1.234567f64,
3567            payment(0.023, 1, 0.0, -1.234567, false).unwrap()
3568        );
3569        assert_approx_equal!(
3570            -1.20681036168133f64,
3571            payment(0.023, 1, 0.0, 1.234567, true).unwrap()
3572        );
3573        assert_approx_equal!(
3574            12344.407037959f64,
3575            payment(0.023, 1, 1.234567, -12345.67, false).unwrap()
3576        );
3577        assert_approx_equal!(
3578            -0.0277566383186706f64,
3579            payment(0.023, 1, 1.234567, -1.234567, true).unwrap()
3580        );
3581        assert_approx_equal!(
3582            -124.719662041f64,
3583            payment(0.023, 1, 1.234567, 123.4567, false).unwrap()
3584        );
3585        assert_approx_equal!(
3586            11944.6469168133f64,
3587            payment(0.023, 1, 123.4567, -12345.67, true).unwrap()
3588        );
3589        assert_approx_equal!(
3590            -126.2962041f64,
3591            payment(0.023, 1, 123.4567, 0.0, false).unwrap()
3592        );
3593        assert_approx_equal!(
3594            -244.137736168133f64,
3595            payment(0.023, 1, 123.4567, 123.4567, true).unwrap()
3596        );
3597        assert_approx_equal!(
3598            -12506.16371f64,
3599            payment(0.023, 1, 12345.67, -123.4567, false).unwrap()
3600        );
3601        assert_approx_equal!(
3602            -12345.67f64,
3603            payment(0.023, 1, 12345.67, 0.0, true).unwrap()
3604        );
3605        assert_approx_equal!(
3606            -24975.29041f64,
3607            payment(0.023, 1, 12345.67, 12345.67, false).unwrap()
3608        );
3609        assert_approx_equal!(
3610            6302.67001787847f64,
3611            payment(0.023, 2, -12345.67, -123.4567, true).unwrap()
3612        );
3613        assert_approx_equal!(
3614            6385.99461810677f64,
3615            payment(0.023, 2, -12345.67, 1.234567, false).unwrap()
3616        );
3617        assert_approx_equal!(
3618            277.566383186706f64,
3619            payment(0.023, 2, -12345.67, 12345.67, true).unwrap()
3620        );
3621        assert_approx_equal!(
3622            64.4763142828967f64,
3623            payment(0.023, 2, -123.4567, -1.234567, false).unwrap()
3624        );
3625        assert_approx_equal!(
3626            61.8336103501328f64,
3627            payment(0.023, 2, -123.4567, 1.234567, true).unwrap()
3628        );
3629        assert_approx_equal!(
3630            6103.29313404248f64,
3631            payment(0.023, 2, -1.234567, -12345.67, false).unwrap()
3632        );
3633        assert_approx_equal!(
3634            1.2208464669705f64,
3635            payment(0.023, 2, -1.234567, -1.234567, true).unwrap()
3636        );
3637        assert_approx_equal!(
3638            -60.3878842471859f64,
3639            payment(0.023, 2, -1.234567, 123.4567, false).unwrap()
3640        );
3641        assert_approx_equal!(
3642            5965.44914325917f64,
3643            payment(0.023, 2, 0.0, -12345.67, true).unwrap()
3644        );
3645        assert_approx_equal!(0f64, payment(0.023, 2, 0.0, 0.0, false).unwrap());
3646        assert_approx_equal!(
3647            -59.6544914325917f64,
3648            payment(0.023, 2, 0.0, 123.4567, true).unwrap()
3649        );
3650        assert_approx_equal!(
3651            60.3878842471859f64,
3652            payment(0.023, 2, 1.234567, -123.4567, false).unwrap()
3653        );
3654        assert_approx_equal!(
3655            -0.624301552644587f64,
3656            payment(0.023, 2, 1.234567, 0.0, true).unwrap()
3657        );
3658        assert_approx_equal!(
3659            -6103.29313404248f64,
3660            payment(0.023, 2, 1.234567, 12345.67, false).unwrap()
3661        );
3662        assert_approx_equal!(
3663            -2.77566383186706f64,
3664            payment(0.023, 2, 123.4567, -123.4567, true).unwrap()
3665        );
3666        assert_approx_equal!(
3667            -64.4763142828967f64,
3668            payment(0.023, 2, 123.4567, 1.234567, false).unwrap()
3669        );
3670        assert_approx_equal!(
3671            -6027.87929852363f64,
3672            payment(0.023, 2, 123.4567, 12345.67, true).unwrap()
3673        );
3674        assert_approx_equal!(
3675            -6385.99461810677f64,
3676            payment(0.023, 2, 12345.67, -1.234567, false).unwrap()
3677        );
3678        assert_approx_equal!(
3679            -6243.6120713602f64,
3680            payment(0.023, 2, 12345.67, 1.234567, true).unwrap()
3681        );
3682        assert_approx_equal!(
3683            5000.22243424033f64,
3684            payment(0.023, 5, -12345.67, -12345.67, false).unwrap()
3685        );
3686        assert_approx_equal!(
3687            2582.91518643341f64,
3688            payment(0.023, 5, -12345.67, -1.234567, true).unwrap()
3689        );
3690        assert_approx_equal!(
3691            2618.50506199896f64,
3692            payment(0.023, 5, -12345.67, 123.4567, false).unwrap()
3693        );
3694        assert_approx_equal!(
3695            2330.9451381636f64,
3696            payment(0.023, 5, -123.4567, -12345.67, true).unwrap()
3697        );
3698        assert_approx_equal!(
3699            26.4208642212016f64,
3700            payment(0.023, 5, -123.4567, 0.0, false).unwrap()
3701        );
3702        assert_approx_equal!(
3703            2.77566383186706f64,
3704            payment(0.023, 5, -123.4567, 123.4567, true).unwrap()
3705        );
3706        assert_approx_equal!(
3707            23.8455687634136f64,
3708            payment(0.023, 5, -1.234567, -123.4567, false).unwrap()
3709        );
3710        assert_approx_equal!(
3711            0.258268467460426f64,
3712            payment(0.023, 5, -1.234567, 0.0, true).unwrap()
3713        );
3714        assert_approx_equal!(
3715            -2357.87180347795f64,
3716            payment(0.023, 5, -1.234567, 12345.67, false).unwrap()
3717        );
3718        assert_approx_equal!(
3719            23.0511829141756f64,
3720            payment(0.023, 5, 0.0, -123.4567, true).unwrap()
3721        );
3722        assert_approx_equal!(
3723            -0.235813601212016f64,
3724            payment(0.023, 5, 0.0, 1.234567, false).unwrap()
3725        );
3726        assert_approx_equal!(
3727            -2305.11829141756f64,
3728            payment(0.023, 5, 0.0, 12345.67, true).unwrap()
3729        );
3730        assert_approx_equal!(
3731            -0.028395041f64,
3732            payment(0.023, 5, 1.234567, -1.234567, false).unwrap()
3733        );
3734        assert_approx_equal!(
3735            -0.488780296602182f64,
3736            payment(0.023, 5, 1.234567, 1.234567, true).unwrap()
3737        );
3738        assert_approx_equal!(
3739            2331.71514789896f64,
3740            payment(0.023, 5, 123.4567, -12345.67, false).unwrap()
3741        );
3742        assert_approx_equal!(
3743            -25.5963349169009f64,
3744            payment(0.023, 5, 123.4567, -1.234567, true).unwrap()
3745        );
3746        assert_approx_equal!(
3747            -50.0022243424032f64,
3748            payment(0.023, 5, 123.4567, 123.4567, false).unwrap()
3749        );
3750        assert_approx_equal!(
3751            -277.566383186706f64,
3752            payment(0.023, 5, 12345.67, -12345.67, true).unwrap()
3753        );
3754        assert_approx_equal!(
3755            -2642.08642212016f64,
3756            payment(0.023, 5, 12345.67, 0.0, false).unwrap()
3757        );
3758        assert_approx_equal!(
3759            -2605.73585751844f64,
3760            payment(0.023, 5, 12345.67, 123.4567, true).unwrap()
3761        );
3762        assert_approx_equal!(
3763            1407.18314215102f64,
3764            payment(0.023, 10, -12345.67, -123.4567, false).unwrap()
3765        );
3766        assert_approx_equal!(
3767            1364.67451221027f64,
3768            payment(0.023, 10, -12345.67, 0.0, true).unwrap()
3769        );
3770        assert_approx_equal!(
3771            283.95041f64,
3772            payment(0.023, 10, -12345.67, 12345.67, false).unwrap()
3773        );
3774        assert_approx_equal!(
3775            24.5178264123383f64,
3776            payment(0.023, 10, -123.4567, -123.4567, true).unwrap()
3777        );
3778        assert_approx_equal!(
3779            13.8494090983119f64,
3780            payment(0.023, 10, -123.4567, 1.234567, false).unwrap()
3781        );
3782        assert_approx_equal!(
3783            -1073.46138390146f64,
3784            payment(0.023, 10, -123.4567, 12345.67, true).unwrap()
3785        );
3786        assert_approx_equal!(
3787            0.250817364198221f64,
3788            payment(0.023, 10, -1.234567, -1.234567, false).unwrap()
3789        );
3790        assert_approx_equal!(
3791            0.0277566383186706f64,
3792            payment(0.023, 10, -1.234567, 1.234567, true).unwrap()
3793        );
3794        assert_approx_equal!(
3795            1112.1116159911f64,
3796            payment(0.023, 10, 0.0, -12345.67, false).unwrap()
3797        );
3798        assert_approx_equal!(
3799            0.108710812902356f64,
3800            payment(0.023, 10, 0.0, -1.234567, true).unwrap()
3801        );
3802        assert_approx_equal!(
3803            -11.121116159911f64,
3804            payment(0.023, 10, 0.0, 123.4567, false).unwrap()
3805        );
3806        assert_approx_equal!(
3807            1086.97166157234f64,
3808            payment(0.023, 10, 1.234567, -12345.67, true).unwrap()
3809        );
3810        assert_approx_equal!(
3811            -0.13960620259911f64,
3812            payment(0.023, 10, 1.234567, 0.0, false).unwrap()
3813        );
3814        assert_approx_equal!(
3815            -11.0075487414567f64,
3816            payment(0.023, 10, 1.234567, 123.4567, true).unwrap()
3817        );
3818        assert_approx_equal!(
3819            -2.8395041f64,
3820            payment(0.023, 10, 123.4567, -123.4567, false).unwrap()
3821        );
3822        assert_approx_equal!(
3823            -13.6467451221027f64,
3824            payment(0.023, 10, 123.4567, 0.0, true).unwrap()
3825        );
3826        assert_approx_equal!(
3827            -1126.07223625102f64,
3828            payment(0.023, 10, 123.4567, 12345.67, false).unwrap()
3829        );
3830        assert_approx_equal!(
3831            -1353.80343092003f64,
3832            payment(0.023, 10, 12345.67, -123.4567, true).unwrap()
3833        );
3834        assert_approx_equal!(
3835            -1396.1732371527f64,
3836            payment(0.023, 10, 12345.67, 1.234567, false).unwrap()
3837        );
3838        assert_approx_equal!(
3839            -2451.78264123383f64,
3840            payment(0.023, 10, 12345.67, 12345.67, true).unwrap()
3841        );
3842        assert_approx_equal!(
3843            418.072090469851f64,
3844            payment(0.023, 50, -12345.67, -1.234567, false).unwrap()
3845        );
3846        assert_approx_equal!(
3847            408.646401579592f64,
3848            payment(0.023, 50, -12345.67, 1.234567, true).unwrap()
3849        );
3850        assert_approx_equal!(
3851            138.288856439316f64,
3852            payment(0.023, 50, -123.4567, -12345.67, false).unwrap()
3853        );
3854        assert_approx_equal!(
3855            4.09970442169419f64,
3856            payment(0.023, 50, -123.4567, -1.234567, true).unwrap()
3857        );
3858        assert_approx_equal!(
3859            2.8395041f64,
3860            payment(0.023, 50, -123.4567, 123.4567, false).unwrap()
3861        );
3862        assert_approx_equal!(
3863            131.133993656746f64,
3864            payment(0.023, 50, -1.234567, -12345.67, true).unwrap()
3865        );
3866        assert_approx_equal!(
3867            0.0418058679642887f64,
3868            payment(0.023, 50, -1.234567, 0.0, false).unwrap()
3869        );
3870        assert_approx_equal!(
3871            -1.27006532596733f64,
3872            payment(0.023, 50, -1.234567, 123.4567, true).unwrap()
3873        );
3874        assert_approx_equal!(
3875            1.34108269642887f64,
3876            payment(0.023, 50, 0.0, -123.4567, false).unwrap()
3877        );
3878        assert_approx_equal!(0f64, payment(0.023, 50, 0.0, 0.0, true).unwrap());
3879        assert_approx_equal!(
3880            -134.108269642887f64,
3881            payment(0.023, 50, 0.0, 12345.67, false).unwrap()
3882        );
3883        assert_approx_equal!(
3884            1.27006532596733f64,
3885            payment(0.023, 50, 1.234567, -123.4567, true).unwrap()
3886        );
3887        assert_approx_equal!(
3888            -0.0552166949285774f64,
3889            payment(0.023, 50, 1.234567, 1.234567, false).unwrap()
3890        );
3891        assert_approx_equal!(
3892            -131.133993656746f64,
3893            payment(0.023, 50, 1.234567, 12345.67, true).unwrap()
3894        );
3895        assert_approx_equal!(
3896            -4.16717596946458f64,
3897            payment(0.023, 50, 123.4567, -1.234567, false).unwrap()
3898        );
3899        assert_approx_equal!(
3900            -4.09970442169419f64,
3901            payment(0.023, 50, 123.4567, 1.234567, true).unwrap()
3902        );
3903        assert_approx_equal!(
3904            -283.95041f64,
3905            payment(0.023, 50, 12345.67, -12345.67, false).unwrap()
3906        );
3907        assert_approx_equal!(
3908            -408.646401579592f64,
3909            payment(0.023, 50, 12345.67, -1.234567, true).unwrap()
3910        );
3911        assert_approx_equal!(
3912            -419.399762339316f64,
3913            payment(0.023, 50, 12345.67, 123.4567, false).unwrap()
3914        );
3915        assert_approx_equal!(
3916            279.458579666982f64,
3917            payment(0.023, 250, -12345.67, -12345.67, true).unwrap()
3918        );
3919        assert_approx_equal!(
3920            284.918268499661f64,
3921            payment(0.023, 250, -12345.67, 0.0, false).unwrap()
3922        );
3923        assert_approx_equal!(
3924            278.503020444443f64,
3925            payment(0.023, 250, -12345.67, 123.4567, true).unwrap()
3926        );
3927        assert_approx_equal!(
3928            2.85886126999323f64,
3929            payment(0.023, 250, -123.4567, -123.4567, false).unwrap()
3930        );
3931        assert_approx_equal!(
3932            2.78512481426844f64,
3933            payment(0.023, 250, -123.4567, 0.0, true).unwrap()
3934        );
3935        assert_approx_equal!(
3936            1.8813241853352f64,
3937            payment(0.023, 250, -123.4567, 12345.67, false).unwrap()
3938        );
3939        assert_approx_equal!(
3940            0.0373122305440668f64,
3941            payment(0.023, 250, -1.234567, -123.4567, true).unwrap()
3942        );
3943        assert_approx_equal!(
3944            0.028395041f64,
3945            payment(0.023, 250, -1.234567, 1.234567, false).unwrap()
3946        );
3947        assert_approx_equal!(
3948            -0.918246991995591f64,
3949            payment(0.023, 250, -1.234567, 12345.67, true).unwrap()
3950        );
3951        assert_approx_equal!(
3952            9.67858499661454E-05f64,
3953            payment(0.023, 250, 0.0, -1.234567, false).unwrap()
3954        );
3955        assert_approx_equal!(
3956            -9.46098240138273E-05f64,
3957            payment(0.023, 250, 0.0, 1.234567, true).unwrap()
3958        );
3959        assert_approx_equal!(
3960            0.939366672811489f64,
3961            payment(0.023, 250, 1.234567, -12345.67, false).unwrap()
3962        );
3963        assert_approx_equal!(
3964            -0.0277566383186706f64,
3965            payment(0.023, 250, 1.234567, -1.234567, true).unwrap()
3966        );
3967        assert_approx_equal!(
3968            -0.0381704118465804f64,
3969            payment(0.023, 250, 1.234567, 123.4567, false).unwrap()
3970        );
3971        assert_approx_equal!(
3972            -1.83902657413021f64,
3973            payment(0.023, 250, 123.4567, -12345.67, true).unwrap()
3974        );
3975        assert_approx_equal!(
3976            -2.84918268499661f64,
3977            payment(0.023, 250, 123.4567, 0.0, false).unwrap()
3978        );
3979        assert_approx_equal!(
3980            -2.79458579666982f64,
3981            payment(0.023, 250, 123.4567, 123.4567, true).unwrap()
3982        );
3983        assert_approx_equal!(
3984            -284.908589914665f64,
3985            payment(0.023, 250, 12345.67, -123.4567, false).unwrap()
3986        );
3987        assert_approx_equal!(
3988            -278.512481426844f64,
3989            payment(0.023, 250, 12345.67, 0.0, true).unwrap()
3990        );
3991        assert_approx_equal!(
3992            -285.886126999323f64,
3993            payment(0.023, 250, 12345.67, 12345.67, false).unwrap()
3994        );
3995        assert_approx_equal!(
3996            15186.408667f64,
3997            payment(0.23, 1, -12345.67, -1.234567, false).unwrap()
3998        );
3999        assert_approx_equal!(
4000            12344.6662869919f64,
4001            payment(0.23, 1, -12345.67, 1.234567, true).unwrap()
4002        );
4003        assert_approx_equal!(
4004            12497.521741f64,
4005            payment(0.23, 1, -123.4567, -12345.67, false).unwrap()
4006        );
4007        assert_approx_equal!(
4008            124.46041300813f64,
4009            payment(0.23, 1, -123.4567, -1.234567, true).unwrap()
4010        );
4011        assert_approx_equal!(
4012            28.395041f64,
4013            payment(0.23, 1, -123.4567, 123.4567, false).unwrap()
4014        );
4015        assert_approx_equal!(
4016            10038.3646483008f64,
4017            payment(0.23, 1, -1.234567, -12345.67, true).unwrap()
4018        );
4019        assert_approx_equal!(
4020            1.51851741f64,
4021            payment(0.23, 1, -1.234567, 0.0, false).unwrap()
4022        );
4023        assert_approx_equal!(
4024            -99.1367338130081f64,
4025            payment(0.23, 1, -1.234567, 123.4567, true).unwrap()
4026        );
4027        assert_approx_equal!(
4028            123.4567f64,
4029            payment(0.23, 1, 0.0, -123.4567, false).unwrap()
4030        );
4031        assert_approx_equal!(0f64, payment(0.23, 1, 0.0, 0.0, true).unwrap());
4032        assert_approx_equal!(
4033            -12345.67f64,
4034            payment(0.23, 1, 0.0, 12345.67, false).unwrap()
4035        );
4036        assert_approx_equal!(
4037            99.1367338130081f64,
4038            payment(0.23, 1, 1.234567, -123.4567, true).unwrap()
4039        );
4040        assert_approx_equal!(
4041            -2.75308441f64,
4042            payment(0.23, 1, 1.234567, 1.234567, false).unwrap()
4043        );
4044        assert_approx_equal!(
4045            -10038.3646483008f64,
4046            payment(0.23, 1, 1.234567, 12345.67, true).unwrap()
4047        );
4048        assert_approx_equal!(
4049            -150.617174f64,
4050            payment(0.23, 1, 123.4567, -1.234567, false).unwrap()
4051        );
4052        assert_approx_equal!(
4053            -124.46041300813f64,
4054            payment(0.23, 1, 123.4567, 1.234567, true).unwrap()
4055        );
4056        assert_approx_equal!(
4057            -2839.5041f64,
4058            payment(0.23, 1, 12345.67, -12345.67, false).unwrap()
4059        );
4060        assert_approx_equal!(
4061            -12344.6662869919f64,
4062            payment(0.23, 1, 12345.67, -1.234567, true).unwrap()
4063        );
4064        assert_approx_equal!(
4065            -15308.6308f64,
4066            payment(0.23, 1, 12345.67, 123.4567, false).unwrap()
4067        );
4068        assert_approx_equal!(
4069            11310.4503055161f64,
4070            payment(0.23, 2, -12345.67, -12345.67, true).unwrap()
4071        );
4072        assert_approx_equal!(
4073            8375.67898789238f64,
4074            payment(0.23, 2, -12345.67, 0.0, false).unwrap()
4075        );
4076        assert_approx_equal!(
4077            6764.48556017354f64,
4078            payment(0.23, 2, -12345.67, 123.4567, true).unwrap()
4079        );
4080        assert_approx_equal!(
4081            139.118538757848f64,
4082            payment(0.23, 2, -123.4567, -123.4567, false).unwrap()
4083        );
4084        assert_approx_equal!(
4085            68.0949511210762f64,
4086            payment(0.23, 2, -123.4567, 0.0, true).unwrap()
4087        );
4088        assert_approx_equal!(
4089            -5452.41809801345f64,
4090            payment(0.23, 2, -123.4567, 12345.67, false).unwrap()
4091        );
4092        assert_approx_equal!(
4093            45.6905014452951f64,
4094            payment(0.23, 2, -1.234567, -123.4567, true).unwrap()
4095        );
4096        assert_approx_equal!(
4097            0.28395041f64,
4098            payment(0.23, 2, -1.234567, 1.234567, false).unwrap()
4099        );
4100        assert_approx_equal!(
4101            -4500.27424389723f64,
4102            payment(0.23, 2, -1.234567, 12345.67, true).unwrap()
4103        );
4104        assert_approx_equal!(
4105            0.553617488789238f64,
4106            payment(0.23, 2, 0.0, -1.234567, false).unwrap()
4107        );
4108        assert_approx_equal!(
4109            -0.450095519340844f64,
4110            payment(0.23, 2, 0.0, 1.234567, true).unwrap()
4111        );
4112        assert_approx_equal!(
4113            5535.33731999359f64,
4114            payment(0.23, 2, 1.234567, -12345.67, false).unwrap()
4115        );
4116        assert_approx_equal!(
4117            -0.230853991869919f64,
4118            payment(0.23, 2, 1.234567, -1.234567, true).unwrap()
4119        );
4120        assert_approx_equal!(
4121            -56.199316777713f64,
4122            payment(0.23, 2, 1.234567, 123.4567, false).unwrap()
4123        );
4124        assert_approx_equal!(
4125            4432.86024228736f64,
4126            payment(0.23, 2, 123.4567, -12345.67, true).unwrap()
4127        );
4128        assert_approx_equal!(
4129            -83.7567898789238f64,
4130            payment(0.23, 2, 123.4567, 0.0, false).unwrap()
4131        );
4132        assert_approx_equal!(
4133            -113.104503055161f64,
4134            payment(0.23, 2, 123.4567, 123.4567, true).unwrap()
4135        );
4136        assert_approx_equal!(
4137            -8320.31723901346f64,
4138            payment(0.23, 2, 12345.67, -123.4567, false).unwrap()
4139        );
4140        assert_approx_equal!(
4141            -6809.49511210762f64,
4142            payment(0.23, 2, 12345.67, 0.0, true).unwrap()
4143        );
4144        assert_approx_equal!(
4145            -13911.8538757848f64,
4146            payment(0.23, 2, 12345.67, 12345.67, false).unwrap()
4147        );
4148        assert_approx_equal!(
4149            3592.96564272554f64,
4150            payment(0.23, 5, -12345.67, -123.4567, true).unwrap()
4151        );
4152        assert_approx_equal!(
4153            4403.54930414689f64,
4154            payment(0.23, 5, -12345.67, 1.234567, false).unwrap()
4155        );
4156        assert_approx_equal!(
4157            2308.53991869919f64,
4158            payment(0.23, 5, -12345.67, 12345.67, true).unwrap()
4159        );
4160        assert_approx_equal!(
4161            44.1934774055241f64,
4162            payment(0.23, 5, -123.4567, -1.234567, false).unwrap()
4163        );
4164        assert_approx_equal!(
4165            35.6753146997254f64,
4166            payment(0.23, 5, -123.4567, 1.234567, true).unwrap()
4167        );
4168        assert_approx_equal!(
4169            1564.64199488175f64,
4170            payment(0.23, 5, -1.234567, -12345.67, false).unwrap()
4171        );
4172        assert_approx_equal!(
4173            0.485195719399889f64,
4174            payment(0.23, 5, -1.234567, -1.234567, true).unwrap()
4175        );
4176        assert_approx_equal!(
4177            -15.2016456706623f64,
4178            payment(0.23, 5, -1.234567, 123.4567, false).unwrap()
4179        );
4180        assert_approx_equal!(
4181            1271.70863764985f64,
4182            payment(0.23, 5, 0.0, -12345.67, true).unwrap()
4183        );
4184        assert_approx_equal!(0f64, payment(0.23, 5, 0.0, 0.0, false).unwrap());
4185        assert_approx_equal!(
4186            -12.7170863764985f64,
4187            payment(0.23, 5, 0.0, 123.4567, true).unwrap()
4188        );
4189        assert_approx_equal!(
4190            15.2016456706623f64,
4191            payment(0.23, 5, 1.234567, -123.4567, false).unwrap()
4192        );
4193        assert_approx_equal!(
4194            -0.358024855634904f64,
4195            payment(0.23, 5, 1.234567, 0.0, true).unwrap()
4196        );
4197        assert_approx_equal!(
4198            -1564.64199488175f64,
4199            payment(0.23, 5, 1.234567, 12345.67, false).unwrap()
4200        );
4201        assert_approx_equal!(
4202            -23.0853991869919f64,
4203            payment(0.23, 5, 123.4567, -123.4567, true).unwrap()
4204        );
4205        assert_approx_equal!(
4206            -44.1934774055241f64,
4207            payment(0.23, 5, 123.4567, 1.234567, false).unwrap()
4208        );
4209        assert_approx_equal!(
4210            -1307.51112321334f64,
4211            payment(0.23, 5, 123.4567, 12345.67, true).unwrap()
4212        );
4213        assert_approx_equal!(
4214            -4403.54930414689f64,
4215            payment(0.23, 5, 12345.67, -1.234567, false).unwrap()
4216        );
4217        assert_approx_equal!(
4218            -3580.3757272128f64,
4219            payment(0.23, 5, 12345.67, 1.234567, true).unwrap()
4220        );
4221        assert_approx_equal!(
4222            3659.46546285804f64,
4223            payment(0.23, 10, -12345.67, -12345.67, false).unwrap()
4224        );
4225        assert_approx_equal!(
4226            2641.89087763997f64,
4227            payment(0.23, 10, -12345.67, -1.234567, true).unwrap()
4228        );
4229        assert_approx_equal!(
4230            3245.38497461473f64,
4231            payment(0.23, 10, -12345.67, 123.4567, false).unwrap()
4232        );
4233        assert_approx_equal!(
4234            359.736202636836f64,
4235            payment(0.23, 10, -123.4567, -12345.67, true).unwrap()
4236        );
4237        assert_approx_equal!(
4238            32.4948478142902f64,
4239            payment(0.23, 10, -123.4567, 0.0, false).unwrap()
4240        );
4241        assert_approx_equal!(
4242            23.0853991869919f64,
4243            payment(0.23, 10, -123.4567, 123.4567, true).unwrap()
4244        );
4245        assert_approx_equal!(
4246            4.42475529243308f64,
4247            payment(0.23, 10, -1.234567, -123.4567, false).unwrap()
4248        );
4249        assert_approx_equal!(
4250            0.264185754587725f64,
4251            payment(0.23, 10, -1.234567, 0.0, true).unwrap()
4252        );
4253        assert_approx_equal!(
4254            -409.655732950875f64,
4255            payment(0.23, 10, -1.234567, 12345.67, false).unwrap()
4256        );
4257        assert_approx_equal!(
4258            3.33317627178063f64,
4259            payment(0.23, 10, 0.0, -123.4567, true).unwrap()
4260        );
4261        assert_approx_equal!(
4262            -0.0409980681429018f64,
4263            payment(0.23, 10, 0.0, 1.234567, false).unwrap()
4264        );
4265        assert_approx_equal!(
4266            -333.317627178063f64,
4267            payment(0.23, 10, 0.0, 12345.67, true).unwrap()
4268        );
4269        assert_approx_equal!(
4270            -0.28395041f64,
4271            payment(0.23, 10, 1.234567, -1.234567, false).unwrap()
4272        );
4273        assert_approx_equal!(
4274            -0.297517517305531f64,
4275            payment(0.23, 10, 1.234567, 1.234567, true).unwrap()
4276        );
4277        assert_approx_equal!(
4278            377.485833614727f64,
4279            payment(0.23, 10, 123.4567, -12345.67, false).unwrap()
4280        );
4281        assert_approx_equal!(
4282            -26.3852436960547f64,
4283            payment(0.23, 10, 123.4567, -1.234567, true).unwrap()
4284        );
4285        assert_approx_equal!(
4286            -36.5946546285804f64,
4287            payment(0.23, 10, 123.4567, 123.4567, false).unwrap()
4288        );
4289        assert_approx_equal!(
4290            -2308.53991869919f64,
4291            payment(0.23, 10, 12345.67, -12345.67, true).unwrap()
4292        );
4293        assert_approx_equal!(
4294            -3249.48478142902f64,
4295            payment(0.23, 10, 12345.67, 0.0, false).unwrap()
4296        );
4297        assert_approx_equal!(
4298            -2645.19072214903f64,
4299            payment(0.23, 10, 12345.67, 123.4567, true).unwrap()
4300        );
4301        assert_approx_equal!(
4302            2839.59579004515f64,
4303            payment(0.23, 50, -12345.67, -123.4567, false).unwrap()
4304        );
4305        assert_approx_equal!(
4306            2308.61372538449f64,
4307            payment(0.23, 50, -12345.67, 0.0, true).unwrap()
4308        );
4309        assert_approx_equal!(
4310            2839.5041f64,
4311            payment(0.23, 50, -12345.67, 12345.67, false).unwrap()
4312        );
4313        assert_approx_equal!(
4314            23.0868753206979f64,
4315            payment(0.23, 50, -123.4567, -123.4567, true).unwrap()
4316        );
4317        assert_approx_equal!(
4318            28.3959397440069f64,
4319            payment(0.23, 50, -123.4567, 1.234567, false).unwrap()
4320        );
4321        assert_approx_equal!(
4322            23.0123305685425f64,
4323            payment(0.23, 50, -123.4567, 12345.67, true).unwrap()
4324        );
4325        assert_approx_equal!(
4326            0.283968566444584f64,
4327            payment(0.23, 50, -1.234567, -1.234567, false).unwrap()
4328        );
4329        assert_approx_equal!(
4330            0.230853991869919f64,
4331            payment(0.23, 50, -1.234567, 1.234567, true).unwrap()
4332        );
4333        assert_approx_equal!(
4334            0.0907822229220255f64,
4335            payment(0.23, 50, 0.0, -12345.67, false).unwrap()
4336        );
4337        assert_approx_equal!(
4338            7.38066853025501E-06f64,
4339            payment(0.23, 50, 0.0, -1.234567, true).unwrap()
4340        );
4341        assert_approx_equal!(
4342            -0.000907822229219732f64,
4343            payment(0.23, 50, 0.0, 123.4567, false).unwrap()
4344        );
4345        assert_approx_equal!(
4346            -0.157054687235803f64,
4347            payment(0.23, 50, 1.234567, -12345.67, true).unwrap()
4348        );
4349        assert_approx_equal!(
4350            -0.283959488222292f64,
4351            payment(0.23, 50, 1.234567, 0.0, false).unwrap()
4352        );
4353        assert_approx_equal!(
4354            -0.231599439391473f64,
4355            payment(0.23, 50, 1.234567, 123.4567, true).unwrap()
4356        );
4357        assert_approx_equal!(
4358            -28.395041f64,
4359            payment(0.23, 50, 123.4567, -123.4567, false).unwrap()
4360        );
4361        assert_approx_equal!(
4362            -23.0861372538449f64,
4363            payment(0.23, 50, 123.4567, 0.0, true).unwrap()
4364        );
4365        assert_approx_equal!(
4366            -28.4867310451513f64,
4367            payment(0.23, 50, 123.4567, 12345.67, false).unwrap()
4368        );
4369        assert_approx_equal!(
4370            -2308.61298731764f64,
4371            payment(0.23, 50, 12345.67, -123.4567, true).unwrap()
4372        );
4373        assert_approx_equal!(
4374            -2839.59489130114f64,
4375            payment(0.23, 50, 12345.67, 1.234567, false).unwrap()
4376        );
4377        assert_approx_equal!(
4378            -2308.68753206979f64,
4379            payment(0.23, 50, 12345.67, 12345.67, true).unwrap()
4380        );
4381        assert_approx_equal!(
4382            2839.5041f64,
4383            payment(0.23, 250, -12345.67, -1.234567, false).unwrap()
4384        );
4385        assert_approx_equal!(
4386            2308.53991869919f64,
4387            payment(0.23, 250, -12345.67, 1.234567, true).unwrap()
4388        );
4389        assert_approx_equal!(
4390            28.3950410000001f64,
4391            payment(0.23, 250, -123.4567, -12345.67, false).unwrap()
4392        );
4393        assert_approx_equal!(
4394            23.0853991869919f64,
4395            payment(0.23, 250, -123.4567, -1.234567, true).unwrap()
4396        );
4397        assert_approx_equal!(
4398            28.395041f64,
4399            payment(0.23, 250, -123.4567, 123.4567, false).unwrap()
4400        );
4401        assert_approx_equal!(
4402            0.230853991869828f64,
4403            payment(0.23, 250, -1.234567, -12345.67, true).unwrap()
4404        );
4405        assert_approx_equal!(
4406            0.28395041f64,
4407            payment(0.23, 250, -1.234567, 0.0, false).unwrap()
4408        );
4409        assert_approx_equal!(
4410            0.230853991869918f64,
4411            payment(0.23, 250, -1.234567, 123.4567, true).unwrap()
4412        );
4413        assert_approx_equal!(0f64, payment(0.23, 250, 0.0, -123.4567, false).unwrap());
4414        assert_approx_equal!(0f64, payment(0.23, 250, 0.0, 0.0, true).unwrap());
4415        assert_approx_equal!(0f64, payment(0.23, 250, 0.0, 12345.67, false).unwrap());
4416        assert_approx_equal!(
4417            -0.230853991869918f64,
4418            payment(0.23, 250, 1.234567, -123.4567, true).unwrap()
4419        );
4420        assert_approx_equal!(
4421            -0.28395041f64,
4422            payment(0.23, 250, 1.234567, 1.234567, false).unwrap()
4423        );
4424        assert_approx_equal!(
4425            -0.230853991869828f64,
4426            payment(0.23, 250, 1.234567, 12345.67, true).unwrap()
4427        );
4428        assert_approx_equal!(
4429            -28.395041f64,
4430            payment(0.23, 250, 123.4567, -1.234567, false).unwrap()
4431        );
4432        assert_approx_equal!(
4433            -23.0853991869919f64,
4434            payment(0.23, 250, 123.4567, 1.234567, true).unwrap()
4435        );
4436        assert_approx_equal!(
4437            -2839.5041f64,
4438            payment(0.23, 250, 12345.67, -12345.67, false).unwrap()
4439        );
4440        assert_approx_equal!(
4441            -2308.53991869919f64,
4442            payment(0.23, 250, 12345.67, -1.234567, true).unwrap()
4443        );
4444        assert_approx_equal!(
4445            -2839.5041f64,
4446            payment(0.23, 250, 12345.67, 123.4567, false).unwrap()
4447        );
4448    }
4449}