#415 – Be Careful When Checking Floating Point Numbers for Equality

When you check two floating point numbers for equality in C#, you might sometimes be surprised at the result.

Consider the following example.  f2 is equal to six sixths (1.0), minus 1.0–which should be equal to 0.0.  But when we compare the result to 0.0, we see that the values are not equal.

            float f1 = 1.0f / 6.0f;
            float f2 = (f1 * 6.0f) - 1.0f;   // Should be 0.0
            float f3 = 0.0f;

            bool check = (f2 == f3);    // Should be true, but is false !

This happens because floating point numbers can’t necessarily be represented exactly when stored in a floating point variable.  Instead, the value stored can be very close, but not equal to, the desired value.

Here’s the output from the example above.  f2 should be equal to 0.0, after our calculation.  It is instead very nearly equal to 0.0.  Because of this, the comparison to the constant 0.0 fails.

About Sean
Software developer in the Twin Cities area, passionate about software development and sailing.

2 Responses to #415 – Be Careful When Checking Floating Point Numbers for Equality

  1. myspec says:

    couldn’t we just use doubles or decimals here? wouldn’t it fix the problem?

    • Sean says:

      No, it won’t necessarily fix the problem. Doubles give you greater precision, which just means the that error in your calculations will be somewhat smaller. But the fundamental truth is the same–a floating point number can’t necessarily be represented exactly.

      Note the same problem using doubles when doing the following:

      double d1 = 12.14;
      double d2 = 12.13;
      double d3 = d1 – d2; // Should be 0.01

      bool check = (d3 == 0.01); // should be true

      In the above code, d3 is not 0.01, as expected, but a bit less. So if you compare it to the constant 0.01, the test will fail. Instead, when comparing floating point numbers, whether float or double, you should subtract them and compare against a small epsilon. I.e. Is the result close enough to what we are expecting?

Leave a comment