3

I am seeing an intriguing situation rounding Currency in C# (VS 2008 SP1). Below is an image of the test cases:

alt text http://img697.imageshack.us/img697/8500/testcases.png

I was expecting cases five, six, and seven (my bad on not numbering them in the output) to round the number up to a penny.

Here is my test code:

static void Main(string[] args)
{
    decimal one = 10.994m;
    decimal two = 10.995m;
    decimal three = 1.009m;
    decimal four = 0.0044m;
    decimal five = 0.0045m;
    decimal six = 0.0046m;
    decimal seven = 0.0049m;
    decimal eight = 0.0050m;

    Console.WriteLine(one + ": " + one.ToString("C"));
    Console.WriteLine(two + ": " + two.ToString("C"));
    Console.WriteLine(three + ": " + three.ToString("C"));
    Console.WriteLine(four + ": " + four.ToString("C"));
    Console.WriteLine(five + ": " + five.ToString("C"));
    Console.WriteLine(six + ": " + six.ToString("C"));
    Console.WriteLine(seven + ": " + seven.ToString("C"));
    Console.WriteLine(eight + ": " + eight.ToString("C"));

    Console.ReadLine();
}

When I reflected into .ToString(string format) to see what was going on I found

public string ToString(string format)
{
    return Number.FormatDecimal(this, format, NumberFormatInfo.CurrentInfo);
}

which has the call to

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern string FormatDecimal(
    decimal value, 
    string format, 
    NumberFormatInfo info);

Is there some logic in that call that says the granularity for my current culture settings for NumberFormatInfo is two decimal places for currencty so don't let the ten thousandths place roll the number up because it is insignificant?

How is this method implemented? Are we into bit shift land, or is something else going on?

Thanks for any insights.

blu
  • 12,905
  • 20
  • 70
  • 106
  • If you really want cases 5, 6, 7 to round up to a penny, then you need to first round to half a penny: Math.Round(five, 3, MidpointRounding.AwayFromZero): The result of this will round to a penny. – Igby Largeman Apr 06 '10 at 22:22
  • Find a culture that measure millidollars and you'll be vindicated. – Hans Passant Apr 06 '10 at 22:24
  • 1
    "Ah no, you don't understand. It's very complicated. It's uh it's aggregate, so I'm talking about fractions of a penny here. And over time they add up to a lot." http://www.imdb.com/title/tt0151804/quotes?qt0996772 – blu Apr 07 '10 at 02:14
  • @Charles agreed, and if they want it they will get it. Although I don't think I will be able to pull, "It's basic math!" with them. – blu Apr 07 '10 at 02:37

1 Answers1

8

Following basic mathematical principles, cases 4, 5, 6, and 7 should not round up to a penny. You don't round by starting at the right-most number and rounding up. You only look one digit to the right of the number you want to round to.

http://www.enchantedlearning.com/math/rounding/

the computer is just performing basic math, as they are supposed to.

Edit - added

a better link: http://math.about.com/od/arithmetic/a/Rounding.htm

David
  • 72,686
  • 18
  • 132
  • 173
  • Interesting, how about case 1 then? – blu Apr 06 '10 at 22:05
  • In case 1, the last digit would force the last 9 to round up. Since 9 + 1 = 10, then the next 9 in has to have 1 added to it, and since that's a 9... – David Apr 06 '10 at 22:06
  • OK, so we are saying that we are rounding to the hundredths place, so only look at the number directly to the right. OK, good answer, thanks. – blu Apr 06 '10 at 22:09