## 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.

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();

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.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();

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

Correction: The title of the article is "What Every Computer Scientist Should Know About Floating-Point Arithmetic"

Reply to this