Java中如何比較浮點數是否相等

0.前言

所謂“相等”,有兩種理解,一種是浮點數的值相等,另一種是指對象相同。

1.值相等

浮點數能表示的精度是有限的,在計算過程中不可避免的會出現截尾而損失精度,而且傳感器等外部設備輸入的數據本身也有誤差,所以如果要判斷一個浮點數double_x是否等於0,用double_x == 0這樣的判斷是不合適的,如果double_x是一系列計算的結果或者是外部傳感器的輸入值,那麼它幾乎不可能是0,它大概率是一個接近0的小數,比如0.000002,那麼,這時候要比較double_x是否等於0,首先要明確自己的精度要求,比如因爲傳感器有誤差,小於0.001的數都可以認爲等於0,那麼就定義epsilon=0.001:

final double epsilon = 0.001;
if(Math.abs(double_x - 0) < epsilon)
{
    return true;
}

2.對象相同

判斷兩個double變量值嚴格相等,一般會直接用double_x == double_y來做比較,這樣做一般沒有問題,但是如果本意是比較兩個浮點數對象是否相同(double_x == double_y是比較兩個對象值是否嚴格相同),對象相同和值嚴格相等是不一樣的,原因是java遵循IEEE 754浮點數標準,在這個標準中規定NaN與任何值比較皆不等,如果double_xdouble_y的值都是NaN,這個時候他們是相同的對象,但double_x == double_y會返回false。解決方法是,判斷浮點數對象是否相同,要用Double.doubleToLongBits將double值轉換過後再比較

if(Double.doubleToLongBits(double_x) == Double.doubleToLongBits(double_y))

Double.doubleToLongBits說明:

Returns a representation of the specified floating-point value according to the IEEE 754 floating-point “double format” bit layout.
Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number.

If the argument is positive infinity, the result is 0x7ff0000000000000L.

If the argument is negative infinity, the result is 0xfff0000000000000L.

If the argument is NaN, the result is 0x7ff8000000000000L.

In all cases, the result is a long integer that, when given to the longBitsToDouble(long) method, will produce a floating-point value the same as the argument to doubleToLongBits (except all NaN values are collapsed to a single “canonical” NaN value).

發佈了25 篇原創文章 · 獲贊 19 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章