Ruby浮点精度

时间:2011-09-05 19:58:30

标签: ruby floating-point floating-accuracy

据我了解,Ruby(1.9.2)浮点数的精度为15位十进制数。因此,我希望舍入float x 到15位小数将等于 x 。对于这种计算,情况并非如此。

x = (0.33 * 10)
x == x.round(15) # => false

顺便说一句,舍入到16位返回true。

你可以向我解释一下吗?

2 个答案:

答案 0 :(得分:9)

部分问题是0.33在底层格式中没有精确表示,因为它不能用一系列 1/2 n 术语表示。因此,当它乘以 10 时,与 0.33 的数字略有不同。

就此而言, 3.3 也没有确切的表示。

第一部分

当数字没有精确的基数为10的表示时,在转换尾数中有信息的最低有效数字时会有一个余数。这个余数将传播到右边,可能是永远的,但它在很大程度上是毫无意义的。这个错误的明显随机性是由于同样的原因解释了你和Matchu注意到的明显不一致的舍入。这是第二部分。

第二部分

此信息(最右边的位)与单个十进制数字传达的信息不完全对齐,因此十进制数字通常略小于原始精度较大时的值。

这就是为什么转换可能会在15位数时舍入为1而在16位数时为0.x:因为较长的转换对于尾数末尾的位没有值。

答案 1 :(得分:2)

好吧,虽然我不确定Ruby如何在内部处理浮动的细节,但我知道为什么这个特殊的代码在我的盒子上失败了:

 > x = (0.33 * 10)
=> 3.3000000000000003
 > x.round(15)
=> 3.300000000000001

第一个浮点数保留16位小数,总共17位数,无论出于何种原因。因此,四舍五入会丢弃这些数字。