【Java】Java中的NAN解析

今天在學習集合框架的時候,看源碼發現了一個不是很理解的問題(Float源碼):

    /**
     * Returns {@code true} if the specified number is a
     * Not-a-Number (NaN) value, {@code false} otherwise.
     *
     * @param   v   the value to be tested.
     * @return  {@code true} if the argument is NaN;
     *          {@code false} otherwise.
     */

    public static boolean isNaN(float v) {
        return (v != v);
    }

判斷isNan爲什麼是v != v ,what???這不是判斷兩個float是否相等麼?

我們仔細看一下上面的註釋:

如果指定的參數(float v入參)是NAN,返回true,否則就是false
NAN :Not-a-Number(不是一個數字)

從上面我們可以分析出來:意思就是兩個NaN用==比較的結果會得到false。

校驗一下:

float firstNan=Float.NaN;
float secoenNan=Float.NaN;
System.out.println("firstNan!=secoenNan = "+(firstNan!=secoenNan));


打印的結果:
firstNan!=secoenNan = true

到底什麼是NAN?我們查閱一下資料,維基百科上得到如下的結果:

 

有點晦澀,下面我們具體講解一下

1、什麼是NAN?

簡單地說,NaN是一個數字數據類型值,代表“不是數字”。NAN通常表示無效操作的結果,Java將floatdouble類型的NaN常量定義爲Float .NaN和Double.NaN

“ 持有類型爲double的非數字(NaN)值的常量。它相當於Double.longBitsToDouble(0x7ff8000000000000L)返回的值。”

“保持float類型的非數字(NaN)值的常量。它等同於Float.intBitsToFloat(0x7fc00000)返回的值。”

我們猜一下下面的結果:

運行代碼:

System.out.println("0 / 0 = " + (0 / 0));

是的,你猜對了ArithmeticException

輸出結果:

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.test.BaseTest.main(BaseTest.java:25)

現在猜猜輸:

運行代碼

System.out.println("0.0 / 0.0 = " + (0.0 / 0.0));

猜對了嗎?

0.0 / 0.0 = NaN

double和float所有的,對於Java中的其他數值數據類型,我們沒有這種類型的常量。

2、NAN的校驗與比較

在java中編寫代碼時,我們應該注意檢查輸入是否有效且在預期範圍內。在大多數情況下,NaN值不是有效輸入。因此,我們應該驗證輸入值不是NaN值並適當地處理這些輸入值。

NaN無法與任何浮動類型值進行比較。這意味着我們會得到虛假的涉及所有的比較操作的NaN(除“!=”爲此我們得到真正的)。

測試代碼如下

float Nan = Float.NaN;
System.out.println("(NaN == 1) = "+(Nan == 1));
System.out.println("(Nan > 1) = "+(Nan > 1));
System.out.println("(Nan < 1) = " + (Nan < 1));
System.out.println("(NaN != 1) = " + (Nan != 1));
System.out.println("(NaN == NaN) = " + (Nan == Nan));
System.out.println("(NaN > NaN) = " + (Nan > Nan));
System.out.println("(NaN < NaN) = " + (Nan < Nan));
System.out.println("(NaN != NaN) = " + (Nan != Nan));

得到結果如下;

(NaN == 1) = false
(Nan > 1) = false
(Nan < 1) = false
(NaN != 1) = true
(NaN == NaN) = false
(NaN > NaN) = false
(NaN < NaN) = false
(NaN != NaN) = true

在我們的代碼中校驗是否爲NAN值,我們可以使用:Float.isNaNDouble.isNaN方法來檢查這些值,這種方法易讀易懂。、

3、isNan()和isInfinite()的區別

NaN:非數值類型;

Infinite:無窮大(包含正無窮大、負無窮大);

總結:

在Java的計算中,在執行涉及float和double類型的操作時,可能會產生NaN值。一些浮點方法和操作產生NaN值而不是拋出異常。我們可能需要明確處理這些結果,我們可以使用:Float.isNaNDouble.isNaN方法來檢查;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章