Claude Sonnet 5.5
Why 0.1 + 0.2 !== 0.3
The cause
JavaScript numbers are IEEE 754 double-precision binary floating-point values. Computers store them in base 2, and just as 1/3 can't be written exactly in decimal (0.3333…), values like 0.1 and 0.2 can't be written exactly in binary. They become repeating fractions that get rounded to the nearest representable value.
0.1 + 0.2; // 0.30000000000000004
0.1 + 0.2 === 0.3; // falseYou can see the hidden error with toPrecision:
(0.1).toPrecision(20); // "0.10000000000000000555"
(0.2).toPrecision(20); // "0.20000000000000001110"
(0.3).toPrecision(20); // "0.29999999999999998890"The sum of the two stored approximations lands on a different double than the one nearest to 0.3, so the strict comparison fails. This isn't a JavaScript bug. Python, Java, C, and most other languages behave the same way.
How to compare instead
1. Epsilon comparison (most common)
Check whether the numbers are close enough:
function nearlyEqual(a, b, epsilon = Number.EPSILON) {
return Math.abs(a - b) < epsilon;
}
nearlyEqual(0.1 + 0.2, 0.3); // trueNumber.EPSILON (≈ 2.22e-16) is the gap between 1 and the next representable double. It works well for values near 1, but it's too small for large numbers and too large for tiny ones. For a more robust approach, use a relative tolerance:
function nearlyEqual(a, b, relTol = 1e-9, absTol = 1e-12) {
return Math.abs(a - b) <= Math.max(relTol * Math.max(Math.abs(a), Math.abs(b)), absTol);
}2. Use integers for money or fixed precision
Work in the smallest unit (e.g. cents) so arithmetic is exact:
const total = 10 + 20; // 10 cents + 20 cents
total === 30; // true
(total / 100).toFixed(2); // "0.30" for display3. Round before comparing
Math.round((0.1 + 0.2) * 100) / 100 === 0.3; // true
// or
+(0.1 + 0.2).toFixed(2) === 0.3; // trueThis is fine for display or when you know the precision you need, but it's less general than a tolerance check.
4. Use a decimal library
For financial or scientific code that needs exact decimal behavior, use a library such as decimal.js, big.js, or bignumber.js:
import Decimal from 'decimal.js';
new Decimal(0.1).plus(0.2).equals(0.3); // trueFor integers beyond 2^53, use native BigInt.
Quick guidance
| Situation | Approach |
|---|---|
| General floating-point math | Tolerance comparison |
| Currency | Integers (cents) or a decimal library |
| Display only | toFixed() / Intl.NumberFormat |
| Arbitrary precision | decimal.js / big.js |
Rule of thumb: never use === on the results of floating-point arithmetic unless you know the values are exactly representable (like integers or powers of two such as 0.5 and 0.25).