···1212 b = 0.15 + 0.15
1313 if(a == b) // can be false!
14141515+Don't use absolute error margins
1616+--------------------------------
1517The solution is to check not whether the numbers are exactly the same, but whether their difference is
1618very small. The error margin that the difference is compared to is often called *epsilon*.
1719The most simple form:
···2426Therefore, it is necessary to see whether the *relative error* is smaller than epsilon:
25272628 if( Math.abs((a-b)/b) < 0.00001 ) // still not right!
2727-2828-There is one important special case where this will fail: When both a and be are zero. 0.0/0.0 is "not a number", which returns false for all comparisons. So we have to take care of that first:
29293030- if( a==b || Math.abs((a-b)/b) < 0.00001 ) // more correct, but bad design
3030+Look out for edge cases
3131+-----------------------
3232+There are some important special cases where this will fail:
31333232-Since it's not immediately clear what this code does, it should be done in a function or method:
3434+* When both `a` and `b` are zero. `0.0/0.0` is "not a number", which returns false for all comparisons.
3535+* When only `b` is zero, the division yields "infinity", which is greater than epsilon even when `a` is smaller.
3636+3737+Also, the result is not commutative (`nearlyEquals(a,b)` is not always the same as `nearlyEquals(b,a)`). To fix these problems, the code has to get a lot more complex, so we really need to put it into a function of its own:
33383439 function nearlyEqual(a,b)
3540 {
3636- return a==b || Math.abs((a-b)/b) < 0.00001;
4141+ epsilon = 0.00001;
4242+ if (a==0.0){
4343+ return Math.abs(b) < epsilon;
4444+ else if (b==0.0){
4545+ return Math.abs(a) < epsilon;
4646+ } else { // ensure commutativity
4747+ return Math.abs((a-b)/a) < epsilon &&
4848+ Math.abs((b-a)/b) < epsilon;
4949+ }
3750 }
38513952 if(nearlyEqual(a,b))
40534141-This is still not a perfect solution. Read the [Comparing floating-point numbers](/references/) paper for more details.5454+Unfortunately, this is *still* not perfect; there are at least two problems that are not easy to fix:
5555+5656+* It reverts to using epsilon as an absolute error measure when `a` or `b` is zero.
5757+* It returns `false` when both `a` and `b` are very small but on opposite sides of zero, even when they're the smallest possible non-zero numbers.
5858+5959+Compare floating-point values as integers
6060+-----------------------------------------
6161+But the there is an alternative to adding even more conceptual complexity to such an apparently simple task: instead of comparing `a` and `b` as [real numbers](http://en.wikipedia.org/wiki/Real_numbers), we can think about them as discrete steps and define the error margin as the maximum number of possible floating-point values between the two values.
6262+6363+This is conceptually very clear and easy and has the advantage of implicitly scaling the relative error margin with the magnitude of the values. Technically, it's a bit more complex, but not as much as you might think, because IEEE 754 floats are designed to maintain their order when their bit patters are interpreted as integers.
6464+6565+However, this method does require the programming language to support conversion between floating-point values and integer bit patters. Read the [Comparing floating-point numbers](/references/) paper for more details.