1. 程式人生 > 實用技巧 >二進位制小數和IEEE浮點標準

二進位制小數和IEEE浮點標準

二進位制小數

首先複習進位計數制的要素:

  1. 數碼:用來表示進位制數的元素。比如

    • 二進位制數的數碼為:0,1
    • 十進位制數的數碼為:0,1,2,3,4,5,6,7,8,9
    • 十六進位制數的數碼為:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
  2. 基數:數碼的個數。比如

    • 二進位制數的基數為2
    • 十進位制數的基數為10
    • 十六進位制數的基數為 16
  3. 位權:數制中每一固定位置對應的單位值稱為位權。

    • 二進位制第2位的位權為\(2^1\),第3位的位權為\(2^2\):\((10010.1110)_2 = 1 * 2^4 + 0 * 2^3 + 0 * 2^2 + 1 * 2^1 + 0 * 2^0 + 1 * 2^{-1} + 1 * 2^{-2} + 1 * 2^{-3} + 0 * 2^{-4} = 16 + 2 + 1/2 + 1/4 + 1/8\)
    • 十進位制第2位的位權為\(10^1\),第3位的位權為\(10^2\):\((123.45)_{10}=1×10^2+2×10^1+3×10^0+4×10^{-1}+5×10^{-2}\)
    • 十六進位制第2位位權為\(16^1\),第3位的位權為\(16^2\):\((BAD)_{16} =11× 16^2+10×16^1+13×16^0=(2989)_{10}\)

    總結來說

    • 十進位製表示公式為:

    • 二進位製表示公式為:

  • 注意:二進位制小數不像整數一樣,只要位數足夠,它就可以表示所有整數。假設我們僅考慮有限長度的編碼,那麼二進位制小數無法精確的表示任意小數,比如十進位制小數0.2,我們並不能將其準確的表示為一個二進位制數,只能增加二進位制長度提高表示的精度。如下圖所示,二進位製表示十進位制的0.2只能無限接近,卻永遠無法精確表示0.2。

IEEE 浮點表示

於是為了在計算機中準確表示浮點數,IEEE指定了一條標準來規範表示浮點數,若不對浮點數的表示作出明確的規定,同一個浮點數的表示就不是唯一的。例如\((1.75)_{10}\)可以表示成\(1.11×2^0\),\(0.111×2^1\),\(0.0111×2^2\)等多種形式。

IEEE,電氣和電子工程師協會( 全稱是Institute of Electrical and Electronics Engineers)是一個國際性的電子技術與資訊科學工程師的協會,是目前全球最大的非營利性專業技術學會,IEEE 754 標準是IEEE二進位浮點數算術標準(IEEE Standard for Floating-Point Arithmetic)的標準編號。

浮點數的儲存格式

IEEE754 標準中規定:

  1. Float 單精度浮點數,用 1 位表示符號,用 8 位表示階碼,用 23 位表示尾數,一共32位。
  2. double 雙精度浮點數,用 1 位表示符號,用 11 位表示階碼,52 位表示尾數,一共64位。
  • 階碼:階碼是整數,階符和 m 位階碼的數值部分共同反映 浮點數的表示範圍及小數點的實際位置 ,常用移碼或補碼錶示。IEEE754標準中採用移碼的表示形式。

    • 移碼:移碼(又叫增碼)是對真值補碼的符號位取反,一般用作浮點數的階碼,引入的目的是便於浮點數運算時的對階操作。

  • 尾數:數符表示浮點數的符號,尾數的數值部分的位數 n 反映浮點數的 精度 ,常用原碼或補碼錶示。IEEE754標準中採用原碼的表示形式

浮點數的表示格式

浮點數表示法是指以適當的形式將比例因子表示在資料中,讓小數點的位置根據需要而浮動。這樣,在位數有限的情況下,既擴大了數的表示範圍,又保持了數的有效精度。

浮點數的真值為:

\[x=(−1)^S×2^e×M
\]

