为什么不是最接近的整数Convert.ToInt32()四舍五入为最接近的偶数,? [关闭](W

2019-06-26 05:27发布

纵观MSDN文档Convert.ToInt32()也指出:

如果值是中间两个整数之间,偶数则返回; 也就是说,4.5被转换为4,和5.5被转换为6。

http://msdn.microsoft.com/en-us/library/ffdk7eyz.aspx

为什么是这样?

当然,它会更合乎逻辑的四舍五入到最接近的整数,不是吗? 如果是这样,4.5将成为5和5.5将成为6,这似乎是更直观。

Answer 1:

维基百科条目的历史部分四舍五入大约有作用的一些声明“轮,甚至”在计算。 有趣的是,它似乎“银行家舍入”有什么证据说明它是在这个词的任何意义上的官员,所以只能粉笔写的俚语术语。

只有“更符合逻辑”,如果您订阅的舍入机制。 银行家舍入(其在此情况下,默认)也是完全合乎逻辑的。

试想一下,如果银行调高为每一个分数量最接近的货币,他们会少了很多以百万计的交易,每天处理(失去很多,对于有争议的)钱数以百万计。 好了,这个例子是愤世嫉俗。

朝最近的偶数去(或奇数,但是历史选择了其他方式)意味着并不是每一个舍入分辨率上升现在有人可以下去 。 当你把这个平衡法则,它成为一个公平的解决方案考虑是负责为多出的半便士支付时使用。

至于为什么这样选择的框架,这个问题试图解决这个问题:

为什么.NET使用银行家作为默认的舍入?

当然,这一切都可以追溯到金融天,其适用于整数号可能被质疑,但何必呢? 接受它,覆盖它,如果你想,才明白它是如何工作的。


人们想知道如何更改默认的舍入:

如果你正在为一个非整数Convert.ToInt32你首先真正需要做的是这样Convert.ToDouble然后Math.Round与超载改变舍入逻辑 。



Answer 2:

这也正是为什么MidpontRounding超载加入Math.Round

因此,对于正确的舍入你应该使用Math.Round而非Convert.ToInt32。



Answer 3:

不考虑MidpointRounding.ToEven(银行家的舍入)或MidpointRounding.AwayFromZero是否会是一个更好的默认主观题。

在设计这一点,微软会考虑语言.NET的目的是要取代。

  • VB经典总是默认使用的银行家舍入。

  • C / C ++转换截断铸造时,具有库函数地板()和小区()在运行时库 - 但(AFAIK,可能是错误的)没有循环函数。

  • Java有一个Math.round该文档中被描述为等同于Math.round(A + 0.5)。 这无疑不是大多数人所期望的负数(-3.5两轮-3)。

  • VB开发人员可真可预计需要不是开发人员从C / C ++或Java的未来更手把手的指导。

因此,它似乎是合理的设计.NET时,类库将提供FloorCeilingRound的方法,以及在往返行为将默认为VB的行为。

这也似乎是合理的Convert.ToInt32()将使用Round方法(虽然我猜的情况下,可以为地面制成,一致性铸造)。



Answer 4:

如果你想要的行为,你需要使用Math.Round并指定MidpointRounding.AwayFromZero

例如:

int result = (int)Math.Round(4.5, MidpointRounding.AwayFromZero);

演示: http://ideone.com/ZAbBL

Convert.ToInt32(double)不使用Math.Round本身,而是以这种方式(ILSpy)实现的真实:

public static int ToInt32(double value)
{
    if (value >= 0.0)
    {
        if (value < 2147483647.5)
        {
            int num = (int)value;
            double num2 = value - (double)num;
            if (num2 > 0.5 || (num2 == 0.5 && (num & 1) != 0))
            {
                num++;
            }
            return num;
        }
    }
    else
    {
        if (value >= -2147483648.5)
        {
            int num3 = (int)value;
            double num4 = value - (double)num3;
            if (num4 < -0.5 || (num4 == -0.5 && (num3 & 1) != 0))
            {
                num3--;
            }
            return num3;
        }
    }
    throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}


文章来源: Why does Convert.ToInt32() round to the nearest even number, instead of nearest whole number? [closed]