我使用了像Math.Round
这样的Math.Round(value, precision)
。精度为3.
当我用于值= 0.0015时,结果将为0.002
当我用于值= 0.0025时,结果仍为0.002
似乎当最后一位数字是偶数时,它将向下舍入,但当最后一位数字为奇数时它会向上舍入。
如何解决这个问题?
附加:在silverlight中,没有MidpointRounding
答案 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;
}