ruby浮点错误

有人可以解释为什么乘以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 

如果您使用双精度二进制(仅限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。

首先,您正在查看结果的string表示forms,而不是实际结果本身。 如果你真的想比较这两个结果,你应该明确地格式化两个结果,使用String#% ,你应该以相同的方式格式化两个结果。

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

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

底线是,从来没有期望任何浮点算术的平等,只有“亲密度”。