二進制小數及 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。十進制數的基數為10。十六進制數的基數為 16.

    ③、位權:數制中每一固定位置對應的單位值稱為位權。例如十進制第2位的位權為101即10,第3位的位權為102即100;而二進制第1位的位權為20即1,第3位的位權為4,對於 N進制數,整數部分第 i位的位權為N(i-1),而小數部分第j位的位權為N-j

  那么我們可以說:每個數碼所表示的數值=該數碼值 * 所處位置的位權。

  

  

  比如十進制數:(123.45)10=1×102+2×101+3×100+4×10-1+5×10-2

    二進制數:(1010)2 =l× 23+0 × 22+l× 21+0 × 20=(10)10

    十六進制數:(BAD)16 =11× 162+10×161+13×160=(2989)10

   二進制小數(10010.1110)2 = 1 * 2+ 0 * 2+ 0 * 2+ 1 * 21 + 0 * 20 + 1 * 2-1 + 1 * 2-2 + 1 * 2-3 +  0 * 2-4 = 16 + 2 + 1/2 + 1/4 + 1/8 

   總結來說

    十進制表示公式:

    

    對於一個形式為bm....b0.b-1....b-n的二進制小數b來說,二進制表示公式:

    

  從上面的二進制公式我們可以看出,小數點向左移動一位,則相當於 (∑ 2* bi)/2。因為每一位的位權都*2-1;反過來,小數點向右移動一位,則相當於該數乘以2。

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

  

 

2、IEEE 浮點表示

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

   IEEE 浮點標准表示: V = (-1)s * M * 2E 

  ①、s 是符號位,為0時表示正,為1時表示負。

  ②、M為尾數,是一個二進制小數,它的范圍是0至1-ε,或者1至2-ε(ε的值一般是2-k次方,其中設k > 0)

  ③、E為階碼,可正可負,作用是給尾數加權。

   我們將浮點數的位划分為三個階段,分別對這些值進行編碼。

  一、一個單獨的符號位 s 直接編碼符號 s

  二、k 位的階碼字段 exp =ek-1ek-2...e1e0 編碼階碼E

  三、n 位小數字段 frac = fn-1fn-2...f1f0 編碼尾數 M,但是編碼出來的值也依賴於階碼字段的值是否等於0.

  一般來說,現在的編譯器都支持兩種浮點格式,一種是單精度,一種是雙精度。單雙精度分別對應於編程語言當中的float和double類型。其中float是單精度的,采用32位二進制表示,其中1位符號位,8位階碼以及23位尾數。double是雙精度的,采用64位二進制表示,其中1位符號位,11位階碼以及52位尾數。如下圖表示:

  

 

   如果給定了位 s 的表示,根據 exp 的值,被編碼的值可以分為三種不同的情況(最后一種情況有兩個變種)。下圖是單精度的情況:

  

  下面我們分別講解這三種情況(規格化、非規格化、特殊值)

   

3、規格化

   階碼E 的位模式exp既不全為0(數值0),也不全為1(單精度8位1,數值為255,雙精度11位,數值為2047)。

  這種情況下,階碼字段被解釋為以偏置形式表示的有符號整數。”偏置”的含義就是在原有的值的基礎上加上一個偏移量,對於階碼位數為k的情況來說,偏移量Bias = 2k-1-1。假設e是階碼的無符號數值,那么真實的階碼E = e - Bias。

  單精度階碼位數為8,則Bias = 127。由於8位階碼下的規格化的浮點數的階碼范圍是1至254,因此真實階碼的范圍則為-126至127。

  對於小數字段 frac = fn-1fn-2...f1f0 它的值 0<= f < 1。那么我們可以表示為0. fn-1fn-2...f1f0,也就是二進制小數點在最高有效位的左邊。當計算浮點數數值的時候,會在尾數值的基礎上加1,也就是真實的尾數M = 1 + f。因此我們可以把 M 看成一個二進制表達式為 1.fn-1fn-2...f1f0的數字。相當於我們省掉了1位二進制,形成了浮點數表示的約定,默認尾數的值還有一個最高位的1。

 

12.5=1100.1=1.1001*2的3次方=0 10000010  1001 0000000000000000000   (浮點數)

1、首先,十進制轉二進制:
整數部分 除二余數倒寫:
12: 12/2=6 余0 ;6/2=3 余0 ;3/2=1 余1 ;1/2=0 余1
倒寫 也就是:1100
小數部分 乘二取整順寫:
0.5: 0.5×2=1.0
取整 也就是:1
12.5的二進制:1100.1
2、然后將二進制轉化為浮點數:
由於12.5為正數,所以符號位為0;
1100.1=1.1001×2^3 指數為3 ,
則 階碼=3+127=130 ,即:10000010

 

   

4、非規格化的值

   當階碼域為全 0 的時候,所表示的數就是非規格化形式。

  按照上面規格化的階碼求值方式來說,非規格化的階碼值應該固定在-Bias這個值上面。不過這里有一個小技巧,我們設定階碼的值E = 1 - Bias。這樣做是為了能夠平滑的從非規格化的浮點數過渡到規格化的浮點數,有關這一點后面我們再詳細看。

  對於尾數的解釋,非規格化的方式與規格化不同,它不會對尾數進行加1的處理,也就是說,真實的尾數M = f。這是為了能夠表示0這個數值,否則的話尾數總是大於1,那么無論如何都將得不到0這個數值。

  非規格化的浮點數除了可以表示0以外,它還有一個作用,就是可以表示接近於0的數值。另外,在浮點數當中,0的表示有兩種,一種是位表示全部為0,則為+0.0。還有一種則是符號位為1,其余全為0,此時為-0.0。

 

5、特殊值

  特殊值是指階碼全為 1 的時候出現的。

  在階碼全為1時,如果尾數位全為0,則表示無窮大。符號位為0則表示正無窮大,相反則表示負無窮大。倘若尾數位不全為0時,此時則表示NaN,表示不是一個數字。一些運算的結果不能是實數或者無窮,就會返回NaN值,比如正無窮減正無窮,-1的根號值。在某些應用中表示未初始化的值,也很有用處。這一點在Javascript當中有一個函數isNaN()與這個NaN的含義有點類似,它的作用是用來判斷一個參數或者表達式是否是一個數字。

 

6、數值范圍

  注意:由於浮點數在正負的區間內是一一對應的,因此我們將忽略符號位對取值范圍的影響,我們只討論符號位為0的情況。

  非規格化

  ①、最小的正非規格化值的位表示,是由最低有效位為 1 而其他所有位為 0 構成。它具有小數(尾數)值 M=f=2-n 和階碼值 E= -2k-1+2。因此它的數字值是 V= 2-n * 22 - 2k-1 = 2-n+2 - 2k-1

  ②、最大的非規格化值,全為0的階碼字段和全為1的小數字段組成。此時的小數(尾數)值 M=f=1-2-n,階碼 E=  -2k-1 +2,因此此時的值為 (1 - 2-n) * 22 - 2k-1

  規格化

  ①、最小的正規格化值,階碼字段的最低有效位為1,其它位為0,。它的尾數值 M = 1。階碼值 E= -2k-1 +2。因此數值 V = 22 - 2k-1

  ②、最大的規格化值,符號位為0,階碼最低有效位等於0,其它位等於 1,尾數為n個1。它的小數值 f=1-2-n,尾數 M= 2 - 2-n,此時的值為(2 - 2-n) * 2-1 + 2k-1,也可以化簡一下為(1 - 2-n-1) * 22k-1

  下面我們看一下非負浮點數單雙精度取值范圍:

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM