Compare floating-point values safely in C#

The computer stores values in binary using 0s and 1s. That means it cannot store all possible decimal values exactly. Sometimes when you multiply or divide two floating-point values, the computer may be unable to store the result exactly.

Usually this is no big deal, but you should be aware that this can happen. In particular, when you compare two values to see if they are equal, you cannot simply use == to compare them. Instead, subtract them and see if the result is close to 0.

For example, consider the following calculation.

float A = 5.7f;
float B = 12f;
float A_times_B = A * B;
txtAtimesB.Text = A_times_B.ToString();

The value A_times_B should be 68.4 but, due to the way the computer stores floating-point values, the result is not exact. If a program uses == to compare the result to 68.4, the result is false.

Instead you should subtract the result from the value 68.4 and see if the difference is (in absolute value) close to 0.

This example uses the following code to demonstrate this technique.

float A = 5.7f;
float B = 12f;
float A_times_B = A * B;
txtAtimesB.Text = A_times_B.ToString();

bool equals1 = (A_times_B == 68.4f);
txtEquals1.Text = equals1.ToString();

bool equals2 = Math.Abs(A_times_B - 68.4f) < 0.00001;
txtEquals2.Text = equals2.ToString();

If you look at the picture at the beginning of the post, you'll see that the computer displays the product as 68.39999 instead of 68.4. (Even this may be slightly different from the way the computer stores the value internally. This is just the decimal representation of the binary value stored by the computer.)

The picture shows that the == test decided that the result was not equal to 68.4. The test Math.Abs(A_times_B - 68.4f) < 0.00001 correctly determined that the product was close to 68.4.

How close the difference must be to 0 depends on the calculation. In this example, 0.00001 works. If you perform a long series of calculations, rounding errors may accumulate and the result may be farther from what you expect it to be so you may need to use another value such as 0.001.

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments

  • 7/26/2013 4:11 PM Carl D wrote:
    While I don't disagree with the advice, I do disagree with the title: this is not about safety, it's about correctness. The quintessential article on this topic is "What every software engineer should know about floating point arithmetic" published in 1991 by David Goldberg. Google it. Read it.
    Reply to this
    1. 7/30/2013 2:32 PM Carl D wrote:
      Correction: The title of the article is "What Every Computer Scientist Should Know About Floating-Point Arithmetic"
      Reply to this
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.