IEEE754浮點數標准學習
因為不太理解書上關於這一段的描述,可能是沒有認真看,故寫了這篇文章,邊看邊做記錄。
浮點數的表示
當然在講之前,我們首先講一下關於浮點數的表示格式。對於任意的實數\(X\),可以表示為如下的形式
其中,\(S\)的取值為0或者1,一般為0為正,1表示負數。
\(E\)是一個二進制定點整數,稱為\(X\)的階碼或者指數
\(M\)是一個二進制定點小數,稱為\(X\)的尾數
\(R\)是基數,可以約定俗稱的設置為2,4,16等
要確定一個實數的值,只要在默認基數\(R\)下,確定數符\(S\)、尾數\(M\)和階碼\(E\)就可以了
舉個具體的例子
將十進制數65798轉換為IBM370的32位短浮點數格式。
第0位為數符S;
第1~7位為7位移碼表示的階碼E;
第8~31位為6位十六進制原碼小數表示的尾數M
階碼的偏置常數=64
基\(R\)=16
解:
因為\((65789)_{10}=(10106)_{16}=(0.101060)_{16}*16^5\)
所以數符\(S=0\)
階碼\(E=(64+5)_{10}=(69)_{10}=(100 0101)_2\)
所以表示形式為如下
0 1000101 0001 0000 0001 0000 0011 0000
換成16進制即為
45 10 10 60H
對於給定的IBM370的32位浮點數的求解,就是這個編碼過程的逆過程,步驟如下:
- 數符\(S=0\),符號位正號
- 階碼\(E=(1000101)_2=(64+5)_{10}\)
- 尾數\(M=(101060)_{16}\)
- 故原十進制數\(X=M^5=(65789)_{10}\)
以上就是浮點數表示的例子,但是在表示浮點數的時候要注意以下幾點:
- 0的表示問題
- 浮點數的密度問題
- 表示精度和表示范圍的權衡
具體問題在教材中已經詮釋的很清楚,這里不做贅述。
IEEE754浮點數標准
首先,對於IEEE754浮點數標准,目前幾乎所有計算機都采用這個標准,並在這個標准中,提供了兩種基本浮點數格式:
- 32位單精度
- 64位雙精度
浮點數格式 | 符號 | 階碼 | 尾數 |
---|---|---|---|
32位單精度格式 | 1 | 8 | 23 |
64位雙精度格式 | 1 | 11 | 52 |
對於IEEE754標准,基數隱含為2。尾數用原碼表示,第一位總為1,所以可以省略第一位,使得單精度的23位實際表示了24位,雙精度的52位,實際表示了53位。
在這這里我有一個疑問,為什么第一位總為1?
我的理解:
因為基數隱含為2,所以對於任意的二進制正數的移碼都可以被表現為如下的形式\[1.XXX*2^M \]對於所有的二進制數都可以表示為這樣的形式
當然這個問題在接下來的一句話就說明了,IEEE754規定隱藏位1的位置在小數點之前。
在在IEEE754標准中,階碼用移碼表示,但偏置常數並不是通常n位移碼所用的\(2^{n-1}\),而是\(2^{n-1}-1\),故而單精度的偏置常數為127,雙精度的偏執常數為1023.
由於隱藏了小數點前1的原因,如果換成等值純小數表示的話,階碼就需要加1.但是無論是哪一種,最終的計算結果和偏置常數的情況是相同的。並且,使尾數帶一個隱藏位,有以下的兩點好處:
- 尾數可以多一位,故精度可以更高
- 階碼的表示范圍可以更大,因而使浮點數的范圍更大
具體的IEEE754各種數的解釋,在書上已經列的非常詳細了,對於規定的數,大概可以分類為如下:
-
全0階碼全0尾數:+0/-0
IEEE754的0有兩種表示:+0和-0。0的符號取決於數的符號位s。一般情況下是等效的。 -
全0階碼非0尾數:非規格化數
非規格化數的特點就是階碼部分全為0,尾數的高位有一個或者連續幾個0,但不全為0。因為隱藏位為0,並且單精度和雙精度浮點數的階碼的值分別為-126或者-1022,故數值可以為
或者,
非規格數的意義在於可以處理階碼下溢,使得出現比最小規格化數還小的數還能繼續進行下去。
為什么能處理階碼下溢?
因為規格化數的表現形式為
設階碼為\(e\),以單精度舉例,則規格化非零整數表示的值為\(2^{e-127}*(1.f)\)
顯然當\(e=1\)時,有最小\(2^{-126}*(1.f)\)
而非規格化整數則為\(2^{-126}*(0.f)\)
顯然能表示更小的數
非規格化數可用於處理階碼下溢,使得出現比最小規格化數還小的數時程序也能繼續進行下去。簡而言之就是尾數向右移動,階碼加1.
當一個十進制運算系統的最小階碼為-99時,有以下過程:
\(2.0000*10^{-26}*5.2*10^{-84}\)
\(=1.04*10^{-109}\)
→\(0.104*10^{-108}\)
→\(0.0104*10^{-107}\)
→\(0.0010*10^{-106}\)
→\(0.0001*10^{-105}\)
→\(0.0000*10^{-104}\)
→\(0.0\)以上就是一個逐級下溢的過程
-
全1階碼全0尾數:+∞/-∞
引入無窮大和無窮小使得在計算過程出現異常的情況下計算可以繼續下去,並且可以提供錯誤檢測的功能。+∞在數值上大於所有有限數,-∞則小於所有有限數,無窮大數既可作為操作數,也可能是運算的結果。當操作數為無窮大時,系統可以有兩種處理方式。- 產生不發信號的非數NaN
如+∞+(-∞),+∞-(+∞),∞/∞等。 - 產生明確的結果
如5+(+∞)=+∞,(+∞)+(+∞)=+∞,5-(+∞)=-∞,(-∞)-(+∞)=-∞等
- 產生不發信號的非數NaN
-
全1階碼非0尾數:NaN(Not a Number)
表示沒有定義的數,稱為非數。分為不發信號和發信號兩種。
可以用非數表示每個變量的非初始化值 -
階碼非全0且非全1:規格化非0數
以上就是書上內容的簡略內容,不知是否表述清楚,但是在邊做筆記邊看書后,我確實能夠比較好的理解IEE754編碼。
以下舉具體的計算實例。
將十進制數-0.75轉換為IEEE754的單精度浮點數格式表示
解:
\((-0.75)_{10}=(-0.11)_2=(-1.1)_2*2^{-1}\)
所以\(s=1,f=0.100...0,e=(127-1)_{10}=(01111110)_2\)
規格化的表示方法為
1 0111 1110 1000 0000 0000 000 0000 000
16進制表示為
BF 40 00 00H