Known larger differences on 524 of 834 recorded answers
Of 834 recorded answers (586 in the answer bank and 248 workbook cells), 524 do not match: 13 differ by more than 16 ULP, 511 differ by at most 16 ULP. How we measure this · See the Rust code
CUMPRINC(rate, nper, pv, start_period, end_period, type) returns the total principal repaid
on a loan between two period numbers, inclusive — the amount by which the outstanding balance
falls over that span.
It is built on the same level-payment annuity as its sibling. The model is one equation:
Solving for the payment gives the constant pmt; each period then splits it:
interest in period k = r × (balance outstanding at the start of period k)
principal in period k = pmt − interest in period k
and, in exact arithmetic,
CUMPRINC(r, n, pv, s, e, type) = Σ_{k = s}^{e} PPMT(r, k, n, pv, 0, type)
In Excel that sum holds on one loan and not in general. CUMPRINC(0.05/12,360,200000,1,12,0) is
the left-to-right binary64 sum of Excel's own twelve PPMT answers, to the last bit, but over
recorded type 0 calls for a single period CUMPRINC equals PPMT on 56 of 135 rows, with PPMT
computed by the route in FN-IPMT-001 (FN-CUMPRINC-001).
Because fv is fixed at zero, summing over the whole schedule gives back the loan:
CUMPRINC(r, n, pv, 1, n, type) is −pv in exact arithmetic. That identity is the single best
sanity check available for this function, and it is exact in the mathematics and only
approximate in binary64 — which makes it a measurement rather than an assertion.
Arguments
CUMPRINC(rate, nper, pv, start_period, end_period, type) — six arguments, all required, and
identical in meaning to CUMIPMT.
Argument
Meaning (Microsoft's wording)
Notes
rate
"The interest rate."
Per period, not per year
nper
"The total number of payment periods."
Truncated to an integer
pv
"The present value."
The loan amount; positive for a loan
start_period
"The first period in the calculation. Payment periods are numbered beginning with 1."
Truncated
end_period
"The last period in the calculation."
Truncated
type
"The timing of the payment."
0 or 1
type
Timing (Microsoft's table)
0 (zero)
Payment at the end of the period
1
Payment at the beginning of the period
Periods are numbered from 1.rate and nper must use the same unit — Microsoft:
"If you make monthly payments on a four-year loan at an annual interest rate of 12 percent, use
12%/12 for rate and 4*12 for nper."
Try it
Quirks
Sign conventions
Money you receive is positive; money you pay is negative. For a loan pv is positive — cash
in — and every payment is negative, so CUMPRINC returns a negative number. Repaying
principal is money leaving.
The full-schedule identity above is the clearest statement of the convention: borrow pv, repay
−pv. A model that treats CUMPRINC as a positive "principal repaid" figure without negating
it will report the loan growing.
Result and edge cases
start_period = 1, end_period = nper returns −pv in exact arithmetic. Any deviation
is accumulated floating-point error, and measuring it is the most informative single experiment
on this page.
type = 1 shifts the schedule: the first payment happens before interest accrues, so the
first period's principal component is the whole payment. This is the same first-period
boundary an attached defect stream names for the interest side.
Early periods repay little principal, late periods almost all of it; the function is
strongly non-linear in start_period even though the payment is constant.
Long ranges cost time proportional to the number of periods summed.
Microsoft's Learn page for this function documents three conditions, and states the first one
with the inequalities the right way round:
"If rate ≤ 0, nper ≤ 0, or pv ≤ 0, CumPrinc generates an error."
Condition (documented)
Documented outcome
rate ≤ 0, nper ≤ 0, or pv ≤ 0
error
start_period < 1, end_period < 1, or start_period > end_period
error
type is any number other than 0 or 1
error
The sibling page disagrees with this one. Microsoft's CumIPmt page states the same
condition as "If rate > 0, nper > 0, or pv > 0 … generates an error" — the inequalities
inverted. Two pages documenting the same validation for two functions that share an
implementation cannot both be right; this page's form is the one the rest of the documentation
and every implementation support. Recorded on CUMIPMT as a
documentation defect.
CUMPRINC follows PPMT on one loan and not in general; its own route is open
On the 30-year loan, CUMPRINC(0.05/12,360,200000,1,12,0) equals the left-to-right binary64 sum of Excel's own twelve PPMT answers, to the last bit, and CUMIPMT over the same periods equals 12*PMT - CUMPRINC, computed from Excel's own answers, to the last bit. That does not generalise: over recorded type 0 calls for a single period, CUMPRINC equals PPMT on 56 of 135 rows and differs on 79, with PPMT computed by the route in FN-IPMT-001.
Explanation (inferred): That the 79 single-period differences are CUMPRINC's own and not PPMT's rests on the PPMT route, which matches every fv 0, type 0 row tested. That CUMIPMT remains count*PMT less CUMPRINC beyond this block is inferred.
Formula
Excel
Mathematical value
=CUMPRINC(0.05/12,360,200000,1,12,0) Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZAInputs and reference value
Typed formula.
-2950.7306911349597 0xc0a70d761d260042
—
=CUMIPMT(0.05/12,360,200000,1,12,0) Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZAInputs and reference value
Typed formula.
-9932.988261156377 0xc0c3667e7f577146
—
=PMT(0.05/12,360,200000) Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZAInputs and reference value
The subtraction is where the digits go. Each summand is pmt − r × balance; early in a
loan those two quantities are close, so the principal component is a small difference of two
larger numbers. That is ordinary cancellation, and it means CUMPRINC over an early range is
intrinsically harder than CUMIPMT over the same range.
Summation order is observable, and so is the choice between summing PPMT terms and
forming pmt × count − CUMIPMT. Those are different functions in binary64.
The full-schedule identity is a calibration instrument.CUMPRINC(r, n, pv, 1, n, type)
should be −pv; the deviation is a direct, dimensioned measure of the accumulated error, and
it needs no oracle to observe.
Boundary periods are where implementations fork: the first period under type = 1, and
the last period, where the remaining balance should land exactly on zero rather than on a
small residual.
Rust code
Show the CalcFunc source of this function
Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.
17 cumprinc_fn "CUMPRINC" (6, 6) [V"rate", V"nper", V"pv", V"start_period", V"end_period", V"type"] |s, a, sv| {
cumulative_out(s, cumulative::cumprinc_kernel(required_num(s, a, 0)?, required_num(s, a, 1)?, required_num(s, a, 2)?, required_num(s, a, 3)?, required_num(s, a, 4)?, required_num(s, a, 5)?))
}
No implementation has been published with a Handbook test suite for this function.
Version differences
The recorded environments below distinguish a reading from a same-input comparison. Counts describe captured inputs in each environment; overlapping captures and comparisons are not totals of unique worksheet calls.
Excel 16.0 build
Platform and CPU
Captured inputs
20228
Windows, 64-bit, CPU not recorded
540
The record contains no same-input comparison between these environments. Reading different inputs on different builds does not establish either a version change or cross-build agreement.
Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA
=CUMPRINC(0.05/12,360,200000,1,12,0) returned -2950.7306911349597 (0xc0a70d761d260042). Inputs were supplied through formula literals. These are controls from this environment, not a same-input comparison with another build.
540 captured inputs are indexed for this environment. Capture dates: 2026-08-09 to 2026-08-09. This is a reading count, not a comparison with another build.
Alternatives
Relationships
CUMIPMT — the interest half. CUMIPMT + CUMPRINC equals
pmt × (end_period − start_period + 1) in exact arithmetic; in floating point the residual is
a measurement of both functions at once.
PPMT — the single-period principal component and this function's summand in the
mathematics. On a one-period range the two differ on 79 of 135 recorded rows (FN-CUMPRINC-001).
IPMT — the interest component, and CUMIPMT's summand in the mathematics.
PMT — the payment every evaluation starts from. Any PMT error is inherited by both
cumulative functions with the same sign in every term.
FV, PV, NPER, RATE — the other faces of the same annuity equation. The Handbook's
research record documents that Excel does not share one annuity kernel across them: PMT
uses a cancellation-safe discount form where FV and PV use the naive power form.
ISPMT — a different loan model (level principal rather than level payment); not a
substitute.
Confused with: PPMT (single period versus range), and with a hand-built amortization
table, which will disagree in the last digits precisely because it accumulates in a different
order.