Code Inspection: Equality comparison of floating point numbers
Using the ==
/!=
operators to compare floating-point numbers is, generally, a bad idea. Floating point values are inherently inaccurate, and comparing them for exact equality is almost never the desired semantics. Comparison via the ==
/!=
operators checks floating-point value representation to be exactly the same, which is very unlikely if you perform any arithmetic operations involving precision loss. For example, let's perform two simple arithmetic operations —
add
0.1
11
times, andmultiply
0.1
by11
— and check whether their floating-point results are equal:
In a test run, we get add = 1.0999999999999999
and multiply = 1.1000000000000001
(although different runtimes can render different results), so the ==
operator evaluates the comparison to false
.
To do this kind of comparison correctly, we need to specify a tolerance, that is, a value to indicate by how much the result can diverge from the intended value. JetBrains Rider helps us automatically rewrite the comparison as Math.Abs([expression]) < [tolerance]
. The tolerance
value depends on the precision of the calculations you perform. In our example, we can safely rely on a tolerance of 0.000000001
:
Note that this inspection ignores some values that are often used as "marker values", like 0
, +Infinity
, -Infinity
, NaN
to represent "not yet initialized value" or "value is absent" when non-zero values are otherwise expected.
However, a better way to do that would be the double?
type with the null
value.