2010-07-28 97 views
2

我正在初始化一个测试两个公式相等的类的实例。Ruby中的操作顺序问题

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

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 

为什么不红宝石取FW公式1和公式2的值,并检查这些值的相等性? Ruby中的操作顺序是什么?Ruby在做什么?我可以看到我对这个问题缺乏了解。我该如何做这项工作?先谢谢你。

回答

3

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

试试这个在IRB:

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

所以,你会发现像0.00001,你觉得会处理浮点运算的任何变化的增量,并用这种方式。你永远不应该==浮游物。

+0

你会用什么而不是浮点比较?在化学中,我可能需要的最具特异性是0.00001;在数学运算中使用浮点数有什么好处吗? – 2010-07-28 19:52:17

+1

使用浮点而不是其他类型没有明显的优势,并且要非常精确,您还必须考虑重要数字并处理舍入问题。然而,将所有数据乘以10k并使用整数运算也是有问题的,所以我现在会坚持使用浮点数。如果您需要的最高精度是.00001,那么处理比较的最佳方法是通过我上面描述的方法,使用(x-y).abs <0.000001左右作为您的最大平均值。错误通常超出1e-9范围,所以这可以。 – drharris 2010-07-28 21:03:22

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