Quant Memo
Core

Numerical Stability and Error Analysis

Why the same mathematically-correct formula can give a computer wildly wrong answers — small rounding errors from finite-precision arithmetic can either stay small or explode, and which one happens depends entirely on how the calculation is arranged.

Prerequisites: Floating-Point Arithmetic and Precision

Two mathematically equivalent formulas for the same quantity — algebraically identical on paper — can give a computer answers that differ by many orders of magnitude. This isn't a bug in the sense of a typo; it's a structural fact about doing arithmetic with numbers that are only ever stored to about 15-16 significant digits. Every operation on a computer introduces a tiny rounding error, and numerical stability is the question of what happens to that error as it flows through the rest of the calculation: does it stay small and harmless, or does it get amplified into something that swamps the true answer?

An analogy: a whispered message down a line

Picture a game of telephone where each person, on top of relaying the message, also has a small independent chance of mishearing a word. Most versions of the game just accumulate a bit of noise — the message at the end is roughly right, slightly garbled. But some versions of the "rules" for relaying can amplify a mishearing — for instance, if each person is instructed to repeat the difference between what they heard and what they expected, a tiny mishearing early on can get blown up into nonsense by the time it reaches the last person. An unstable numerical algorithm is the second kind of relay: it doesn't just pass rounding error along, it magnifies it.

The math, one piece at a time

Every floating-point number is stored with a relative error bounded by machine epsilon, ε2.2×1016\varepsilon \approx 2.2 \times 10^{-16} for standard double precision — meaning a stored value x^\hat{x} satisfies x^=x(1+δ)\hat{x} = x(1+\delta) for some tiny δε|\delta| \le \varepsilon. In words: each stored number is correct to about 16 significant digits, off by a relative error no bigger than roughly 101610^{-16}. The dangerous operation is subtracting two nearly-equal numbers, called catastrophic cancellation: if aa and bb are both accurate to relative error ε\varepsilon but aba \approx b, then aba - b is a small number computed from the difference of two large numbers' rounding errors, so its relative error can be enormous even though aa and bb individually were fine.

Formally, if aa and bb have absolute errors of size roughly εa\varepsilon \cdot |a|, the absolute error in aba - b stays roughly the same size — but the relative error in the result is that absolute error divided by ab|a-b|, which explodes if ab|a-b| is much smaller than a|a| and b|b| themselves:

relative error of (ab)    εaab.\text{relative error of } (a-b) \; \approx \; \frac{\varepsilon \cdot |a|}{|a - b|} .

In plain English: subtracting two close numbers doesn't create more absolute error, but it shrinks the answer's own size, so the same absolute error now represents a much larger fraction of a much smaller result — the accurate digits cancel out along with the values, leaving only noise.

Worked example 1: catastrophic cancellation by hand

Compute x=1,000,0011,000,000x = \sqrt{1{,}000{,}001} - \sqrt{1{,}000{,}000} using 6 significant digits, as a limited calculator might. 1,000,0011000.0005\sqrt{1{,}000{,}001} \approx 1000.0005, rounded to 6 digits: 1000.001000.00. 1,000,000=1000.00\sqrt{1{,}000{,}000} = 1000.00 exactly. Subtracting gives 00 — completely wrong; the true answer is about 0.00050.0005. Rewriting algebraically using ab=aba+b\sqrt{a}-\sqrt{b} = \frac{a-b}{\sqrt{a}+\sqrt{b}} avoids the subtraction of close numbers entirely: 11,000,001+1,000,00012000.00=0.0005\frac{1}{\sqrt{1{,}000{,}001}+\sqrt{1{,}000{,}000}} \approx \frac{1}{2000.00} = 0.0005, matching the true value even with only 6-digit precision.

Worked example 2: a P&L example with real dollar figures

A book's mark-to-market P&L is computed as ending valuestarting value\text{ending value} - \text{starting value}, where a position worth roughly $50,000,000 moves by only $120 in a quiet session — a true relative change of about 2.4×1062.4 \times 10^{-6}. If ending and starting values are each stored with a rounding error of about ε×50,000,00050,000,000×2.2×10160.000011\varepsilon \times 50{,}000{,}000 \approx 50{,}000{,}000 \times 2.2\times10^{-16} \approx 0.000011, that's a rounding noise floor of roughly one-hundredth of a cent — negligible next to $120, so this particular subtraction is actually fine. The lesson isn't "always avoid subtraction" but "check how large the noise floor is relative to the answer you're computing" — cancellation is only catastrophic when the result is close in size to the rounding error itself.

a and b, each accurate to ~1e-16 relative error a b a − b: tiny gap, same absolute noise now dominates
When a and b are close, their difference is small — but the rounding noise in each doesn't shrink, so that fixed noise becomes a large fraction of the now-small answer.
naive: √(a)−√(b) relative error ≈ 100% rewritten: (a−b)/(√a+√b) relative error ≈ 1e-6
Two algebraically identical formulas for the same quantity: the naive subtraction loses nearly all precision, while the algebraically rearranged version — avoiding subtraction of two close large numbers — stays accurate.

What this means in practice

Numerical stability governs which formula a pricing library actually implements, not just which formula a textbook writes down: computing implied volatility, Greeks via finite differences, variance as E[X2](E[X])2\mathbb{E}[X^2]-(\mathbb{E}[X])^2 (unstable — prefer accumulating squared deviations from a running mean), or covariance matrices from near-collinear factors. Anywhere a calculation subtracts two large, similar quantities to get a small answer, or divides by a number close to zero, stability deserves a second look before trusting the output.

Numerical stability is about how rounding error, always present at roughly 101610^{-16} relative size per operation, propagates through a calculation — a formula is unstable if algebraically-tiny rounding errors get amplified into a large relative error in the final answer, and the fix is usually an algebraically equivalent rearrangement that avoids subtracting two nearly-equal large numbers.

The classic mistake is assuming that because a formula is mathematically correct — provably equal to the right answer with real-number arithmetic — it must also be numerically safe to implement directly. Mathematical correctness and numerical stability are entirely separate properties; ab\sqrt{a}-\sqrt{b} and aba+b\frac{a-b}{\sqrt{a}+\sqrt{b}} are the same number on paper and can differ by 100% relative error in floating-point code. Never assume a formula copied straight from a derivation is safe to code up without checking whether it subtracts two close quantities anywhere.

Related concepts

Practice in interviews

Further reading

  • Higham, Accuracy and Stability of Numerical Algorithms, ch. 1-2
  • Trefethen & Bau, Numerical Linear Algebra, lecture 14
ShareTwitterLinkedIn