根据文档,该decimal.Round方法使用round-to-even算法,这对于大多数应用程序来说并不常见.所以我总是最终编写一个自定义函数来做更自然的圆半算法:
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;
}
Run Code Online (Sandbox Code Playgroud)
有谁知道这个框架设计决策背后的原因?
是否有任何内置的圆形半算法实现到框架中?或者可能是一些非托管Windows API?
对于初学者而言,这可能会产生误导,因为他们只是写了一个decimal.Round(2.5m, 0)期望3但结果是2.
Ost*_*mar 427
另一个答案是为什么银行家的算法(也就是一半到一半)是一个不错的选择是非常正确的.与大多数合理分布相比,它没有像零方法那样的圆半部分遭受负偏差或正偏差.
但问题是为什么.NET使用Banker的实际舍入作为默认值 - 答案是微软遵循IEEE 754标准.在备注下的MSDN for Math.Round中也提到了这一点.
另请注意,.NET通过提供MidpointRounding枚举来支持IEEE指定的替代方法.他们当然可以为解决关系提供更多选择,但他们选择只满足IEEE标准.
Kib*_*bee 191
可能是因为它是一个更好的算法.在执行多次舍入的过程中,您将平均所有.5的最终向上和向下舍入.如果您是例如添加一堆舍入数字,则可以更好地估计实际结果.我会说即使它不是人们所期望的,但这可能是更正确的事情.
Mic*_*tum 86
虽然我不能回答"为什么微软的设计师选择这个作为默认设置?"的问题,但我只是想指出一个额外的功能是不必要的.
Math.Round允许您指定MidpointRounding:
Ian*_*ose 23
小数几乎用于赚钱 ; 在与钱合作时,银行家的四舍五入很常见.或者你可以说.
大多数银行家都需要十进制类型; 因此,它"银行家的四舍五入"
银行家四舍五入的优势在于,如果您:平均获得相同的结果:
加起来之前的舍入在计算机之前的日子里节省了大量的工作.
(在英国,当我们去十进制银行不会处理半便士,但多年来仍然有半便士硬币和商店经常价格以半便士结束 - 所以很多四舍五入)
| 归档时间: |
|
| 查看次数: |
54289 次 |
| 最近记录: |