I just read on MDN that one of the quirks of JS\'s handling of numbers due to everything being \"double-precision 64-bit format IEEE 754 values\" is that when you d
Understanding rounding errors in floating point arithmetic is not for the faint-hearted! Basically, calculations are done as though there were infinity bits of precision available. The result is then rounded according to rules laid down in the relevant IEEE specifications.
This rounding can throw up some funky answers:
Math.floor(Math.log(1000000000) / Math.LN10) == 8 // true
This an an entire order of magnitude out. That's some rounding error!
For any floating point architecture, there is a number that represents the smallest interval between distinguishable numbers. It is called EPSILON.
It will be a part of the EcmaScript standard in the near future. In the meantime, you can calculate it as follows:
function epsilon() {
if ("EPSILON" in Number) {
return Number.EPSILON;
}
var eps = 1.0;
// Halve epsilon until we can no longer distinguish
// 1 + (eps / 2) from 1
do {
eps /= 2.0;
}
while (1.0 + (eps / 2.0) != 1.0);
return eps;
}
You can then use it, something like this:
function numericallyEquivalent(n, m) {
var delta = Math.abs(n - m);
return (delta < epsilon());
}
Or, since rounding errors can accumulate alarmingly, you may want to use delta / 2 or delta * delta rather than delta.