https://www.youtube.com/watch?v=MFq97zUZvTs
Every programmer hits it eventually. You type 0.1 + 0.2 and get 0.30000000000000004. Not 0.3. Not in Python, not in JavaScript, not in any language. This isn't a bug — it's IEEE 754 working exactly as designed.
Why 0.1 Can't Be Stored Exactly
You already know that 1/3 in decimal is 0.333... — it repeats forever. Binary has the same problem, just with different numbers.
In base 2, you can only represent fractions built from powers of two: 1/2, 1/4, 1/8. But 1/10? Its denominator has a factor of 5, and binary can't express 5. So 0.1 in binary becomes 0.000110011001100110011... — repeating forever. The computer has to stop somewhere, and the stored value is 0.1000000000000000055511151231257827021181583404541015625. Close. Not exact.
How IEEE 754 Stores Numbers
The standard uses 64 bits split into three parts:
- 1 bit for the sign (positive or negative)
- 11 bits for the exponent (the scale — which power-of-two window)
- 52 bits for the mantissa (where exactly inside that window)
Think of it like scientific notation in binary: 1.something × 2^power.
The key insight: the exponent picks a window (between 1 and 2, between 2 and 4, etc.), and the mantissa divides that window into 4.5 quadrillion evenly spaced slots. Between 1 and 2, that's incredibly precise. Between 1,000,000 and 2,000,000? Same number of slots spread across a million times more space. Each slot is now 128 apart. Precision degrades with magnitude.
The Tiebreaker That Creates 0.30000000000000004
When you add the stored values of 0.1 and 0.2, the true sum lands exactly between two representable values: 0.3 and 0.30000000000000004. IEEE 754's tiebreaker rule — round to even — picks the one whose last significant bit is even. That's 0.30000000000000004.
Not a bug. Not an approximation error. The standard picked the only correct choice.
Real Disasters
In 1991, a Patriot missile battery tracked an incoming Scud using a clock that counted in tenths of a second. But 0.1 can't be stored exactly. After 100 hours, the error grew to 0.34 seconds — enough to miss the Scud by 687 meters. 28 soldiers died.
Twitter's post IDs are 64-bit integers, but JavaScript stores all numbers as 64-bit floats (max safe integer: 2^53). Large Twitter IDs silently lose their last digits. The number you get back isn't the number they sent.
Working With Floats Safely
→ Never compare with ==. Check if the difference is smaller than a threshold (like 1e-9).
→ For money, store cents as integers.
→ For exact decimal math, use a decimal library.
Floating point isn't broken. It's a brilliantly engineered tradeoff between range, precision, and speed. But it only works if you know the rules.
Watch the full animated breakdown: Why Every Computer Gets This Wrong
Top comments (0)