For those of you who have been around since the VB6 days, you surely remember the interesting rounding behavior of CInt(x). Specifically, it rounded a number ending in .5 to the nearest even number. That is, CInt(2.5) rounded to 2 and CInt(3.5) rounded to 4.
This behavior still exists in VB.NET. No real surprise there. And, to be honest, I don’t mind it that much. When I see “CInt,” I really don’t have any preconceived, intuitive understanding of what it does.
Math.Round(x) is another question entirely. I expect it to… well, round. The way I expect. The way were all taught in second grade. Point-five and bigger rounds up; smaller than point-five rounds down. Every time. Not rounding up sometimes, rounding down other times.
But, after that rant, you’re not going to be surprised when I tell you that Math.Round behaves just like CInt by default.
Want proof? Just see what this code outputs:
Console.WriteLine(Math.Round(1.5))
Console.WriteLine(Math.Round(2.5))
Console.WriteLine(Math.Round(3.5))
Console.WriteLine(Math.Round(4.5))
There is an easy way to make this code work more intuitively. This code yields the results you’d expect:
Console.WriteLine(Math.Round(1.5, MidpointRounding.AwayFromZero))
Console.WriteLine(Math.Round(2.5, MidpointRounding.AwayFromZero))
Console.WriteLine(Math.Round(3.5, MidpointRounding.AwayFromZero))
Console.WriteLine(Math.Round(4.5, MidpointRounding.AwayFromZero))
The insidious thing about this problem is that you often have to create very specific test cases to uncover this issue. It’s particularly nasty, since the actual behavior differs very slightly from the intuitive behavior.
You’ve been warned.