Convert.Toint32(double value)取整时的四舍六入五成双规则

用Convert.Toint32()给小数转换成整数时,会四舍五入。比如:

Convert.Toint32(4.1) = 4
Convert.Toint32(4.3) = 4
Convert.Toint32(4.51) = 5
Convert.Toint32(4.6) = 5

但是,如果小数后面是.5 或者.50 之类的中间数,转换后的结果就让大家意向不到了。总之,结果是:
如果value为两个整数中间的数字,则返回二者中的偶数。
比如Convert.Toint32(3.5),3.5是整数3和4之间的数,此时取偶数4
比如Convert.Toint32(4.5),4.5是整数4和5之间的数,此时取偶数4

看看Convert.Toint32()官方具体的实现:

public static int ToInt32(double value)
{
    if (value >= 0)
    {
        if (value < 2147483647.5)
        {
            int result = (int)value;
            double dif = value - result;
            if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
            return result;
        }
    }
    else
    {
        if (value >= -2147483648.5)
        {
            int result = (int)value;
            double dif = value - result;
            if (dif < -0.5 || dif == -0.5 && (result & 1) != 0) result--;
            return result;
        }
    }
    throw new OverflowException(SR.Overflow_Int32);
}

从这里我们看到了if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;if (dif < -0.5 || dif == -0.5 && (result & 1) != 0) result--;这两行代码,这里的在四舍五入里大于0.5的直接进位,但是等于0.5的还要判断是否是奇数,是奇数才会去进位。

这叫奇进偶舍,又称为四舍六入五成双规则、银行进位法(Banker's Rounding),是一种计数保留法,是一种数字修约规则。从统计学的角度,“奇进偶舍”比“四舍五入”更为精确:在大量运算时,因为舍入后的结果有的变大,有的变小,更使舍入后的结果误差均值趋于零。而不是像四舍五入那样逢五就进位,导致结果偏向大数,使得误差产生积累进而产生系统误差。“奇进偶舍”使测量结果受到舍入误差的影响降到最低。其具体要求举例如下(以保留两位小数为例):
(1)要求保留位数的后一位如果是4,则舍去。例如5.214保留两位小数为5.21。
(2)如果保留位数的后一位如果是6,则进上去。例如5.216保留两位小数为5.22。
(3)如果保留位数的后一位如果是5,而且5后面不再有数,要根据应看尾数“5”的前一位决定是舍去还是进入: 如果是奇数则进入,如果是偶数则舍去。例如5.215保留两位小数为5.22; 5.225保留两位小数为5.22。
(4)如果保留位数的后一位如果是5,而且5后面仍有数。例如5.2254保留两位小数为5.23,也就是说如果5后面还有数据,则无论奇偶都要进入。

添加新评论