在Math.Round中获得不同的结果

时间:2009-10-22 11:45:38

标签: .net rounding

ticketPriceInPence = 7360
percentageToRefund = 100

(int)(Math.Round((ticketPriceInPence * 0.01) * (percentageToRefund * 0.01), 2, MidpointRounding.AwayFromZero) * 100)

结果为:73.59

(int)(Math.Round((ticketPriceInPence * 0.01) * (percentageToRefund * 0.01) * 100, 2, MidpointRounding.AwayFromZero))

结果为:73.60

知道为什么会产生不同的2种不同结果

5 个答案:

答案 0 :(得分:4)

浮点数的old case无法represent decimals exactly

你似乎在这里处理钱,然后你真的应该考虑使用decimal

decimal ticketPriceInPence = 7360;
decimal percentageToRefund = 100;
var result1 = (int)(Math.Round((ticketPriceInPence * 0.01m) * (percentageToRefund * 0.01m), 2, MidpointRounding.AwayFromZero) * 100);
var result2 = (int)(Math.Round((ticketPriceInPence * 0.01m) * (percentageToRefund * 0.01m) * 100, 2, MidpointRounding.AwayFromZero));

答案 1 :(得分:1)

简单的答案是,这是由于使用浮点数的方程中的舍入误差。这是因为,一般来说,没有浮点数的精确二进制表示,所以你得到的只是近似值。

我注意到你有:

(percentageToRefund * 0.01)

在第一个等式中,并且:

(percentageToRefund * 0.01) * 100

在第二个。

后一个表达式将导致舍入误差,因为您首先除以100然后再乘以100。输入不等于输出,差异取决于机器架构,操作系统,语言和编译器。

如果你正在处理钱,你应该使用decimal类型(假设C#)

答案 2 :(得分:0)

因为浮点数不是确切的数字。我建议阅读http://en.wikipedia.org/wiki/Floating_point。你会看到结果不同的原因。

答案 3 :(得分:0)

长话短说。这是因为将浮点值表示为二进制数据时的精度错误。这基本上意味着你无法用32/64位表示每个可能的浮点数,所以2.1实际上是2.1000000000000001等。这就是为什么你不应该做类似2.145 ==“其他值应该是2.145”的原因之一。

我建议您阅读维基百科上的文章以获取更多详细信息:Wiki Link

答案 4 :(得分:0)

这是由于浮点数的精度有限。

相关问题