Code Inspection: Equality comparison of floating point numbers
== operator to compare floating-point numbers is, generally, a bad idea. The problem arises from the fact that, typically, results of calculations have to be ‘fitted’ into floating-point representation, which does not always match the perceived reality of what result should be produced.
For example, suppose you take a root of
var root = Complex.Sqrt(new Complex(-4, 0)). Then, you decide to ensure that the real part of the result is
0 (zero), by asserting that
root.Real == 0.0. Unfortunately, the actual result of the calculation is (1.22460635382238E-16, 2), so the comparison will, predictably, fail.
In order to do these comparisons correctly, you need to specify a tolerance, that is, a value to indicate by how much the result can diverge from the intended value. Then, the comparison above can be rewritten, for example, as
Math.Abs(root.Real)< 1.E-10. Similarly, comparisons between two values can take the form of
Math.Abs(x - y)< tolerance. The tolerance value really depends on the precision of the calculations being performed but, in most cases, should be at least the
Epsilon value (
double.Epsilon, and so on). The
Epsilon is a constant that denotes the smallest non-zero value that can be represented with the type of floating number you are using. Note that, in the majority of cases, the
Epsilon value is too low to be used as a reliable tolerance value.