舍入小数值

Shi*_*ivi 8 c# floating-point

我在使用C#舍入十进制值时遇到问题 Math.Round(a, 2);

当我将1.275舍入2小数点时,结果是1.27.当我为1.375做同样的事情时,结果是1.38.

为什么它不是在1.275到1.28之间?

谢谢

Cod*_*aos 8

我无法重现你的问题:

Math.Round(1.275m, 2) => 1.28m
Math.Round(1.375m, 2) => 1.38m
Run Code Online (Sandbox Code Playgroud)

我怀疑您声称使用decimal值是错误的,而您使用的是double值.double不能完全代表许多十进制值,所以当你写1.275,它实际上是1.27499 ... 1.375 是少数可表示的onces之一,所以它实际上1.375.

如果您的代码关心精确的十进制表示,例如当您处理金钱时,您必须使用decimal而不是二进制浮点,例如doublefloat.


但即使您使用十进制表示,对于许多用户来说,舍入行为也会出乎意料:

Math.Round(1.265m, 2) => 1.26m
Math.Round(1.275m, 2) => 1.28m
Run Code Online (Sandbox Code Playgroud)

默认Math.Round使用MidpointRounding.ToEven,也称为Banker的回合.这样可以避免累积偏差.5.

您可以使用Round采用舍入模式的重载,并将其设置AwayFromZero为获得您期望的行为.

Math.Round(1.275m, 2, MidpointRounding.AwayFromZero) => 1.28m
Run Code Online (Sandbox Code Playgroud)

  • 如果1.275四舍五入到1.28,那将是解释,但事实并非如此. (3认同)

Ica*_*rus 7

MSDN对此行为有这样的说法:

来电者须知

由于将十进制值表示为浮点数或对浮点值执行算术运算可能导致精度损失,因此在某些情况下,Round(Double,Int32)方法可能看起来不会将中点值舍入到最接近的偶数值小数位数的值.这在以下示例中说明,其中2.135舍入为2.13而不是2.14.发生这种情况是因为内部方法将值乘以10 位数,并且在这种情况下的乘法运算会受到精度损失的影响.

public class Example
{
   public static void Main()
   {
      double[] values = { 2.125, 2.135, 2.145, 3.125, 3.135, 3.145 };
      foreach (double value in values)
         Console.WriteLine("{0} --> {1}", value, Math.Round(value, 2));

   }
}
// The example displays the following output:
//       2.125 --> 2.12
//       2.135 --> 2.13
//       2.145 --> 2.14
//       3.125 --> 3.12
//       3.135 --> 3.14
//       3.145 --> 3.14
Run Code Online (Sandbox Code Playgroud)