在c#中,Math.Round(2.5)的结果是2。

应该是3,不是吗?为什么在c#中它是2 ?


当前回答

这是非常丑陋的,但总是产生正确的算术四舍五入。

public double ArithRound(double number,int places){

  string numberFormat = "###.";

  numberFormat = numberFormat.PadRight(numberFormat.Length + places, '#');

  return double.Parse(number.ToString(numberFormat));

}

其他回答

这被称为舍入到偶数(或银行家舍入),这是一种有效的舍入策略,可以最大限度地减少总和中的累积错误(MidpointRounding.ToEven)。理论是,如果你总是在同一个方向四舍五入一个0.5的数字,误差会更快地累积(四舍五入到偶数应该是最小化)(a)。

以下是MSDN对以下内容的描述:

Math.Floor, which rounds down towards negative infinity. Math.Ceiling, which rounds up towards positive infinity. Math.Truncate, which rounds up or down towards zero. Math.Round, which rounds to the nearest integer or specified number of decimal places. You can specify the behavior if it's exactly equidistant between two possibilities, such as rounding so that the final digit is even ("Round(2.5,MidpointRounding.ToEven)" becoming 2) or so that it's further away from zero ("Round(2.5,MidpointRounding.AwayFromZero)" becoming 3).

下面的图表可能会有所帮助:

-3        -2        -1         0         1         2         3
 +--|------+---------+----|----+--|------+----|----+-------|-+
    a                     b       c           d            e

                       a=-2.7  b=-0.5  c=0.3  d=1.5  e=2.8
                       ======  ======  =====  =====  =====
Floor                    -3      -1      0      1      2
Ceiling                  -2       0      1      2      3
Truncate                 -2       0      0      1      2
Round(ToEven)            -3       0      0      2      3
Round(AwayFromZero)      -3      -1      0      2      3

请注意,Round比它看起来强大得多,因为它可以舍入到特定的小数点后数位。其他的都是0小数。例如:

n = 3.145;
a = System.Math.Round (n, 2, MidpointRounding.ToEven);       // 3.14
b = System.Math.Round (n, 2, MidpointRounding.AwayFromZero); // 3.15

对于其他函数,你必须使用乘除技巧来达到相同的效果:

c = System.Math.Truncate (n * 100) / 100;                    // 3.14
d = System.Math.Ceiling (n * 100) / 100;                     // 3.15

(a)当然,这个理论取决于这样一个事实,即你的数据在偶数一半(0.5,2.5,4.5,…)和奇数一半(1.5,3.5,…)之间的值分布相当均匀。

如果所有的“半值”都是偶数(例如),错误就会像你总是四舍五入一样快速累积。

从MSDN:

默认为Math。圆的使用 MidpointRounding.ToEven。大多数人 不熟悉“四舍五入? 甚至“作为替代”,四舍五入 “远离零”更常见 . net默认为 “四舍五入到偶数” 统计上的优势是因为 没有分享的倾向 四舍五入的意思是四舍五入 比它循环的频率稍高 向下(假设数字为 四舍五入往往是积极的。)

http://msdn.microsoft.com/en-us/library/system.math.round.aspx

简单的方法是:

Math.Ceiling(decimal.Parse(yourNumber + ""));

来自MSDN的数学。Round(double a)返回:

最接近a的整数 a的分数分量是一半 两个整数之间,其中一个是 偶数和另一个奇数,然后是偶数 返回Number。

... 因此,在2和3中间的2.5被四舍五入为偶数(2)。这被称为银行家四舍五入(或四舍五入为偶数),是一种常用的四舍五入标准。

同一篇MSDN文章:

此方法的行为如下 IEEE标准754,第4节。这 四舍五入有时被称为 四舍五入到最接近的,或银行家的 舍入。它最小化舍入误差 这是持续舍入的结果 一个单一的中点值 方向。

您可以通过调用Math的重载来指定不同的舍入行为。回合采取midpointround模式。

使用. net对数字进行舍入可以得到您正在寻找的答案。

基本上它是这么说的:

返回值

精度等于数字的最接近的数字值。如果值位于两个数的中间,其中一个是偶数,另一个是奇数,则返回偶数。如果value的精度小于数字,则value不变地返回。

这种方法的行为遵循IEEE标准754,第4节。这种四舍五入有时被称为最接近四舍五入,或银行家四舍五入。如果数字为零,这种舍入有时被称为趋零舍入。