Javascript’s number type is based on the “IEEE 754” standard, in which it specifically uses its double-precision, 64-bit binary floating-point format.
This means that some numbers really can’t be trusted to be exact. An infamous example is:
0.1 + 0.2 === 0.3; // false
This equality test should have passed, but it didn't, because the binary floating point 0.1, and 0.2 are not exact (it's really close, though).
Comparing Small Decimal Values
If we need to run an equality test on small decimal values, we should use a very small number as the tolerance for comparison. If a number being tested is very close to this very small number, then we can safely assume that the number must be equal to each other. This very small number is commonly called machine epsilon. In javascript, this number represents 2^-52.
ES6 conveniently predefined this tolerance value as Number.EPSILON
.
Using Number.EPSILON
Since this value is predefined for us in ES6, we can now compare two numbers for 'equality'.
a = 0.1 + 0.2; // 0.30000000000000004
b = 0.3;
Math.abs( a - b ) < Number.EPSILON; // true
So what happened above? We compared the difference between a
and b
. If that difference was smaller than our machine epsilon, then we say that these two values are 'equal' (because it fell within the tolerance number).
Polyfill pre-ES6
A simple polyfill you can use if you're still not using ES6:
if (!Number.EPSILON) {
Number.EPSILON = Math.pow(2,-52);
}