2012-02-18 29 views
25

爲什麼這個比較會給我'錯誤'?我看了看源的Float.NaN被定義爲Float.NaN == Float.NaN

/** 
* A constant holding a Not-a-Number (NaN) value of type 
* <code>float</code>. It is equivalent to the value returned by 
* <code>Float.intBitsToFloat(0x7fc00000)</code>. 
*/ 
public static final float NaN = 0.0f/0.0f; 

編輯:奇怪的是,如果我這樣做:

System.out.println("FC " + (Float.compare(Float.NaN, Float.NaN))); 

它給了我0。所以Float.compare()確實認爲NaN 等於自己!

回答

32

由於Java實現這保證了對NaN任何比較將返回false的IEEE-754浮點標準(除!=返回true)

這意味着,你不能在你平時的方式檢查是否浮動點編號爲NaN,所以你既可以重新解釋這兩個數字爲整數,並比較它們或使用的要聰明得多的解決方案:

def isNan(val): 
    return val != val 
+5

除'!='比較之外,它們返回'true'。 – 2012-02-18 13:40:09

+3

你可以用這種方式測試NaN!如果'x == x'爲false,那麼x是NaN。 – 2012-02-18 13:41:19

+0

@Daniel Ups對不起,您好!簡化得太多了。 – Voo 2012-02-18 13:45:03

53

使用Float.isNaN檢查NaN值。

+6

+1更好的解決方案,但很差的解釋! – 2013-10-11 19:19:39

+1

@Rolfツ沒有什麼要補充的,它非常簡單。 – Flawyte 2015-01-09 19:46:52

-1

我需要說的是:Wikipedia About NaN

它寫的很清楚。有趣的是,該共同標準的浮點NaN的表示NaN的是這樣的:

S111 1111 1XXX XXXX XXXX XXXX XXXX XXXX

的s爲符號(正或負), 1是指數,x被認爲是有效載荷。

看看有效負載,NaN不等於任何NaN,並且這些負載的這些信息對於您作爲開發人員(例如複數)來說很有趣。

另一件事是,在標準他們有信號和相當NaN。信號NaN(sNaN)是指應該引發反應的NaN,例如異常。應該用它來大聲說出你的等式中有問題。一個安靜的NaN(qNaN)是一個無聲無息的NaN。

創建信號的sNaN被轉換爲qNaN,以便在後續操作中不再產生更多信號。記住一些系統將i^0 = 1定義爲NaN^0 = 1成立的常數。所以有些情況下人們用NaN進行計算。

所以最後我會用這個:qNaN!= sNaN,但是這是內部的,並且對於用戶來說是不可觀察的(你不能檢查那個)。沿着付款和標誌混合(是的,你可以有負面和正面的NaN),在我看來,總是迴歸NaN!= NaN看起來像一個更明智的選擇,我終於學會欣賞 - >我永遠不會抱怨或懷疑關於NaN的不平等。讚美那些給予我們這麼好的標準的人!順便說一下:Java使用一個有效載荷爲0(所有x都爲零)的正數NaN。

+0

複數與有效載荷有什麼關係? – 2015-09-23 17:33:19