I’ve been playing around with floating point numbers a little bit, and based on what I’ve learned about them in the past, the fact that 0.1 + 0.2 ends up being something like 0.30000000000000004 doesn’t surprise me.
What does surprise me, however, is that integer arithmetic always seems to work just fine and not have any of these artifacts.
I first noticed this in JavaScript (Chrome V8 in node.js):
0.1 + 0.2 == 0.3 // false, NOT surprising
123456789012 + 18 == 123456789030 // true
22334455667788 + 998877665544 == 23333333333332 // true
1048576 / 1024 == 1024 // true
C++ (gcc on Mac OS X) seems to have the same properties.
The net result seems to be that integer numbers just — for lack of a better word — work. It’s only when I start using decimal numbers that things get wonky.
Is this is a feature of the design, an mathematical artifact, or some optimisation done by compilers and runtime environments?
I’m writing that under assumption that Javascript uses double-precision floating-point representation for all numbers.
Some numbers have an exact representation in the floating-point format, in particular, all integers such that
|x| < 2^53. Some numbers don’t, in particular, fractions such as 0.1 or 0.2 which become infinite fractions in binary representation.If all operands and the result of an operation have an exact representation, then it would be safe to compare the result using
==.Related questions:
What number in binary can only be represented as an approximation?
Why can’t decimal numbers be represented exactly in binary?