0

我有一个运行大量计算的系统,由于某种原因,每次 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。听起来整数比较在这里可能是最好的,除非有替代解决方案。

4

1 回答 1

2

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

我想这是您看到的错误类型,例如:ArgumentError: comparison of String with Float failed

Float 对象中的低位问题可能会干扰您的排序,尽管引发实际异常似乎极不可能。像大多数十进制字符串分数一样,0.07在底层浮点格式中没有精确的表示。可以想象,不同的获取方式0.07(字面常量与计算结果)可能会导致一个非常不同的值。

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

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

于 2013-02-01T23:18:04.203 回答