Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::math_big_integer::BigInt; ← from math.big-integer ^1.0.0 · built alongside by fune
/// The AER of a gross rate paid `payments_per_year` times a year:
/// (1 + i / n)^n − 1, per the UK Finance / BSA AER Practice Note formula (d),
/// rounded half-up to two decimal places of a percent (a whole basis point).
///
/// With i = b / 10000 and D = 10000 × n the exact value in basis points is
/// 10000 × ((D + b)^n − D^n) / D^n, computed in integers and rounded once.
///
/// # Panics
/// Panics on a rate or frequency out of range.
pub fn savings_aer(gross_rate_basis_points: i64, payments_per_year: i64) -> i64 {
let b = gross_rate_basis_points;
if b < 0 || b > 100000 {
panic!("grossRateBasisPoints must be between 0 and 100000, received {}", b);
}
let n = payments_per_year;
if n < 1 || n > 365 {
panic!("paymentsPerYear must be between 1 and 365, received {}", n);
}
let d = BigInt::from_i64(10000 * n);
let whole = d.pow(n as u64);
let numerator = BigInt::from_i64(10000).mul(&d.add(&BigInt::from_i64(b)).pow(n as u64).sub(&whole));
// Half-up for a non-negative fraction: floor((2N + M) / 2M).
let two = BigInt::from_i64(2);
two.mul(&numerator).add(&whole).div(&two.mul(&whole)).to_i64()
}
pub fn fune_vector(args: &[Value]) -> Value {
Value::Int(savings_aer(args[0].as_i64(), args[1].as_i64()))
}