ruby浮点错误

时间:2010-10-29 20:26:29

标签: ruby floating-point

有人可以解释为什么乘以100会得到不太准确的结果,但乘以10会得到更准确的结果吗?

± % sc
Loading development environment (Rails 3.0.1)
>> 129.95 * 100
12994.999999999998
>> 129.95*10
1299.5
>> 129.95*10*10
12995.0

3 个答案:

答案 0 :(得分:24)

如果你手动进行双精度二进制计算(限制为53位有效位),你会看到发生了什么:

129.95 = 1.0000001111100110011001100110011001100110011001100110 x 2 ^ 7

129.95 * 100 = 1.1001011000010111111111111111111111111111111111111111011 x 2 ^ 13

这是56位有效位,所以四舍五入为53位

1.1001011000010111111111111111111111111111111111111111 x 2 ^ 13,等于

12994.999999999998181010596454143524169921875

现在129.95 * 10 = 1.01000100110111111111111111111111111111111111111111111 x 2 ^ 10

这是54位有效位长,所以舍入到53位,它是1.01000100111 x 2 ^ 10 = 1299.5

现在1299.5 * 10 = 1.1001011000011 x 2 ^ 13 = 12995。

答案 1 :(得分:4)

首先关闭:您正在查看结果的字符串表示形式,而不是实际结果本身。如果确实想要比较两个结果,则应使用String#%显式格式化两个结果,并且应该以相同的方式格式化两个结果。

其次,这就是二进制浮点数的工作原理。它们是不精确的,它们是有限的,它们是二元的。这三个意味着你会得到四舍五入的错误,这通常看起来是完全随机的,除非你碰巧记住整个IEEE754并且可以在你的睡眠中背诵它。

答案 2 :(得分:2)

没有完全等于129.95的浮点数。所以你的语言使用的是一个接近它的值。当该值乘以100时,结果接近12995,但它恰好不等于12995.(它也不完全等于它用来代替129.95的原始值的100倍。)因此,您的解释器会打印一个十进制数字,该数字接近(但不等于)129.95 * 100的值,并显示它不完全是12995.结果129.95 * 10也是如此。完全等于1299.5。这主要是运气。

底线是,永远不要指望任何浮点运算的平等,只是“接近”。