Floating point 在执行诸如$price=(int)((0.1+;0.7)*10)之类的操作时应采取哪些预防措施;答案是7
在PHP中 还是红宝石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()?任何其他方法都可以避免这个陷阱吗?使用舍入,而不是只取
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