Compound Interest in Code: The Closed Form You Should Actually Use
If you have ever priced a savings product or modeled a recurring investment in code, you have met compound interest. The naive approach loops month by month. It works, but it is slow for long horizons and awkward when you want the balance at an arbitrary time. The closed form is one line — here is the derivation, the edge cases, and the implementation details that bite.
The formula
For a principal P, a periodic rate r (annual nominal rate divided by the number of compounding periods per year n), and t years:
A = P * (1 + r/n)^(n*t) -
P— principal (starting balance) -
r— annual nominal interest rate as a decimal (5% →0.05) -
n— compounding periods per year (monthly → 12, daily → 365) -
t— time in years
The loop equivalent credits interest to the balance each period, so period k+1 earns interest on the interest from period k. The exponent n*t is just the total number of periods.
Worked example
P = 1000, r = 0.05, n = 12, t = 5:
periodic rate = 0.05 / 12 = 0.004167 periods = 12 * 5 = 60 A = 1000 * (1.004167)^60 = 1283.36 So the balance grows to about 1,283 after five years — 283 in interest, of which a portion is interest earned on earlier interest.
The continuous limit
As n grows without bound, compounding approaches a closed form of its own:
A = P * e^(r*t) This is useful as a quick upper bound and shows up constantly in finance and actuarial code. It also makes a good sanity check: the discrete result must always be below the continuous one for the same r and t.
Where implementations go wrong
- Percent vs decimal. Callers pass
5meaning 5%. Divide by 100. This is the single most common bug. - Rate period mismatch. If your rate is already monthly but you also divide by 12, you compound far too slowly. Document which unit
ris in. - Floating point on money. Binary floats cannot represent 0.1 exactly. For anything that settles real money, use a decimal type (
decimal.Decimalin Python, integer cents) and round only at the end. - Negative and zero rates. The formula still works for
r < 0(decay) andr = 0(balance unchanged), but naive integer typecasts ofn*twill truncate fractional years. - Overflow.
(1 + r/n)^(n*t)can overflow a 32-bit float for long horizons and high rates. Use 64-bit.
Tooling
When you just need the number — or want to see how the balance changes as you vary the principal, rate, or compounding frequency — I built a small client-side Compound Interest Calculator. It runs in the browser, shows the year-by-year growth, and makes the discrete-vs-continuous difference visible without you writing a loop.
Bottom line
- Use
A = P (1 + r/n)^(nt); reach forP e^(rt)as the continuous bound. - Normalize percent → decimal and document the rate's period.
- Use decimal/integer cents for money, 64-bit floats for the math.
![Industrial Communication — Ch.10: Factory Automation [EN]](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft1hw2kvh64lkchmsurzd.png)

