FN-PMT-001: PMT takes ln(1+rate) from a series, and stores its quotient before the rate
Detail for matching Excel's bits · measured · recorded 2026-11-04
With RN(v) meaning v rounded to 64 bits on the x87 unit and then stored to binary64, PMT with fv 0 and type 0 at rates from -1/3 to 1/2 runs: s = rate/(2+rate); L = 2s + 2s*(s^2*T), where T = 1/3 + s^2/5 + ... + s^20/23 by Horner, all in plain binary64, which is the atanh series for ln(1+rate) (Abramowitz and Stegun 4.1.27) with the 2s term added last; t = -(nper*L); u = exp(t) stored; em = RN(RN(RN(u-1)*t)/ln(u)) for |t| < 1, and RN(u-1) otherwise, Kahan's way of forming expm1; q = RN(pv/em); PMT = RN(q*rate). L is not the correctly rounded logarithm: at rate 0.05/12 it is 0x3f7107fd59addc8a, one unit below 0x3f7107fd59addc8b, and the common 30-year loan below comes out 1 unit from the correctly rounded payment.
| Call and input route | Inputs | Excel | Correct value | Recorded in |
|---|---|---|---|---|
=PMT(0.05/12,360,200000)formula-literal | As typed | -1073.64324602427810xc090c692af15f63a | -1073.6432460242780xc090c692af15f639 | Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA |
Correct value: mpmath at 800 bits with rate the binary64 0x3f71111111111111 that 0.05/12 evaluates to; correctly rounded.
Basis: For each of 1,184 rates one binary64 L reproduces Excel's em at every nper (1,622 of 1,622 power-of-two and 1,849 of 1,849 other nper, L taken from nper 1 alone). The series gives that L at 1,181 rates; the correctly rounded log1p and fdlibm's log1p each give it at 667. Order and precision of the last two steps: in all 4,802 groups of recorded answers sharing (rate, nper) with 8 or more pv values, these steps admit one em; a binary64 quotient leaves 59 groups with none, and binary64 for both steps 111. 720 of 720 fresh type 0 rows over 20 rates, both signs, match (Excel build 20527). Over every recorded PMT row, types and fv included, 279,887 of 291,978 match.
Inferred: The range -1/3 to 1/2 is where twelve series terms converge, not a measured Excel boundary. Rate 0.419, near sqrt(2)-1, misses by 1 unit, so a range reduction may start there. Negative rates rest on 20 rates' controls and the recorded rows.
Open: type 1: Excel multiplies q by one stored binary64 K near rate/(1+rate) per rate (pinned at all but one of about 458 recorded rates and at 20 of 20 fresh ones), but K's formula is open: the correctly rounded quotient fits 344 of 458.
Open: Nonzero fv: the numerator of q is open. The best form tried fits 5,600 of 7,491 rows, and 146 rows admit no binary64 numerator under this order.
Open: Rates outside -1/3 to 1/2.
Evidence and capture sources
- ExcelFunctionsHandbook · content/notes/evidence/2026-11-04/annuity-EVIDENCE.txt b5d84a80a5a4640eca9ce04f232c0bc115503f34 · section UPDATE research write-up; the update supersedes the blocked outcome at its head
- DnaCalc · crates/calc-func/src/ported/financial_time_value_family.rs 08ea3d7ae0ba8d7241e2545aeeb78ff246ac6963 · pmt the logarithm and the stored quotient in the product; the commit message carries the row counts
- DnaCalc · crates/calc-func/src/ported/excel_numeric/mod.rs 08ea3d7ae0ba8d7241e2545aeeb78ff246ac6963 · excel_log1p_atanh the series
- DnaCalc · crates/calc-func/tests/captures/catalogue/sections/dcj9k_annuity.capture.json c9f9d354165d2c20b9455c32582ea50baac7ba73 · recorded answers of the 30-year loan block
- DnaCalc · crates/calc-func/tests/captures/catalogue/sections/dcj9k_annuity.capture.json c9f9d354165d2c20b9455c32582ea50baac7ba73 · sheet dcj9k_annuity, row 726, column 4