Math.Round用于Silverlight中的偶数和奇数

时间:2014-02-18 06:01:09

标签: c# silverlight math numbers rounding

我使用了像Math.Round这样的Math.Round(value, precision)。精度为3.

当我用于值= 0.0015时,结果将为0.002

当我用于值= 0.0025时,结果仍为0.002

似乎当最后一位数字是偶数时,它将向下舍入,但当最后一位数字为奇数时它会向上舍入。

如何解决这个问题?

附加:在silverlight中,没有MidpointRounding

3 个答案:

答案 0 :(得分:1)

选择不同的舍入类型,请参阅http://msdn.microsoft.com/en-us/library/f5898377(v=vs.110).aspx

从该链接:

using System;

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, MidpointRounding.AwayFromZero));

   }
}
// The example displays the following output: 
//       2.125 --> 2.13 
//       2.135 --> 2.13 
//       2.145 --> 2.15 
//       3.125 --> 3.13 
//       3.135 --> 3.14 
//       3.145 --> 3.15

更多信息:http://msdn.microsoft.com/en-us/library/system.midpointrounding(v=vs.110).aspx

正如评论员2.135 --> 2.13所指出的那样,看起来并不正确。这是因为浮点精度。原文指出:

  

由于代表可能导致精度损失   十进制值作为浮点数或执行算术   对浮点值的操作,在某些情况下为Round(Double,   Int32,MidpointRounding)方法可能不会出现圆中点   mode参数指定的值。这在图中说明   下面的示例,其中2.135舍入到2.13而不是2.14。   发生这种情况是因为内部方法将值乘以   10个数字,这种情况下的乘法运算受到a   失去精确度。

答案 1 :(得分:0)

对于Decimal,您可以使用

Decimal RoundAwayFromZero(Decimal v)
{
    return Math.Truncate(v + (v < 0m ? -.5m : .5m));
}

Double的相同:

Double RoundAwayFromZero(Double v)
{
    return Math.Truncate(v + (v < 0.0 ? -.5 : .5));
}

Trivia:Truncate也可以用modulo表示 - 这里是Decimal s:

Decimal Truncate(Decimal v)
{
    return v - (v % 1m);
}

对于在舍入之前使用显式精度乘法的舍入,再次在Decimal s:

Decimal RoundAwayFromZero(Decimal v, Int32 p)
{
    var f = (Decimal)Math.Pow(10, p);

    return RoundAwayFromZero(v * f) / f;
}

答案 2 :(得分:0)

我目前的解决方案是实现我的舍入方法如下。

    private double Rounding(double value, int Precision)
    {
        double result = value;
        if (result.ToString().EndsWith("5"))
        {
            var power = result.ToString().LastIndexOf("5") - 1;
            if (power > Precision)
            {
                result = result + (1 / Math.Pow(10, power));
            }
        }
        result = Math.Round(result, Precision);
        return result;
    }