Ruby Float问题

时间:2013-02-01 22:41:06

标签: ruby floating-point

我有一个系统正在运行一堆计算,出于某种原因,每次0.07显示它显示为0.07000000000000001

我很清楚浮点数是近似值,但是我正在编写代码:

number = '%.2f' % ( num1 - num2 )
number.to_f

尽管如此,0.07000000000000001仍然会出现在我的代码中并最终导致数组排序失败:

sort! { |a,b| b <=> a }      <-- b equals 0.07000000000000001 and a equals 0.08

它引发了一个错误,说它无法比较这两个数字。关于如何解决这个问题的任何想法?

更新

所以看起来好像原始值是0.07351923338974675,此时我调用.round(2)。然后我暂时将它存储在Redis中,然后将其拉出来。当它运行计算时,它最终显示为0.07000000000000001。听起来整数比较在这里可能是最好的,除非有另一种解决方案。

1 个答案:

答案 0 :(得分:2)

所有数字都是有序的,但是String不能对数字进行有序比较,只能进行相等比较以查看它们是否是同一个对象。 (显然,这种比较总是会返回错误。)

我想这是你看到的错误类型,例如: ArgumentError:String与Float的比较失败

Float对象中的低位比特的问题可能会干扰您的排序,但提高实际异常似乎不太可能。与大多数十进制字符串分数一样,0.07在底层Float格式中没有精确表示。可以想象,获得0.07的不同方式(字面常量与计算结果)可能会导致每个稍微不同的值。

但是请注意,如果您尝试打印的数字比实际数量更多,您将看到最后一位的剩余部分。这些数字可以是非零,但它们不会告诉您有关您的号码的任何有用信息。

最安全的做法是缩放到整数值,调用#to_i,并比较整数。