
February 8th, 2012, 06:24 PM
#1
Basic Question about Math.Round and {0:C}
I'm just running through a C# book and had a question, In my visual studio 2010 I put this code in:
double inflation = .04, initialCost = 1.00, finalCost = 0, cost = 0, years = 3;
cost = initialCost * inflation + initialCost;
cost = cost * inflation + cost;
finalCost = cost * inflation + cost;
finalCost = Math.Round(finalCost, 3);
Console.WriteLine("In {0} years the item will cost {1:C} with a starting cost of {2:C} and an inflation rate of {3} ", years,finalCost, initialCost, inflation);
My question: With the" finalCost = Math.Round(finalCost, 3);" my output for finalCost is 1.13 but if I comment it out I get 1.12 output for finalCost.
Can someone tell me why this is and if I'm missing something?

February 8th, 2012, 06:41 PM
#2
Re: Basic Question about Math.Round and {0:C}
Here is it properly formatted with the tags
I'm just running through a C# book and had a question, In my visual studio 2010 .NET 4 I run this code in:
Code:
double inflation = .04, initialCost = 1.00, finalCost = 0, cost = 0, years = 3;
cost = initialCost * inflation + initialCost;
cost = cost * inflation + cost;
finalCost = cost * inflation + cost;
finalCost = Math.Round(finalCost, 3);
Console.WriteLine("In {0} years the item will cost {1:C} with a starting cost of {2:C} and an inflation rate of {3} ", years,finalCost, initialCost, inflation);
My question: With the" finalCost = Math.Round(finalCost, 3);" my output for finalCost is 1.13 but if I comment it out I get 1.12 output for finalCost.
Can someone tell me why this is and if I'm missing something?

February 8th, 2012, 07:56 PM
#3
Re: Basic Question about Math.Round and {0:C}
The actual value of finalCost is 1.125.
The rules of Mathematics (and therefore the Round() function) say that, when rounding to N decimal places, if the N+1th decimal digit is >4, then the Nth decimal digitis incremented.
So in your case:
1.125 rounded to 2 decimal places (currency) is 1.13. This is because 5 is greater than 4 and hence the 2 is incremented to 3.
Explained much better here.
Rob

Ohhhhh.... Old McDonald was dyslexic, E O I O EEEEEEEEEE.......

February 8th, 2012, 08:35 PM
#4
Re: Basic Question about Math.Round and {0:C}
Actually, they are both doing the rounding, but there are differences in the approach.
The Math.Round(double, int, MidpointRounding) variant of the method provides you with a way to explicitly set the approach to use for the midpoint case.
There are two possibilities:
 MidpointRounding.ToEven  If the digit in the decimals position is odd, it is changed to an even digit. Otherwise, it is left unchanged. This behavior follows IEEE Standard 754, section 4. It is sometimes called rounding to nearest, or banker's rounding. It minimizes rounding errors that result from consistently rounding a midpoint value in a single direction.
 MidpointRounding.AwayFromZero  The digit in the decimals position is always rounded up to the next digit. This is the most commonly known rounding method. It is known as symmetric arithmetic rounding.
The default approach for the Math.Round() method is MidpointRounding.ToEven  generally, the more precise one.
But, if you go to the MSDN entry on the currency format specifier, you'll find this:
If the value to be formatted has more than the specified or default number of decimal places, the fractional value is rounded in the result string. If the value to the right of the number of specified decimal places is 5 or greater, the last digit in the result string is rounded away from zero. [emphasis by me]
Last edited by TheGreatCthulhu; February 8th, 2012 at 08:38 PM.

February 8th, 2012, 08:54 PM
#5
Re: Basic Question about Math.Round and {0:C}
Wait... Didn't check the numbers; what you're experiencing is the opposite of what should happen. (BTW, it appears that the C format specifier rounds to 2 decimal places by default on your system, and you're telling math to round to 3).
 a few moments after 
OK, if I reproduced your program correctly, you should get the value of 1.124864
Math.Round(finalCost, 3) should produce 1.125.
In the away from zero mode,
1.124864 is rounded to 1.12, and
1.125 is rounded to 1.13.

February 8th, 2012, 10:19 PM
#6
Re: Basic Question about Math.Round and {0:C}
I see so generally I should just use the {0:C} and be done with it as the "Math.Round(finalCost, 3)" just complicates things. I guess it depends on which way you want to go, I just added the Math.Round(finalCost, 3) as I though it should round to 1.13 when I saw the original 1.124864 and wondered which way was the correct way. To me using the "Math.Round(finalCost, 3)" seems more correct than the {0:C}, although the {0:C} is made for currency so I guess it is correct.
Just a question, which way would you use in a Production Environment?
Thank you guys for your help,
jdearing

February 9th, 2012, 07:52 AM
#7
Re: Basic Question about Math.Round and {0:C}
Originally Posted by jdearing
[...] I just added the Math.Round(finalCost, 3) as I though it should round to 1.13 when I saw the original 1.124864 [...]
If you check the docs for Math.Round(double, int), you'll see this description for the second parameter:
The number of fractional digits in the return value.
So, it refers to the number of decimal places after the decimal point. That's why your program rounded to 1.125.
Originally Posted by jdearing
Just a question, which way would you use in a Production Environment?
Depends. Generally, if you wanted to round numbers for various calculations, like in a physicsbased simulation, you would use Math.Round().
However, note that Math.Round() and {0:C} have different purposes.
Math.Round() changes the actual numerical data value, while {0:C} only changes the string representation of the value, without ever changing the original data.
By using a Math.Round(double, int, MidpointRounding) overload, and setting the last parameter to AwayFromZero will get you the same behavior as with {0:C}, in terms of how the rounding is done, but the difference in whether the original data is affected or not still remains.
So, it's like this: if you just want to round the number for display, so that a user (human) can read it with more ease, use {0:C}, and leave the original number unchanged, maintaining the more accurate, higher precision value internally. The user usually only cares for the value to be precise up to a number of decimal places.
If, OTOH, you need to work with rounded values in your internal calculation, then use Math.Round(). For example, you might want to do this if you're performing calculations with doubles, so that you can have greater precision, but ultimately only need an integer value. Use Math.Round() if you need rounding in your implementation regardless of whether you're gonna display the result as text or not.

February 9th, 2012, 11:07 AM
#8
Re: Basic Question about Math.Round and {0:C}
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

Click Here to Expand Forum to Full Width
This is a Codeguru.com survey!
