According to the documentation, the decimal.Round
method uses a round-to-even algorithm which is not common for most applications. So I always end up writing a custom function to do the more natural round-half-up algorithm:
public static decimal RoundHalfUp(this decimal d, int decimals)
{
if (decimals < 0)
{
throw new ArgumentException("The decimals must be non-negative",
"decimals");
}
decimal multiplier = (decimal)Math.Pow(10, decimals);
decimal number = d * multiplier;
if (decimal.Truncate(number) < number)
{
number += 0.5m;
}
return decimal.Round(number) / multiplier;
}
Does anybody know the reason behind this framework design decision?
Is there any built-in implementation of the round-half-up algorithm into the framework? Or maybe some unmanaged Windows API?
It could be misleading for beginners that simply write decimal.Round(2.5m, 0)
expecting 3 as a result but getting 2 instead.
0.5.ToString("0") == "1"
). I think that usually when you round, you do it to display the value on the screen. So this makes it really interesting. – Orthmand = 9.825m
is aDecimal
(exactly representable for sure), then stuff likedecimal.Round(d, 2)
andMath.Round(d, 2)
gives9.82
, while formatting liked.ToString("F2")
,d.ToString("N2")
andd.ToString("0.00")
gives"9.83"
(the decimal separator character depending on the culture of the current thread). Not friendly. – GleichMath.Round
. – Orthman