Learning Objectives
By the end of this lesson you will be able to:
- Explain in simple terms why 0.1 cannot be stored exactly in binary
- Describe the IEEE 754 double precision format (64-bit float)
- Predict which types of calculations are most vulnerable to floating-point error
The Binary Fraction Problem
Humans count in base 10 (decimal). Computers count in base 2 (binary).
In decimal, 1/3 = 0.333... — an infinite repeating decimal. We accept this and round when needed.
In binary, 1/10 (0.1) = 0.000110011001100... — an infinite repeating binary fraction. The computer must round this to fit in the available bits, storing an approximation: approximately 0.1000000000000000055511151231257827021181583404541015625.
This is not a bug. It's the mathematical reality of representing base-10 fractions in base-2.
IEEE 754 Double Precision
A 64-bit floating-point number (Java double, JavaScript number) has:
- 1 sign bit
- 11 exponent bits (range: roughly 10^-308 to 10^308)
- 52 mantissa bits (~15-17 significant decimal digits of precision)
The consequence: any calculation involving fractions may accumulate tiny rounding errors.
The Famous Example
0.1 + 0.2 = 0.30000000000000004
0.1 + 0.2 === 0.3 // false in JavaScript, Python, Java...
This is not a bug in the specific language. It reproduces in every IEEE 754 language because they all use the same binary representation.
When Floating-Point Error Matters
For most applications, the error (about 10^-17 for this example) is negligibly small. But it matters when:
- Financial calculations: Accumulating floating-point errors over thousands of transactions compounds into visible penny discrepancies
- Equality checks:
if (price == 0.10)will fail ifpricewas computed (not assigned) as 0.1 - Sorting/comparison: Items that should sort equal may sort differently due to accumulated error
- Rounding at scale: Rounding 0.30000000000000004 is different from rounding 0.3
The Correct Approach
- For money: Use integer arithmetic (store cents as integers, not dollars as floats) or
BigDecimal - For comparisons: Use epsilon comparison:
Math.abs(a - b) < 0.000001rather thana == b - For display: Round to the appropriate number of decimal places before showing to users
Pro Tip: If a financial system shows you a price like $15.999999999997 instead of $16.00, that's almost certainly accumulated floating-point error. It's a bug worth filing — the system should use appropriate numeric types.
Key Takeaways
- 0.1 cannot be stored exactly in binary IEEE 754 — it's stored as an approximation
- This affects all IEEE 754 languages: Java, Python, JavaScript, C#, Go, etc.
- Floating-point errors matter most in financial calculations, equality comparisons, and accumulated operations
- Use integer arithmetic or BigDecimal for money; epsilon comparison instead of exact equality