Silverlight Tip of the Day #40: 1.05 != 1.05 - Peril with Floating Point Comparisons.
The other day I found a bug in one of my Silverlight applications that was doing floating point comparisons.
In my animation of an image I was increasing the ScaleTransform.ScaleX by “0.05” from “0.0” to “2.0 and checking to see when my ScaleTransform.ScaleX= “2.0”. The problem was it was never reaching exactly 2.0. Talking with my co-workers it turns out this is a side effect of parsing a float, the divide by 10 isn’t precise with a base 2 float representation. For example, looking in the debugger, when I set ScaleX = 1.05 the actual value turned out to be 1.0499999523162842.
Moral of the story: “Comparing floating point is fraught with peril. Do not rely on comparisons with floats or exact fuzzy with epsilon. That is, floating computation has errors so never do equal comparisons. Also, you should generally never introduce an epsilon and do a fuzzy comparison since it simply pushes your bugs to some other range of numbers you likely don’t test.”
Below is the wrong way to do it. This is an infinite loop since it never reaches exactly 2.0. In my debugger, it hit 1.9999991655349731 and then 2.0499992370605469.
scale.ScaleX = 0.0;
while (scale.ScaleX != 2.0)
{
scale.ScaleX += 0.05;
// Do stuff here...
}
Alternate way (compare to less than equal)
scale.ScaleX = 0.0;
while (scale.ScaleX < 2.0)
{
scale.ScaleX += 0.05;
// Do stuff here...
}
Thank you,
--Mike Snow
Subscribe in a reader