I wrote a simple method to test this.

using System;

namespace round_test

{

class MainClass

{

public static void Main (string[] args)

{

double x = 0d;

while (x < 5d)

{

Console.WriteLine("actual: " + x.ToString());

Console.WriteLine("rounded: " + Math.Round(x).ToString());

x += 0.1d;

}

}

}

}

The output using mono wasn't very consistent. For instance, 2.5 -> 3 while the rest of the n.5 -> closest even number to n (4.5 -> 4, 3.5 -> 4). (full output here). Odd behaviour, bug??

EDIT: It seems there are two types of rounding, explained on MSDN. The default is banker's rounding.

It's not a bug, that kind of rounding is called Banker's Rounding

ReplyDeleteYes, after reading the MSDN article I understood what was up. It's still odd though they would pick that as the default. I wonder why that is...

ReplyDeleteIt reduces systematic rounding error in large calculations, because it is not biased toward rounding up. For similar reasons it's the default behavior for IEEE floating point (when one must round to a machine-representable number). -- Different anonymous poster.

ReplyDeleteDude, its not even just bankers rounding, its totally normal mathematical rounding. Just think of the numbers starting from .0 to .9, then .5 is actually closer to the next bigger number... if i have to spell it out: 0,1,2,3,4 = round down ; 5,6,7,8,9 round up... it does make sense... just think about it

ReplyDeleteAlso, when you are adding 0.1d, bear in mind that it can't be expressed as an exact floating point number (0.1 in decimal == 0.0001100110011... in binary). So it will be a number slightly less than 0.1 which you are adding. This should explain why 2.5 rounded to 3 - it wasn't actually 2.5.

ReplyDeleteWhen you are doing these things, increment by powers of two (like 0.5 or 0.25) so you don't get errors like this.

The article is confusing, I think because there is some information missing from the first sentence:

ReplyDelete"I had read on a forum somewhere that Math.Round() rounded to the closest even number."

I think what you mean is:

"...for cases where the floating point value ends with .5."

Yes, you are right.

ReplyDeletehttp://en.wikipedia.org/wiki/Rounding#Round_half_to_even

ReplyDeleteNot a bug. Fixing it would be.