C# 为什么Convert.ToInt32()会舍入到最近的偶数,而不是最近的整数?

C# 为什么Convert.ToInt32()会舍入到最近的偶数,而不是最近的整数?,c#,decimal,rounding,int32,C#,Decimal,Rounding,Int32,查看msdn文档中的Convert.ToInt32() 如果值介于两个整数之间,则为偶数 返回;也就是说,4.5转换为4,5.5转换为6 这是为什么? 当然,四舍五入到最接近的整数更合乎逻辑,不是吗?如果是这样,4.5将变为5,5.5将变为6,这似乎更直观。这正是将重载添加到的原因 因此,对于正确的舍入,您应该使用Math.Round而不是Convert.ToInt32。的维基百科条目的历史部分有一些关于“舍入到偶数”在计算中的作用的陈述。有趣的是,“银行家四舍五入”似乎并没有证据表明它在任何

查看msdn文档中的
Convert.ToInt32()

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

这是为什么?

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

这正是将重载添加到的原因

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

的维基百科条目的历史部分有一些关于“舍入到偶数”在计算中的作用的陈述。有趣的是,“银行家四舍五入”似乎并没有证据表明它在任何意义上是官方的,所以只能记为俚语术语

如果您同意这种舍入机制,那么它只会“更符合逻辑”。银行家四舍五入(这是本例中的默认值)也是完全合乎逻辑的

想象一下,如果银行把每一个零碎的金额凑到最接近的一分钱,他们每天处理的数以百万计的交易就会少赚很多钱(对愤世嫉俗的人来说,损失很多)。好的,这个例子是愤世嫉俗的

接近最近的偶数(或奇数,但历史选择了其他方式)意味着并非所有舍入分辨率都会上升,有些分辨率现在会下降。当你把这一点应用到平均法则中时,当考虑到谁负责支付额外的半便士时,它就成为了一个公平的解决方案

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

当然,这一切都可以追溯到金融时代,它对整数的适用性可能会受到质疑,但为什么要麻烦呢?接受它,如果你想覆盖它,只要理解它是如何工作的。
对于想知道如何更改默认舍入的人:


如果要将非整数转换为Convert.ToInt32,则首先需要执行类似于Convert.ToDouble的操作,然后执行。

如果需要该行为,则需要使用并指定
中点舍入.AwayFromZero

例如:

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

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

public static int到int32(双值)
{
如果(值>=0.0)
{
如果(值<2147483647.5)
{
int num=(int)值;
double num2=值-(double)num;
如果(num2>0.5 | |(num2==0.5&&(num&1)!=0))
{
num++;
}
返回num;
}
}
其他的
{
如果(值>=-2147483648.5)
{
int num3=(int)值;
double num4=值-(double)num3;
如果(num4<-0.5 | |(num4==-0.5&&(num3&1)!=0))
{
num3--;
}
返回num3;
}
}
抛出新的OverflowException(Environment.GetResourceString(“Overflow_Int32”);
}

不考虑中点舍入.ToEven(银行舍入)或中点舍入.AwayFromZero是更好的默认值这一主观问题

在设计这一功能时,微软会考虑将.NET设计用来取代的语言

  • VB classic在默认情况下始终使用银行家四舍五入

  • > P/C/C++转换在浇铸时截断,在运行时库中有库函数FROULL()和CELL(),但是(AfEk,可能是错误的)没有圆函数。

  • Java有一个Math.round,它被描述为等同于Math.round(a+0.5)。这可能不是大多数人对负数的预期(-3.5轮到-3轮)

  • 可以说,VB开发人员比来自C/C++或Java的开发人员需要更多的人手

因此,在设计.NET时,类库将提供
Floor
天花
Round
方法似乎是合理的,并且Round行为将默认为VB的行为


Convert.ToInt32()将使用Round方法似乎也是合理的(尽管我想可以为Floor制作一个案例,以便与铸造保持一致)。

如果需要特定的行为,请使用
Math.Round
方法。当然,Convert.ToInt32()确实已经使用了此方法和所描述的行为。这与平均数有关,你转换并加上6个数字,其中一半向下四舍五入,另一半向上四舍五入。如果所有数字都向上或向下四舍五入,你会得到一个更准确的数字。@Ramhound我很感激,我只是好奇,为什么你说的时候,在任何场景中,偶数都比奇数更偏好“当然,四舍五入到最接近的整数更合乎逻辑?”,整个问题是有两个“最接近的整数”…@Curt我认为这通常是因为大多数学校(至少在英国)只教授四舍五入,其中.5表示“向上”。我陷入了“这到底是怎么回事?”?“银行家们的圈套。嗯。。。你自己和其他人似乎对奎斯顿感到困惑。我没有看到任何一部分说“我如何才能获得一致性?”,这更多的是关于为什么当初做出这个决定。我也同意,如果有目的的话,这不是一个很好的违约行为done@Ramhound.@AdamHouldsworth-这难道不是一个复制品吗question@Ramhound检查时是的,但在为重复检测机提供数据时,有少量重复数据是有价值的。当输入上述问题时,问题中的副本将永远不会在搜索结果中返回。我想你的意思是银行将赚更少的钱。。。我无法想象他们会输any@musefan但是在
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"));
}