繁体   English   中英

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

[英]Getting different result in Math.Round

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种​​不同的结果

这是浮点数不能精确表示小数旧情况

您似乎在这里处理金钱,然后您真的应该考虑使用小数

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));

简单的答案是由于使用浮点数的方程中的舍入误差。 这是因为,通常,由于没有精确的浮点数二进制表示形式,因此您得到的只是近似值。

我注意到您已经:

(percentageToRefund * 0.01)

在第一个方程式中,以及:

(percentageToRefund * 0.01) * 100

在第二。

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

如果您要处理金钱,则应使用decimal类型(假设使用C#)

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

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

我建议阅读Wikipedia上的文章以获取更多详细信息: Wiki链接

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM