2013-03-22 88 views
15

什麼是比較兩個浮點數值以獲得精確相等的優雅,可讀和非冗長的方法?檢查兩個浮點數/雙精度值是否相等

聽起來很簡單,它是一個邪惡的問題。該==運營商沒有得到楠完成工作,並且還具有零特殊處理:

(+0.0 == -0.0) -> true 
Double.NaN == Double.NaN -> false 

但我想,以確定是否兩個值是完全一樣的(但我不照顧針對不同的NaN模式,所以任何NaN ==任何其他NaN - > true)。

可以這個醜八怪一段代碼做到這一點:

Double.doubleToLongBits(a) == Double.doubleToLongBits(b) 

有沒有更好的方式來寫這個(並意圖明顯)?

+0

你不一天爲什麼你想這樣做。如果他們真的是浮點數,你的答案將不會有意義。 – Julian 2013-03-22 18:18:35

+0

@ Julian參見PeterLawrey的答案就是一個非常有意義的例子。然而,我的應用程序是一個對象的equals()方法,其中float是主鍵的一部分(不是我自己選擇的)。浮點通常無法直觀的假設,所以我很小心地覆蓋邊緣案例。 – Durandal 2013-03-25 10:53:16

+0

對不起,你不能做得更好,你的「醜陋的怪物片」已經是完美的了...... – 2013-03-25 11:36:16

回答

10

我想說,你已經擁有了最好的方法。它清楚地表明您對按位值表示值感興趣。您恰好將這些位轉換爲long作爲方便的64位類型,它沒有任何時髦行爲。

如果你不希望它頻繁出現在你的代碼庫做什麼,只是添加一個方法把它包起來:

public static boolean bitwiseEqualsWithCanonicalNaN(double x, double y) { 
    return Double.doubleToLongBits(x) == Double.doubleToLongBits(y); 
} 

請注意,根據您的問題,這確實不同的NaN值之間分化。如果您想在稍後的日期執行此操作,則需要使用Double.toRawLongBits

+0

Mhhh,你和彼得的答案都有他們的吸引力。爲了清楚起見,我認爲靜態助手會更好一些,因爲我可以對方法發表評論,任何人都會在這個問題上磕磕碰碰。儘管如此,仍在考慮一個好的方法名稱。 – Durandal 2013-03-22 14:48:07

22

您可以使用

Double.compare(a, b) == 0 

從Javadoc文檔的compareTo

  • Double.NaN通過這種方法被認爲比其他所有double值(包括Double.POSITIVE_INFINITY等於本身和更大)。
  • 該方法認爲0.0d大於-0.0d。
+0

那麼這兩個0的區別是否恰當呢? – 2013-03-22 14:26:15

+0

它會做NaNs。檢查-0和0 – 2013-03-22 14:27:05

+1

我剛剛檢查過。它的確如此。尼斯 - 雖然不*顯然*正確,我會說。 (我會直覺地預期*聲稱正數和負數是相等的,我更喜歡這個代碼,這使得它對於精確的比特感興趣。) – 2013-03-22 14:27:39

相關問題