2

我正在初始化一个测试两个公式是否相等的类的实例。

该公式的计算值实际上是相等的:

RubyChem::Chemical.new("SOOS").fw
=> 96.0

RubyChem::Chemical.new("OSSO").fw
= 96.0

当我创建一个新类来检查这两个实例的相等性时,我对结果有点惊讶:

x = RubyChem::BalanceChem.new("SOOS","OSSO")
x.balanced
=>false

y = RubyChem::BalanceChem.new("SOOS","SOOS")
y.balanced
=> true

RubyChem::BalanceChem 初始化方法在这里:

def initialize(formula1, formula2)
  @balanced = RubyChem::Chemical.new(formula1).fw == RubyChem::Chemical.new(formula2).fw
end

为什么 ruby​​ 不获取公式 1 和公式 2 的 fw 值并检查这些值的相等性?Ruby 中的操作顺序是什么,Ruby 在做什么?我可以看到我对这个问题缺乏了解。我怎样才能使这项工作?先感谢您。

4

3 回答 3

4

Ruby 1.8在将 float 转换为 string 时存在错误。有时给定的字符串不能很好地表示浮点数。这是一个例子0.56

0.5600000000000005.to_s == 0.56.to_s  #=> true
# should have returned false, since:
0.5600000000000005      == 0.56       #=> false

这就解释了为什么两个看似相同的结果实际上并不相同。

您可能希望在一定的误差范围内进行比较,在进行比较之前进行一些舍入,或者使用像BigDecimalor之类的确切类型Rational

于 2010-07-28T20:34:31.620 回答
3

您可能不想检查浮点数是否相等。相反,您应该比较增量。

在 irb 中试试这个:

x = 1.000001
y = 1.0
x == y
(x-y).abs < 0.00001

因此,您会发现一个像 0.00001 这样的增量,您认为它可以处理浮点运算中的任何变化,并以这种方式使用它。你永远不应该==漂浮。

于 2010-07-28T17:35:00.820 回答
2

这可能是浮点精度引起的另一个问题。

我可以向您保证,在评估相等性之前计算的那些值。

查看 Ruby 的运算符优先级

于 2010-07-28T17:20:23.600 回答