關於java中浮點數中Infinity和NaN的解釋

引言

我們都知道計算機是用二進制表示數據,那浮點數計算機是怎麼表示的那?

1.0/0的結果是什麼?爲什麼?
0/0的結果是什麼?爲什麼?
0.0/0.0的結果是什麼?爲什麼?

先說結論:

1)1.0/0的結果是什麼?爲什麼?
    1.1 結果:Infinity
    1.2 原因:①1/0.1=10 ②1/0.01=100 ③1/0.001=1000,所以分子確定時,分母越小商越大,分母趨向於0時,商無窮大。對於java語言,手冊中也有提到加減運算的第一步就是零值檢測,如果涉及其中一個數是0,可以直接得出結果。


2)0/0的結果是什麼?爲什麼?
    2.1 結果:Exception / by zero
    2.2 原因:根據乘法與除法互爲逆運算可證,一是零做除數不能得到固定的商;二是零做除數還不回原。因此說:“零做除數沒有意義”或“規定零不能做除數”。1)中提到的java語言可適用


3)0.0/0.0的結果是什麼?爲什麼?
    3.1 結果:NaN
    3.2 原因:個人覺得還是java虛擬機自己搞的邏輯,目的就是用一個公式來模擬出這種Not a Number的值來,就像NaN轉成Long統一翻譯爲0xff800001一樣。底層應該是在零值檢測時處理的。爲什麼這樣說,因爲(0.0f == 0)是true,那0.0/0是不是就等於0/0,那爲什麼會有兩種結果。只有自己定義用來標示能解釋通的吧。
 

NaN是什麼?

        NaN是“IEEE 754”協議中規定了幾種特殊值,
        1. 第一種 指數是0並且尾數的小數部分是0,這個數±0(和符號位相關)
        2. 第二種 指數2e-1並且尾數的小數部分是0,這個數是±∞(同樣和符號位相關)
        3. 第三種 指數2e-1並且尾數的小數部分非0,這個表示爲不是一個數(NaN)
 這些方法也就對應了計算機內部的存儲,相對應的就是jdk中native longBitsToDouble()方法中
        <p>If the argument is any value in the range {@code 0x7f800001} through {@code 0x7fffffff} or in the range  {@code 0xff800001} through {@code 0xffffffff}, the result is a NaN.</p>
        <p>If the argument is {@code 0x7f800000}, the result is positive infinity.
        <p>If the argument is {@code 0xff800000}, the result is negative infinity.
        在計算機中歸根結底都是要通過0 1來表示,只不過定義的區間不同罷了,java中對NaN用一個Long型值表示 0x7fc00000,具體可參見JDK intBitsToFloat()方法,將一定區間內的值,轉化爲一個常量值。
 

NaN是怎麼產生的?

        NaN的產生還是要通過數學來求證,數學中求這個公式的值x/[x*cos(1/x)],當x趨向於0的時候,利用洛必達法則可推導出這個公式的結果是不存在的,因爲cos(1/x)的極限不存在,所以上下不能比較。在代碼中乘除的運算都是對應的加減被除數,《碼出高效:java開發手冊》中提到,加減運算是第一步就是零值檢測,檢查參加運算是否存在爲0的數。

        推測java虛擬機就是在這一步進行的處理,python中使用0.0/0.0會的到一個ZeroDivisionError: float division by zero,並不是NaN,這樣表示float('nan')的時候纔會提示NaN。

 

觸發的情況

      1. 至少有一個參數是NaN的運算
      2. 不定式
            2.1 下列除法運算:0/0、∞/∞、∞/−∞、−∞/∞、−∞/−∞
            2.2 下列乘法運算:0×∞、0×−∞
            2.3 下列加法運算:∞ + (−∞)、(−∞) + ∞
            2.4 下列減法運算:∞ - ∞、(−∞) - (−∞)
      3. 產生複數結果的實數運算。例如:
            3.1 對負數進行開偶次方的運算
            3.2 對負數進行對數運算
            3.3 對正弦或餘弦到達域以外的數進行反正弦或反餘弦運算

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