Code Inspection: Compare of float numbers with equality operator
Using the
==
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
-4
using
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, i.e., a value to indicate by how
much the result can diverge from the intended value. Then, the comparison above can be rewritten, e.g., 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 (
float.Epsilon
,
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.
Please note that, in the majority of cases, the
Epsilon value is too low to be used as a reliable tolerance value.