Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does System.MidpointRounding.AwayFromZero not round up in this instance?

Tags:

c#

.net

In .NET, why does System.Math.Round(1.035, 2, MidpointRounding.AwayFromZero) yield 1.03 instead of 1.04? I feel like the answer to my question lies in the section labeled "Note to Callers" at http://msdn.microsoft.com/en-us/library/ef48waz8.aspx, but I'm unable to wrap my head around the explanation.

like image 582
John W Avatar asked Feb 10 '12 00:02

John W


People also ask

What is MidpointRounding AwayFromZero?

AwayFromZero. 1. The strategy of rounding to the nearest number, and when a number is halfway between two others, it's rounded toward the nearest number that's away from zero. ToEven.

What is Mid point rounding?

Midpoint values are rounded to the next number away from zero. For example, 3.75 rounds to 3.8, 3.85 rounds to 3.9, -3.75 rounds to -3.8, and -3.85 rounds to -3.9. This form of rounding is represented by the MidpointRounding.

When a number is halfway between two others it is rounded toward the nearest number that is away from zero?

According to MSDN on MidpointRounding: When a number is halfway between two others, it is rounded toward the nearest number that is away from zero. In your case, 1299.492 is not halfway between 1229.49 and 1299.50, so MidpointRounding. AwayFromZero doesn't even apply.


1 Answers

Your suspicion is exactly right. Numbers with fractional portion, when expressed as literals in .NET, are by default doubles. A double (like a float) is an approximation of a decimal value, not a precise decimal value. It is the closest value that can be expressed in base-2 (binary). In this case, the approximation is ever so vanishingly on the small side of 1.035. If you write it using an explicit Decimal it works as you expect:

Console.WriteLine(Math.Round(1.035m, 2, MidpointRounding.AwayFromZero)); Console.ReadKey(); 

To understand why doubles and floats work the way they do, imagine representing the number 1/3 in decimal (or binary, which suffers from the same problem). You can't- it translates to .3333333...., meaning that to represent it accurately would require an infinite amount of memory.

Computers get around this using approximations. I'd explain precisely how, but I'd probably get it wrong. You can read all about it here though: http://en.wikipedia.org/wiki/IEEE_754-1985

like image 190
Chris Shain Avatar answered Sep 28 '22 10:09

Chris Shain