Floating point 在执行诸如$price=(int)((0.1+;0.7)*10)之类的操作时应采取哪些预防措施;答案是7

Floating point 在执行诸如$price=(int)((0.1+;0.7)*10)之类的操作时应采取哪些预防措施;答案是7,floating-point,integer,Floating Point,Integer,在PHP中 还是红宝石 echo (int) ( (0.1+0.7) * 10 ); 结果是7而不是8。要抓住这样的陷阱可能真的很难。我认为,如果在北美,这是一个小问题,因为我们计算的价格高达多少美分,所以17.28美元或17.29美元可能是一个小问题。但在像中国或香港这样的国家,价格只能是一个整数。在这种情况下,如果我们的程序很慷慨,只要求客户提供价格的整数部分,那么如果8变为7,就会出现问题。所以也许我们总是需要小心使用round()?任何其他方法都可以避免这个陷阱吗?使用舍入,而不是只取

在PHP中

还是红宝石

echo (int) ( (0.1+0.7) * 10 );

结果是7而不是8。要抓住这样的陷阱可能真的很难。我认为,如果在北美,这是一个小问题,因为我们计算的价格高达多少美分,所以17.28美元或17.29美元可能是一个小问题。但在像中国或香港这样的国家,价格只能是一个整数。在这种情况下,如果我们的程序很慷慨,只要求客户提供价格的整数部分,那么如果8变为7,就会出现问题。所以也许我们总是需要小心使用round()?任何其他方法都可以避免这个陷阱吗?

使用舍入,而不是只取数字的整数部分(这是.to_i或(int)所做的)。在PHP中,您可以使用:

p ((0.1+0.7) *10).to_i

我确信Ruby也有类似的函数,我只是不知道它叫什么。

如果你想要精确的答案,不要使用浮点数学。如果你计算价格的总和,使用定点算法。如果你的最小价值是一美分,那么把所有价格都当作美分

Ruby版本的
round
方法的工作原理如下:

echo round((0.1+0.7)*10);
但正如史蒂文指出的,浮点运算可能会令人震惊地不准确。为了提高Ruby的准确性,您可以使用
BigDecimal

((0.1+0.7)*10).round  #=> 8

BigDecimal实例是从字符串而不是浮点数初始化的。因此,
.to_
调用上述函数。

依赖
0.1.to_
给出
“0.1”
在概念上是个坏主意,即使在Ruby中总是正确的。仅仅写下
“0.1”
会安全得多。
a = BigDecimal.new("0.1")
b = BigDecimal.new("0.7")
((a+b)*10)  #=> returns a BigDecimal with a value of 8.0