2010-07-28 96 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