2016-07-08 54 views
2

如果我比較abc像這樣紅寶石可枚舉不能在分功能比較的BigDecimal的NaN

[a,b,c].min 

其中

a = BigDecimal.new("NaN") 
b = BigDecimal.new("NaN") 
c = BigDecimal.new("0.0") 

我得到:

ArgumentError: comparison of BigDecimal with BigDecimal failed 

但如果我是使用ruby的Enumerable的比較運算符然後我得到這個:

irb(main):001:0> a <=> b 
=> nil 

irb(main):002:0> a <=> c 
=> nil 

並沒有錯誤呈現。這是Ruby中的問題,還是我誤解了min,還有什麼我可以用來實現與不會爆炸的枚舉的min相同的效果?

+2

手動比較實際上不工作,因爲操作者宇宙飛船(<=>)是必需的,以返回'[-1,0,1]一個'以用作比較的。這就是爲什麼你看到比較失敗,因爲'nil'不是一個有效的結果。爲什麼你需要能夠找到包含'NaN'的數組的最小值?你能否拒絕這些價值觀? –

+0

我現在只是照顧任何'NaN'反饋。我們從API獲取這些數據,因此我無法訪問我們收到的數據。 – TheLegend

+0

在答案中增加了一些可能有所幫助的新信息。 – MarsAtomic

回答

1

從Ruby語言documentation

NaN被從未被視爲與任何其它的值,甚至NaN的 本身:

N = ::新的('楠)

n ==可0.0 - >零

n ==可N - >零

據我所知,NaN值的任何實例都是獨一無二的。

考慮以下代碼片段:

require 'bigdecimal' 

a = BigDecimal('NaN') 
b = BigDecimal('NaN') 

puts a == b 
puts a > b 
puts a < b 

你會得到false對於這些比較。 minmax依賴排序產生結果,並且如@phoffer指出的,sort根據第二個數字是否等於,大於或小於第一個數字,產生0,1和-1的值。

TL; DR:任何時候您在操作中使用NaN時,您都無法期待有意義的結果。

如果您正在使用的API返回NaN,那麼您至少可以通過檢測它來保護自己免受此類情況的影響。 NaN實際上是Float的一個實例,因此您可以使用nan?方法對其進行測試。

2.2.0 :002 > require 'bigdecimal' 
=> true 
2.2.0 :003 > a = BigDecimal('NaN') 
=> #<BigDecimal:7fae1b3bd050,'NaN',9(9)> 
2.2.0 :004 > a.nan? 
=> true 
+0

非常感謝。這有助於我看到實際發生的情況。併爲'.nan?'方法+1。 – TheLegend