JetBrains Rider 2024.1 Help

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, and

  • multiply 0.1 by 11

— and check whether their floating-point results are equal:

double add = 0; for (int i = 1; i <= 11; i++) { add += 0.1; } double multiply = 0.1 * 11; Console.WriteLine(add == multiply); // false

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:

double add = 0; for (int i = 1; i <= 11; i++) { add += 0.1; } double multiply = 0.1 * 11; var tolerance = 0.000000001; Console.WriteLine(Math.Abs(add - multiply) < tolerance); // true

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.

Last modified: 11 February 2024