Why 0.1 + 0.2 ≠ 0.3
Micro-lessons
Type 0.1 + 0.2 into any language and you get 0.30000000000000004. It’s not a bug in the language — it’s that 0.1 has no exact binary form, and the rounding doesn’t cancel.
The number line, in base 2
A binary fraction can only land on sums of ½, ¼, ⅛, …. One-tenth isn’t such a sum — in binary it’s 0.0001100110011…, repeating forever, exactly the way ⅓ = 0.333… never terminates in decimal. A double has room for 52 mantissa bits, so it stops and rounds to the nearest representable value.
Decode it yourself
Every double is a sign bit, an 11-bit exponent, and a 52-bit mantissa. Here’s the exact value each bit pattern really stores — click a preset or type your own:
- sign
- 0 (+)
- exponent
- 1019 → 2-4
- mantissa
- 1 + 2702159776422298/252
0.1000000000000000055511151231257827021181583404541015625You typed 0.1, but that isn’t representable in binary — it’s rounded to the nearest double, shown above.The two results are adjacent doubles — exactly one ULP apart, the smallest step floating point can take (a single ULP step still flips several bits through the mantissa’s carry chain; the differing bits are highlighted). 0.1 + 0.2 lands one ULP above the double nearest 0.3, so 0.1 + 0.2 === 0.3 is false, and the printed value is 0.30000000000000004.
0.1 rounds to a double a hair above 0.1; 0.2 rounds to one a hair above 0.2. Their exact sum then has to round again to fit 52 bits — and it lands on the double one step past the one nearest 0.3. Three roundings, none of them cancelling. The gap is one ULP ≈ 2⁻⁵² of the value.
What to do about it
Never test floating-point numbers with ==. Compare with a tolerance — |x − y| < ε — sized to the magnitudes involved. For exact money, don’t use doubles at all: count integer cents, or a decimal type. The machine epsilon that bounds a single rounding is 2⁻⁵² ≈ 2.2 × 10⁻¹⁶, which is why doubles still give you about 15–16 honest decimal digits.
Say it, don’t just nod
Of ½, ⅜, 0.1, and 0.25 — which are stored exactly as a double?
A fraction is exact in binary floating point exactly when its reduced denominator is a power of two. ½, ⅜ = 3/2³, and 0.25 = 1/4 all qualify — stored perfectly.
0.1 = 1/10 does not: 10 = 2 · 5, and that factor of 5 can never be cleared by powers of two. So 0.1 is the one that rounds — decode it above and you’ll see the endless tail.