How to Use This Tool
Type any number. You get the exact value stored in memory, the bits, and how far it is from the number you meant.
The expansion always terminates
A double stores a binary fraction, and every binary fraction is a sum of powers of two, so its
decimal form is finite. It is just long. 0.1 is stored as exactly:
0.1000000000000000055511151231257827021181583404541015625
That is not an approximation of the stored value — it is the stored value, written
out. Your language prints 0.1 because it prints the shortest string that reads back to the
same double, which is a display convenience and not the number.
The example that actually changes how you code
0.1 + 0.2 is famous and inert. This one is not:
(1.005).toFixed(2) returns "1.00", not "1.01".
It looks like toFixed is broken. It is not. 1.005 cannot be stored
exactly, and the nearest double is 1.00499999999999989341858963598497211933135986328125
— genuinely below the halfway point. Rounding it down is correct. Every currency bug of the shape
“the total is a cent off” is some version of this.
It is not one unlucky number, either. 2.675 rounds to 2.67,
0.615 to 0.61 and 1.255 to 1.25, all for the same
reason: each is stored just below the value you typed. Try them in the box above and read the long
number.
What to do about it
- Money: use integers. Store cents, not pounds. Every language that gets currency right does this, and every one that does not has a rounding bug waiting.
- Comparison: use a tolerance.
Math.abs(a - b) < 1e-9rather thana === b. Pick the tolerance from the size of your numbers, not from a blog post. - Integers: watch 2⁵⁰. Above
Number.MAX_SAFE_INTEGER(9,007,199,254,740,991) consecutive integers are no longer all representable, so a 64-bit database ID loses digits silently in JSON. Send it as a string. - Accumulating: order matters. Adding a million small numbers to a large one loses more than adding the small ones together first.
This is not a JavaScript problem
It applies to double in C, Java, C#, Go, Rust, Swift and to Python's float
— all the same IEEE 754 binary64. Python's decimal, Java's BigDecimal
and similar types avoid it by storing decimal digits instead, at a cost in speed. JavaScript gets blamed
because it has no integer type to fall back on.
