Tuesday, February 22, 2011

Math.Round in .NET is buggy!

I was trying a piece of code and I was amazed to see that Math.Round(4.5) results to 4! 1.5 leads to 2, 2.5 leads also to 2, 3.5 leads to 4, as does 4.5. According to the MSDN documentation on Math.Round, The behavior of this method follows IEEE Standard 754, section 4. This kind of rounding is sometimes called rounding to nearest, or banker's rounding. It minimizes rounding errors that result from consistently rounding a midpoint value in a single direction. To control the type of rounding used by the Round method, call the Math.Round(Double, MidpointRounding) overload. That's nice and everything, but it contradicts the description of the method on the same page: Rounds a double-precision floating-point value to the nearest integral value. It also contradicts the behaviour of Javascript's Math.round in Microsoft's browser Internet Explorer.

The solution for this is to use the overload Math.Round(value,MidpointRounding.AwayFromZero). Math.Round(4.5,MidpointRounding.AwayFromZero) equals 5. If you don't know that, like I did after 5 years of .Net, you are pretty much screwed. So be wary of helpful mathematical functions.