Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么.NET使用银行家&x27;默认为四舍五入吗?_.net_Rounding - Fatal编程技术网

为什么.NET使用银行家&x27;默认为四舍五入吗?

为什么.NET使用银行家&x27;默认为四舍五入吗?,.net,rounding,.net,Rounding,根据文档,该方法使用了一种从圆到平的算法,这在大多数应用中并不常见。因此,我总是编写一个自定义函数来执行更自然的取整半向上算法: public static decimal RoundHalfUp(this decimal d, int decimals) { if (decimals < 0) { throw new ArgumentException("The decimals must be non-negative", "d

根据文档,该方法使用了一种从圆到平的算法,这在大多数应用中并不常见。因此,我总是编写一个自定义函数来执行更自然的取整半向上算法:

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;
}
public static decimal RoundHalfUp(此十进制数为d,整数为小数)
{
if(小数<0)
{
抛出新ArgumentException(“小数必须为非负”,
“小数”);
}
十进制乘数=(十进制)数学功率(10,小数);
十进制数=d*乘法器;
if(十进制截断(数字)<数字)
{
数量+=0.5m;
}
返回小数。四舍五入(数字)/乘法器;
}
有人知道这个框架设计决策背后的原因吗

框架中是否内置了半舍五入算法的实现?或者是一些非托管的Windows API


对于初学者来说,简单地编写
decimal.Round(2.5m,0)
可能会误导他们,他们期望结果是3,但得到2。

可能是因为这是一个更好的算法。在进行多次舍入的过程中,你将平均得出所有.5的结果都是上下平均舍入。这可以更好地估计实际结果,例如,添加一组四舍五入的数字。我想说的是,尽管这不是一些人所期望的,但这可能是更正确的做法。

虽然我无法回答“为什么微软的设计师选择此作为默认设置?”的问题,但我只想指出,额外的功能是不必要的

允许您指定:

  • ToEven-当一个数字介于其他两个数字之间时,它将向最近的偶数舍入
  • 远离零-当一个数字位于其他两个数字的中间时,它将向远离零的最近数字四舍五入
小数主要用于货币;使用货币时,银行家四舍五入很常见。或者你可以说

大多数银行家需要这一点 十进制类型;因此它确实如此 “银行家四舍五入”

银行家的优势在于,如果您:

  • 将一组“发票行”四舍五入,然后再相加
  • 或者把它们加起来,然后把总数四舍五入
在计算机出现之前,先四舍五入再相加节省了大量工作


(在英国,当我们使用十进制时,银行不会处理半便士的问题,但多年来,仍然有半便士硬币,商店的价格通常以半便士结尾,所以有很多舍入)

关于银行家算法(aka)是一个好选择的原因,其他答案是非常正确的。它不像最合理的分布上的方法那样受到负或正偏差的影响

但问题是为什么.NET使用银行家的实际四舍五入作为默认值——答案是微软遵循了这一标准。下面的备注中也提到了这一点


还请注意,.NET通过提供
中点舍入
枚举来支持IEEE指定的替代方法。当然,他们可以提供解决关系的方法,但他们选择只满足IEEE标准。

使用另一个超负荷的圆函数,如下所示:

decimal.Round(2.5m, 0,MidpointRounding.AwayFromZero)
它将输出3。如果你使用

decimal.Round(2.5m, 0,MidpointRounding.ToEven)

你会得到银行家的四舍五入。

四舍五入不是“更自然的”。自然与此无关。这只是你在小学里学到的,当你学会了“舍入”的概念。小学的课程并不总是描绘一幅完整的画面。@Rob这就是为什么它更自然,即使它不正确,我不明白,@Pacerier。我解释了为什么它不是自然的,你说这就是为什么它是自然的。我的论点如何与我的结论相悖?我的结论与你的相反?你已经习惯的东西可能会感觉自然,有时我们会比喻说某些东西是“第二天性”,但这并不能使它们自然。@Rob我说的是自然,因为它感觉自然。你知道有36个不同的物体有着相同的变量名自然权利吗?自然是完全相似的,所以用这个词是错误的;但这太迂腐了。也许“通常”是一个更好的词….“人们通常做的四舍五入是什么”>0.5到1.0,正如我在相关线程中提到的,确保你的四舍五入是一致的-如果你有时在数据库中做四舍五入,有时在.net中,你会有奇怪的,一分钱的错误需要你花上几周的时间才能弄清楚。一位客户曾经付给我4万多美元,以追踪两个数字之间0.11美元的舍入误差,而这两个数字都不到10亿美元;0.11美元是由于大型机和SQL Server之间第8位舍入误差的差异造成的。谈谈完美主义者吧@EJB-如果我要应付10亿美元,我可能是一个完美主义者;-)@E.J.布伦南:你花了4万美元才弄明白?我一直看到这样的问题,四舍五入是原因#1,双/浮点标准化是原因#2,如果没有预定义的测试用例,程序员错误#3-#3可以立即设置为#1。顺便说一句,你能帮我联系一下你的亿万富翁客户吗?我想我也能在他的系统中找到一些价值4万美元的漏洞D@seanxe:或者如果你看到了办公空间。说真的,每当你看到金钱中神秘的、微小的不准确之处,解决它们究竟是如何发生的这个谜几乎总是一个好主意。您可能会决定不修复bug,但了解根本原因仍然有价值。我敢打赌,许多与钱打交道的人都乐于注意到哪怕是很小的误差。假设奇数和偶数输入的平均分布当然是+1,以获得更好的算法,尽管奥斯特马尔有实际的答案()@Ian,但我也给出了+1的答案。无论如何,我们可以得到“被接受的答案”也许OP可以做到这一点。