I have been working with the Microsoft .NET framework for a while. The other day I learned something new. I was using the Math.Round method, and I noticed that it was not working the way that I expected. Here is what I mean. I had a value of .3650, and I was rounding it to two decimal places Math.Round(.3650,2). I was expecting the result to round up to .37, but instead it rounded down to .36. What's going on?
After some research, I found that the Math.Round method in .NET, by default, follows the round-to-even rule or bankers rounding. From MortgageLoanCalculating.com:
“In grade school most of us learned that when the remainder at the rounding position is .5 or above we round up and if less than .5 we round down. When dealing with small amounts of data, this rounding method does not present a problem. However, when working with large sets of numbers, this rounding method produces results that will be skewed upwards. To address this problem, a new rounding method, sans the asymmetrical frequency distribution, was developed.
“With the round-to-even rule, when the remainder at the rounding position is .5, that number is rounded up when the number before it is odd, and rounded down when the number before it is even. For example, the number 6.5, using the round-to-even rule, would round down to the even number 6.0, while the number 7.5 would round up to the even number 8.0 -- hence the name round-to-even rule. The round-to-even rule is also referred to as bankers rounding because, not surprisingly, this rounding method is often used by bankers.”
So in my case with Math.Round(.3650,2), since the number before .50 was even, 6, it rounded down to .36. Not what I wanted. The fix, the Math.Round method comes with an overload that takes a MidpointRounding value.
Using the overload Math.Round(.3650,2,MidPointRounding.AwayFromZero), my code returned .37, which was what I wanted.
Why does the Math.Round method default to the round-to-even rule or bankers rounding? Apparently, it is following the IEEE 754 standard.
I also tried rounding .3650 to two decimal places using the T-SQL and Excel rounding functions. In both cases, the result was .37.
Below are links I used to gather my information.
http://msdn.microsoft.com/en-us/library/System.Math.Round(v=vs.110).aspx#Round3_Example
http://stackoverflow.com/questions/977796/why-does-math-round2-5-return-2-instead-of-3-in-c