1. 程式人生 > 實用技巧 >浮點數在計算機中的表示

浮點數在計算機中的表示

接上一篇部落格《為什麼會有補碼?》,我僅僅分析了整數在計算機中表示方式,但是計算機中的浮點數又是如何表示的呢?

引子

首先,使用之前部落格的程式,可以看到如下的這些實數在計算機中的計算結果是

實際數值 數值型別 計算機中的表示
102.3235 float 42CCA5A2
-3.256 float C050624E
120.254 double 405E104189374BC7
-56.2441 double C04C1F3EAB367A10

右邊的計算機中的數值表示是按照《IEEE 754-2008》的標準儲存資料的,具體的規定如下所示。

IEEE 754 標準

表示形式

IEEE 754 規定了二進位制浮點數在計算中的儲存方式,我們以 C 語言中的 float 為例來具體說明。無論是 32 位系統還是 64 位系統,計算機中的 float 佔用 4 個位元組,我們就使用這些位元組來儲存任意的浮點數,可以參考下圖

轉化成對應的數學表示形式,浮點數 VV

\[V = (-1)^s\times M\times 2^E \]

  • ss 表示符號位,佔據 1 個 bit 位,如果是負數則 s=1s=1,如果是非負數則 s=0s=0;
  • MM 表示 mantissa,佔據 23 個位元,表示有效數字,表示的數字介於 1 和 2 之間;
  • EE 為非負整數,表示基於 2 為基數的指數大小,佔據 8 個位元。

因此,如果確認了上面 3 個引數,也就唯一確定了浮點數在計算機中的儲存形式。我們以102.3235為例,來看看上面的這幾個數字是如何表示出來的?

  1. 102.3235的二進位制原碼形式是1100110.01010010110100001110 = 1.10011001010010110100001110*2^6
  2. 確認 ss。因為是正數,因此 s=0s=0。
  3. 確認 MM。MM 表示1.xxxxxx之後的xxxxxx的部分,即計算機內部儲存 MM 時,預設表示的第一位總是 1,可以捨棄表示 1 的這一位,而僅僅儲存小數點之後的部分。因此 M=10011001010010110100001110M=10011001010010110100001110,因為只能儲存 23 個位元,將多餘的位數部分截斷得到 M=10011001010010110100001M=10011001010010110100001。
  4. 確認 EE。它是個肺腑正數,按照第 1 步計算出來的結果,我們的指數應該是 6。但是,IEEE 規定根據二進位制計算浮點數時,需要給指數減去一個偏置值,對於 float 型別這個數為 127,對於 double 型別,這個數是 1023。因此反過來,在將數字轉換成二進位制儲存的時候,要加上這個偏置值,因此 E=6+127=133E=6+127=133。
  5. 綜合以上的所有計算結果,最後在計算機中儲存的形式是01000010110011001010010110100001,轉換成 16 進位制就是42CCA5A2

特別規定

依照上面的方法,可以依次確認其他 3 個浮點數的表示形式。這都是比較常規的規格化資料的處理方法,IEEE 針對一些特殊的數字(絕對值特別接近 0 的數字或者無窮大無窮小),引入了一些特殊的規定,稱為非規格化表示方法,總結如下。

  • 規格化資料。如果指數部分既不是 0 也不是 255(EE 不全為 0 或者不全為 1),就是規格化儲存方式,具體的計算方法與之前介紹的相同。
  • 非規格化資料。EE 全為 0 就是非規格化的資料,此時的指數固定為 1-127 或者 1-1023,有效數字 MM 的計算不再捨棄第一位的 1,而是 0.xxxxxxxx 的小數部分,這樣就可以表示 0 和非常接近 0 的小數字。需要注意的是,0 有兩種表示。
  • 特殊數字。EE 全為 1 表示特殊的數字
    • 如果 MM 全為 0,表示無窮大,正負取決於符號 ss;
    • 如果 MM 不全為 0,表示這是一個非數 NaN(Not a Number)。

精度誤差及表示範圍

如果明白之前的內容,那就可以計算出來每種表示方法的取值範圍以及表示的資料誤差。在計算之前,有如下的一些假設:

  1. 正數和負數的表示方法是對稱的,因此我們僅僅關注正數即可;
  2. 不考慮特殊值的計算,因為其僅僅是計算了不同幾個數值,沒有計算的價值。

如果需要計算最大的規格化數字,那麼其在記憶體中的表示應該是 s=1,M=1.11…1,E=111…10s=1,M=1.11…1,E=111…10,最後的結果就是 1.1111…1×2127=3.4×10381.1111…1×2127=3.4×1038,其他的基本可以推測出來了,如下表所示

參考資料