decimal.Round
方法使用舍入到偶数算法,这对于大多数应用程序来说并不常见。因此,我总是最终编写一个自定义函数来执行更自然的四舍五入算法:
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;
}
有人知道这个框架设计决策背后的原因吗?
框架中是否有内置的上舍入算法实现?或者也许是一些非托管的 Windows API?
对于初学者来说,简单地写下
decimal.Round(2.5m, 0)
期望结果为 3,但却得到 2,这可能会产生误导。
其他答案以及为什么银行家算法(又名round half to equal)是一个不错的选择的原因是非常正确的。在最合理的分布上,它不会像“远离零的一半”方法那样受到负偏差或正偏差的影响。 但问题是为什么 .NET 使用 Banker 的实际舍入作为默认值 - 答案是 Microsoft 遵循了
IEEE 754标准。 MSDN for Math.Round 的备注下也提到了这一点。 另请注意,.NET 通过提供
MidpointRounding
枚举来支持 IEEE 指定的替代方法。他们当然可以提供
更多替代方案来解决关系,但他们选择只满足 IEEE 标准。
;在处理金钱时,银行家的四舍五入很常见。 或者你可以说。
主要是银行家需要 小数类型;因此它确实 “银行家四舍五入”银行家四舍五入的优点是,如果您满足以下条件,平均而言您会得到相同的结果:
在将一组“发票行”相加之前将其四舍五入,
(在英国,当我们采用十进制时,银行不会处理半便士,但多年来仍然有半便士硬币,商店经常有以半便士结尾的价格 - 所以有很多四舍五入)
decimal.Round(2.5m, 0,MidpointRounding.AwayFromZero)
它将输出3
。如果你使用
decimal.Round(2.5m, 0,MidpointRounding.ToEven)
您将获得银行家的四舍五入。