我有一个系统正在运行一堆计算,出于某种原因,每次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。听起来整数比较在这里可能是最好的,除非有另一种解决方案。
答案 0 :(得分:2)
所有数字都是有序的,但是String不能对数字进行有序比较,只能进行相等比较以查看它们是否是同一个对象。 (显然,这种比较总是会返回错误。)
我想这是你看到的错误类型,例如: ArgumentError:String与Float的比较失败。
Float对象中的低位比特的问题可能会干扰您的排序,但提高实际异常似乎不太可能。与大多数十进制字符串分数一样,0.07
在底层Float格式中没有精确表示。可以想象,获得0.07
的不同方式(字面常量与计算结果)可能会导致每个稍微不同的值。
但是请注意,如果您尝试打印的数字比实际数量更多,您将看到最后一位的剩余部分。这些数字可以是非零,但它们不会告诉您有关您的号码的任何有用信息。
最安全的做法是缩放到整数值,调用#to_i,
并比较整数。