其中

  • S代表符號位,取值為0或1
  • e代表指數,E代表階碼
    • \(e=E-127(Float)\),\(e=E-1023(Double)\)
    • \(E=e_移-1\)
    • 計算指數e時,對階碼E的計算採用原碼的計算方式,因此單精度浮點數(Float)的階碼E為8位的取值範圍是0到255。根據規定,階碼E既不全為0(數值0),也不全為1。
    • 所以單精度下8位階碼E的規格化的浮點數階碼範圍是1至254,因此指數e的範圍則為-126至127。
    • 雙精度下11位階碼E的規格化的浮點數階碼範圍是1至2046,所以指數e範圍為-1022至1023。
  • M代表尾數,決定浮點數的精度,它是一個二進位制小數,表示為\(M=1+f\)
    • 其中\(f\)是n 位的尾數所表示的小數值,滿足\(0\le f<1\),其二進位製表示為:\(\small {0.f_{n-1}f_{n-2}\cdot \cdot \cdot f_{1}f_{0}}\) ,也就是二進位制小數點在最高有效位的左邊。
    • 由於是\(1+f\),所以我們又可以看成\(\small {1.f_{n-1}f_{n-2}\cdot \cdot \cdot f_{1}f_{0}}\)
    • 所以尾數的範圍為\(1 \le M < 2\)

由上面的每個對應位置的範圍,我們可以求得

  • 單精度最小規格化正數為:\(x=(-1)^0×2^{-126}×1\)
  • 單精度最大規格化正數為:\(x=(-1)^0×2^{127}×(2-2^{-23})\)

例題

a:

0,01,其中0代表是正數,所以原碼和補碼相同,01→\(0*2^1+1*2^0=1\),所以階碼為+1

1.1001,其中1代表是負數,所以原碼為補碼末尾減一(1000),按位取反(0111),對應真值為-0.0111=\(-(2^{-2}+2^{-3}+2^{-4})=-\frac{7}{16}\)

所以\(a=2^1×(-0.0111)=2^1×(-\frac{7}{16})=-\frac{7}{8}\)

b:

0,01,對應真值為+1

0.01001對應真值為+0.01001=\(+(2^{-2}+2^{-5})=+\frac{9}{32}\)

所以\(b=2^1×(+0.01001)=2^1×\frac{9}{32}=\frac{9}{16}\)

規格化單精度浮點數

為了提高資料的表示精度同時保證資料表示的唯一性,需要對浮點數做規格化處理。

在計算機內,對非0值的浮點數,要求尾數的絕對值必須大於基數R(這裡R=2)的倒數,即\(|M|≥1/R\)

0.5規格化

0.5的二進位制為0.1

符號位S為0,指數為\(e=-1\)(為啥?我猜是因為0.1中1的最高位是-1),規格化後尾數為1.0(為啥?因為M最小為1.0)。

單精度浮點數尾數域共23位,右側以0補全,尾數域:

\[M=[000\ 0000\ 0000\ 0000\ 0000\ 0000]_2​
\]

階碼E:

\[E=[−1]_移​−1=[0111\ 1111]_2​−1=[0111\ 1110]_2​
\]

對照單精度浮點數的儲存格式,將符號位S,階碼E和尾數域M存放到指定位置,得0.5的機器碼:

\[0.5=[0011\ 1111\ 0000\ 0000\ 0000\ 0000\ 0000\ 0000]_2
\]

1.5規格化

1.5的二進位制為1.1

符號位為0,指數\(e=0\)(為啥?我猜是因為1.1中1的最高位是0),規格化後尾數為1.1(為啥?因為二進位制為1.1,所以M就是1.1,如果二進位制是1111,M就是1.111)。

尾數域M右側以0補全,得尾數域:

\[M=[100\ 0000\ 0000\ 0000\ 0000\ 0000]_2
\]

階碼E:

\[E=[0]_移-1=[1000 0000]_2-1=[0111 1111]_2
\]

得1.5的機器碼:

\[1.5=[0011\ 1111\ 1100\ 0000\ 0000\ 0000\ 0000\ 0000]_2
\]

5規格化

5的二進位制為101

符號位為0,指數為\(e=2\),規格化後尾數為1.01(為啥?因為二進位制為101,所以M就是1.01)。

單精度浮點數尾數域共23位,右側以0補全,尾數域:

\[M=[010\ 0000\ 0000\ 0000\ 0000\ 0000]_2
\]

階碼E:

\[E=[2]_移−1=[1000\ 0010]_2−1=[1000\ 0001]_2
\]

得5的機器碼:

\[5=[0100\ 0000\ 1010\ 0000\ 0000\ 0000\ 0000\ 0000]_2
\]

參考文獻

浮點數的表示 -- 基本格式、規格化、表示範圍_starter_____的部落格-CSDN部落格_浮點數規格化表示

詳解 浮點數的規格化表示_Hello.Aaric的部落格-CSDN部落格_浮點數規格化

浮點數表示_shuzfan的專欄-CSDN部落格_浮點數

IEEE754 浮點數的表示方法_Dablelv的部落格專欄-CSDN部落格_ieee 754