Having recently been subject to a number of rounding issues in an application, we've had to take a closer look at how rounding works in the .Net framework.

It seams that when using Math.Round(), there is an overload that allows us to specify the type of rounding that is used in the form of the MidpointRounding enumeration.

 

As the Microsoft documentation will tell you, there are two possible values we can choose from:

  • ToEven: Round to the nearest even number.
  • AwayFromZero: Round to the nearest number away from zero.

This proves to be quite interesting when you start thinking about it in a little more detail.  I was generally taught at school that you usually round up to the nearest number so that 0.5 becomes 1, -4.5 becomes for and so on.  This is not the case in .Net it would seem and I find it a little surprising that it has taken me this long to notice.

If you write a little console application in Visual Studio, you can take a look at how this works:

            Console.WriteLine(
                "Value   Default   Even   FromZero"
                );
            for (decimal myValue = -2.0M; myValue < 2.0M; myValue += 0.1M)
            {
                Console.WriteLine(String.Empty.PadLeft(35,'-'));
                Console.WriteLine(
                    "{0}   {1}   {2}   {3}",
                    myValue.ToString("0.0").PadLeft(5),
                    Math.Round(myValue, 0).ToString("00").PadLeft(7),
                    Math.Round(myValue, 0, MidpointRounding.AwayFromZero).ToString("00").PadLeft(4),
                    Math.Round(myValue, 0, MidpointRounding.ToEven).ToString("00").PadLeft(8)
                    );
            }

The following table give you an idea of how these work for some values.

Value Round to Even Round Away from Zero
0.4 0 0
0.5 0 1
1.4 1 1
1.5 2 2

 

The interesting point is that the default value for Math.Round when not specified is ToEven which is not really what I would have expected.  I was also a little intrigued to find that there is not provision of a TowardsZero value.  Having a look at Wikipedia, there are numerous methods of rounding and they give a handy list of which languages make which preference.  .Net favors what Wikipedia calls 'Round-half-even', which is MidpointRounding.RoundToEven.  It's sometimes refereed to as Banker's Rounding.

This clearly is not a massive revelation, but when you start to deal with systems that need to perform calculations and correlate the results of those calculations with other, less-precise systems you should take note of how you will be rounding as checking this out early can prevent headaches later.


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist
posted @ Wednesday, December 17, 2008 12:41 PM | in .Net Framework

Comments

No comments posted yet.

Post Comment

Title *
Name *
Email
Url
Comment *  


Please add 8 and 4 and type the answer here: