Ruby 为什么这种比较失败?

Ruby 为什么这种比较失败?,ruby,floating-point,Ruby,Floating Point,知道为什么会这样吗a是一个大的十进制数 a # => 87.6 (word_count * b).to_f # => 87.6 a.to_f == (word_count * b).to_f # => false 我找到的使其按我所需工作的最佳解决方案是: a.to_s.to_f 铸造。要截断数字,还有其他方法,如: "%.2f" % a 或 我将向你解释为什么会发生这种情况,这是最初的问题

知道为什么会这样吗<代码>a是一个大的十进制数

a                               # => 87.6
(word_count * b).to_f           # => 87.6
a.to_f == (word_count * b).to_f # => false

我找到的使其按我所需工作的最佳解决方案是:

a.to_s.to_f
铸造
。要截断数字,还有其他方法,如:

"%.2f" % a


我将向你解释为什么会发生这种情况,这是最初的问题

这里首先要了解的是,在
irb
上显示为return的是对字符串的转换。例如:

class A
  def to_s
    "return value"
  end
end
A.new
=> return value
此外,
.to_s
方法与比较方法无关。他们有两种不同的实现

所以你可以有这样的东西:

class A
  def to_s
    "87.6"
  end
end

class B
  def to_s
    "87.6"
  end
end

A.new
=> 87.6
B.new
=> 87.6
A.new == B.new
=> false
浮点数真的很难比较。发件人:

根据IEEE标准的定义,浮点数的比较与通常的整数比较略有不同。负零和正零比较相等,每个NaN比较不相等于每个值,包括它本身。除NaN之外的所有值都严格小于+∞ 并且严格地大于−∞. 有限浮点数的排序方式与其值(在实数集合中)相同

粗略地说,IEEE二进制浮点数的位表示与其基2对数成正比,平均误差约为3%。(这是因为指数字段位于数据的更重要部分。)这可用于某些应用,例如数字声音处理中的音量渐变


因此,作为个人观点,最好的事情是永远不要比较浮点数的相等性。这将避免将来出现一些警告,即使您现在的逻辑是正确的。我建议在比较之前先将其截断或四舍五入。

我会非常谨慎地使用等式来比较浮点数。浮点数的性质使得它们不精确,因此两个应该相等的数字可能会相差很小。尝试类似于
(a.to_f-(word_count*b).to_f).abs<0.01
请参阅(和许多类似文章)尝试查看1.0000000000000000000000000001在您的控制台中显示为什么,您将更好地了解发生了什么。如果您只是想比较所看到的内容,那么调用
到\u s
而不是
到\u f
可能会更好。
class A
  def to_s
    "87.6"
  end
end

class B
  def to_s
    "87.6"
  end
end

A.new
=> 87.6
B.new
=> 87.6
A.new == B.new
=> false