Numeric Chicanery

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.

Print | posted @ Thursday, April 02, 2009 11:37 AM

Comments on this entry:

Gravatar # re: Numeric Chicanery
by bystander at 4/8/2009 1:18 PM

But the intuitive behavior introduces a bias when you do lots of calculations. The default behavior does not and hence is better suited to numerical algorithms. It's called the Banker Rounding by the way.
Gravatar # re: Numeric Chicanery
by Jeff Certain at 4/8/2009 1:33 PM

Fair enough. We tend to deal with fairly large numbers (in excess of a thousand dollars) so rounding up to the nearest penny instead of using bankers' rounding really isn't going to introduce a statistically meaningful bias.

If you're dealing with large sets of fairly small numbers, I can see why you'd be concerned. Thanks for pointing out the gap in the conversation!
Gravatar # re: Numeric Chicanery
by Jeff Certain at 4/8/2009 1:34 PM

I meant to include this link: http://en.wikipedia.org/wiki/Banker%27s_rounding#Round-to-even_method
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: