Convert.ToInt奇怪的舍入为十进制和双精度

时间:2014-10-30 14:00:54

标签: c# .net double decimal rounding

我偶然发现Convert课程的这种奇怪行为,我想分享。

Convert.ToInt(16,32,64)方法在doubledecimal类型上以奇怪的方式使用时:

来自msdn:

  

转换后的值四舍五入为最接近的16位有符号整数。如果   值是两个整数之间的中间值,偶数是   回;也就是说,4.5转换为4,5.5转换为6.

这是一种非常奇怪的行为,它可能导致很难找到错误。

我用反射器查看了分析代码,但它是extern方法:

//Convert.ToInt32
[SecuritySafeCritical, __DynamicallyInvokable]
public static int ToInt32(decimal value)
{
    return decimal.FCallToInt32(value);
}

//decimal
[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
internal static extern int FCallToInt32(decimal d);

我知道Convert类用于将基本数据类型转换为另一种基本数据类型,它不应该用于舍入值,但您同意我们必须期望标准舍入。

我的问题是为什么这种行为以及为什么它没有在MSDN上标记大红色字体

1 个答案:

答案 0 :(得分:2)

这被称为银行家的四舍五入,它专门用于金融应用程序。由于decimal是专为财务应用程序设计的,因此很明显为什么它是decimal的默认舍入方法,不是吗? :)

背后的想法是,如果你总是单向舍入,.5数字会破坏数字的分布,换句话说,你的舍入错误会显着积累。通过基于均匀性向上或向下舍入,在这些情况下,通常会最终累计50%的时间,而其余时间则减少 - 因此错误将保持非常小。

这是在计算机之前使用的东西:)