Today I was trudging through some old code and came across a (nasty-looking) line of code like this:
// OMG this is nasty!
price = Convert.ToDecimal(Convert.ToDouble(price.ToString("#######.##")));
I thought, “What the hell is going on here?!”. This was inside a two-case switch statement (which is also totally retarded) and the second case had this type of logic in it:
price = Math.Round(price + 0.005, 2);
So I decided to do a little testing (using the awesomeness that is LINQPad) with this curious rounding code. Running this through LINQPad produces interesting output:
void Main()
{
12.365.ToString("#######.##").Dump();
12.375.ToString("#######.##").Dump();
12.385.ToString("#######.##").Dump();
"----------------------".Dump();
Math.Round(12.365, 2).Dump();
Math.Round(12.375, 2).Dump();
Math.Round(12.385, 2).Dump();
}
Output:
12.37 12.38 12.39 ---------------------- 12.36 12.38 12.38
The .NET Math.Round actually does not do “engineering” rounding… it does “bankers’” rounding. Here is how “bankers’” rounding works: If the next-to-last digit of the number you’re rounding is an even number, you round up. If it is an odd number, you round down. So 12.365 rounds up to 12.37… and 12.375 rounds down to 12.37. Crazy huh! Gotta love those bankers trying to hold onto their precious pennies!
The other odd-looking rounding using the ToString method actually give you “engineering” rounding… or simply “normal” rounding. What a PITA!
On a tangential thought, it appears that Math.Truncate and Math.Floor have identical results.
You’ve been warned!











November 11th, 2009 7:56 pm
Right, what you’re looking for is Math.Round(134.567, 2, MidpointRounding.AwayFromZero);
Also, Truncate and Floor are only equal for positive numbers. Floor will return the lesser integer while Truncate returns the greater one for negative decimal values, because the integral part of a negative is greater than the Floor of that same number if it has digits after the decimal point.
The MidpointRounding.AwayFromZero gives you engineering Round functionality. Please don’t use ToString() to do mathematical rounding in your calculations.
November 13th, 2009 8:46 am
Todd,
That’s some great information… thank you! I don’t deal with rounding much but it’s great to have the “goods” when you need them.
- Wil