5.4.22Scientific Computing (Python)

Floating point gotchas — catastrophic cancellation, associativity failure

2,063 words9 min readdifficulty · medium6 backlinks

1. WHAT is a floating point number?

WHY 2522^{-52}? With 52 fraction bits after the implicit leading 1, the least significant bit at exponent 00 has weight 2522^{-52}. That is the resolution near 1.01.0.

The key word is relative: error scales with the magnitude of the number, not absolutely.


2. Catastrophic cancellation

Figure — Floating point gotchas — catastrophic cancellation, associativity failure

3. Associativity failure


4. Common mistakes (steel-manned)


5. Recall

Recall Active recall — cover the answers
  • What's the relative-error amplifier in aba-b? → a+bab\dfrac{|a|+|b|}{|a-b|}.
  • Is float subtraction of near-equal numbers itself inaccurate? → No, it's exact; it just exposes prior error.
  • Why does (a+b)+ca+(b+c)(a+b)+c\neq a+(b+c)? → Each + rounds at a place that depends on the partial sum's magnitude.
  • Fix for the small quadratic root? → x=c/(ax+)x_- = c/(a x_+).
  • What does Kahan summation track? → The low-order bits lost in each addition.
Recall Feynman: explain to a 12-year-old

Imagine your calculator can only show 4 digits. Write 1234000012340000 and add 11 — the calculator still shows 1234000012340000, the 11 just fell off the edge. Now if two giant numbers are almost the same, like 1234000012340000 and 1234000012340000, and you subtract them, the calculator says 00 — but the real answer might have been a tiny number that got eaten earlier. So big-minus-big is dangerous: the answer is small but the mistakes are big. And 1+(huge)+(huge)1+\text{(huge)}+(-\text{huge}) can be 00 if you do it left-to-right but 11 if you cancel the huge ones first — the order of adding changes the answer!


Flashcards

What is machine epsilon for IEEE-754 double?
2522.22×10162^{-52}\approx 2.22\times10^{-16}, the gap between 1.01.0 and the next representable double.
State the floating rounding model.
fl(x)=x(1+δ)\text{fl}(x)=x(1+\delta) with δu=12εmach|\delta|\le u=\tfrac12\varepsilon_{\text{mach}}.
What is catastrophic cancellation?
Loss of significant digits when subtracting two nearly-equal numbers; small absolute errors become large relative errors.
Relative-error amplification factor for aba-b?
a+bab\dfrac{|a|+|b|}{|a-b|}, which blows up as aba\to b.
Is the subtraction step itself the source of error?
No — for near-equal operands it's exact (Sterbenz); it only reveals error already present in the operands.
Stable way to get the small root of x2+bx+cx^2+bx+c?
Compute the large-magnitude root, then use x2=c/(ax1)x_2=c/(a x_1) (product of roots).
Stable form of 1cosx1-\cos x near 0?
2sin2(x/2)2\sin^2(x/2).
Stable form of x+1x\sqrt{x+1}-\sqrt{x}?
1x+1+x\dfrac{1}{\sqrt{x+1}+\sqrt{x}}.
Why is float addition not associative?
Each + rounds at a place that depends on the running magnitude; different groupings round differently.
Give values where (a+b)+ca+(b+c)(a+b)+c\neq a+(b+c).
a=1,b=1016,c=1016a=1,b=10^{16},c=-10^{16} → gives 0 vs 1.
What error does naive summation of nn terms accumulate?
(n1)uxi\sim (n-1)\,u\sum|x_i|, growing with nn.
What does Kahan summation achieve and how?
Reduces sum error to u\sim u (independent of nn) by carrying the lost low-order bits in a compensation variable.
Why is 0.1+0.2==0.3 False?
None of those are exactly representable in binary; rounded sum differs from rounded 0.3 by 1017\sim10^{-17}.
Correct way to compare floats?
Tolerance test: abs(x-y) <= atol + rtol*max(|x|,|y|) (e.g. math.isclose).

Connections

Concept Map

keeps ~15-16 digits

defines

bounds

error is

scales with magnitude

revealed by subtraction

amplification factor

blows up when a approx b

each plus rounds

a+b +c not equal a+ b+c

classic case

fix by

Finite precision doubles

52-bit mantissa

Machine epsilon 2^-52

Rounding model fl x = x 1+delta

Relative error <= u

Absolute error grows with size

Catastrophic cancellation

a plus b over a minus b

Relative error explodes

Associativity failure

Order changes result

Quadratic formula loses precision

Rewrite formula to avoid subtraction

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, computer real numbers ko exactly store nahi kar sakta — har double ke paas sirf ~15-16 significant digits hote hain (machine epsilon 2.2×1016\approx 2.2\times10^{-16}). Normally itna kaafi hai, lekin do jagah dimaag kaam karna band kar deta hai. Pehla: catastrophic cancellation. Jab tum do bade aur lagbhag barabar numbers ko subtract karte ho, answer chhota nikalta hai par jo chhoti-chhoti errors pehle se chhupi thi, woh relative terms mein bahut bada ho jaati hai. Subtraction khud galat nahi karta — woh to exact hai — bas pehle se baked error ko expose kar deta hai. Amplification factor hota hai a+bab\frac{|a|+|b|}{|a-b|}, jo aba\approx b pe explode karta hai.

Iska fix? Formula ko rewrite karo taaki near-equal subtraction aaye hi na. Jaise quadratic formula mein chhoti root ke liye x2=c/(ax1)x_2 = c/(a x_1) use karo, ya 1cosx1-\cos x ki jagah 2sin2(x/2)2\sin^2(x/2). Yaad rakho: zyada precision (float128) ya zyada terms add karna problem solve nahi karega — asli problem expression ki conditioning hai, formula badalna padega.

Doosra gotcha: associativity failure. Maths mein (a+b)+c=a+(b+c)(a+b)+c = a+(b+c), par floats mein nahi! Kyunki har + apne aap round karta hai. Example: a=1a=1, b=1016b=10^{16}, c=1016c=-10^{16}. Left-to-right karo to 1+10161+10^{16} ka chhota 11 "gir" jaata hai (absorption), phir 1016-10^{16} se 00 milta hai. Par agar pehle b+c=0b+c=0 karo, phir +1+1, to answer 11 aata hai! Isliye lambi summation mein chhote numbers pehle add karo, ya Kahan summation use karo jo lost bits ko ek compensation variable mein track karta hai. Aur kabhi floats ko == se compare mat karo — tolerance (math.isclose) use karo.

Go deeper — visual, from zero

Test yourself — Scientific Computing (Python)

Connections