Scott
Scott

Reputation: 13921

C# Math.Round Error?

Ok, I realize it's early on a Sunday so I hope I'm just missing something obvious:

I have this function:

private decimal CashConversion(decimal amount, decimal ratio)
{
    if (ratio == 1) return amount;

    decimal convertedAmount = amount / ratio;
    return Math.Round(convertedAmount, 2);
}

When I call it like this:

decimal tax = CashConversion(96.53, 15);

The "tax" variable is equal to 6.43. However, 96.53/15 is 6.435333333333333. Rounding that to 2 places should return 6.44. Am I missing something here?

Upvotes: 4

Views: 4135

Answers (3)

Falanwe
Falanwe

Reputation: 4744

Check the documentation for Math.Round: As 2 is even, and the next digit after the second is 5, the value is rounded down, according to the IEEE Standard 754, section 4. It's called banker's rounding.

It's not an error, but an expected behaviour. Maybe not the one you were expecting though.

If you want the "mathematically correct" behaviour though, you can call the Decimal.Round(Decimal, Int32, MidpointRounding) overload, as in:

Math.Round(convertedAmount, 2, MidpointRounding.AwayFromZero);

Upvotes: 5

Jason
Jason

Reputation: 89092

By default, Math.Round uses banker's rounding. You probably are expecting it to use midpoint rounding. To force this behavior, try this:

Math.Round(convertedAmount, 2, MidpointRounding.AwayFromZero);

Upvotes: 2

Peter O.
Peter O.

Reputation: 32878

That's indeed what is expected: 6.435 would round to 6.44:

When d is exactly halfway between two rounded values, the result is the rounded value that has an even digit in the [(decimals+1)th decimal position]. For example, when rounded to two decimals, the value 2.345 becomes 2.34 and the value 2.355 becomes 2.36[, and 2.3653333 becomes 2.37]. This process is known as rounding toward even, or rounding to nearest.

Upvotes: 3

Related Questions