在做一些像$ price =(int)((0.1 + 0.7)* 10)这样的事情时要采取什么预防措施;得到7作为答案

时间:2009-05-17 02:10:30

标签: floating-point integer

PHP中的

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

或在Ruby中

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

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

3 个答案:

答案 0 :(得分:7)

如果您想要准确的答案,请不要使用浮点数学。如果你总结价格使用定点算术。如果您的最小值为1美分,则将所有价格视为美分。

答案 1 :(得分:2)

使用舍入而不是仅取数字的整数部分(.to_i或(int)正在执行)。在PHP中,您可以使用:

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

我确信Ruby有类似的功能,我只是不知道它叫什么。

答案 2 :(得分:1)

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

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

但正如史蒂文指出的那样,浮点运算可能非常不准确。为了提高Ruby的准确性,您可以使用BigDecimal

a = BigDecimal.new("0.1")
b = BigDecimal.new("0.7")
((a+b)*10)  #=> returns a BigDecimal with a value of 8.0

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