Ruby中的操作顺序问题

时间:2010-07-28 17:17:35

标签: ruby operator-precedence

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

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

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没有获取formula1和formula2的fw值并检查这些值的相等性? Ruby中的操作顺序是什么,Ruby正在做什么?我可以看到我对这个问题缺乏了解。我怎样才能做到这一点?提前谢谢。

3 个答案:

答案 0 :(得分:4)

Ruby 1.8有一个bug when converting floats to string。有时给定的字符串不是浮点数的良好表示。以下是0.56的示例:

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

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

您可能希望在某个误差范围内进行比较,在进行比较之前进行一些舍入,或者使用BigDecimalRational这样的确切类型。

答案 1 :(得分:3)

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

在irb中尝试:

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

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

答案 2 :(得分:2)

这可能是由floating point precision引起的另一个问题。

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

参见Ruby的operator precedence