《編碼》之定點數與浮點數

    《編碼》真是一本不錯的書,從燈泡通信、繼電器、二進制層層深入,再到加法器、彙編、處理器。全部連了起來,精妙啊,可惜現在纔看到這本書,不過也爲時不玩。

     23章中講到了定點數與浮點數,所以這裏做下記錄吧。

1.定點數

     所謂的定點數,就是隻小數點的位置總是在數的某個特定的位置,也就是有效位數是固定的。像書中所舉的用壓縮BCD(用四個位來表示0~9)保存數值就是隻留兩位小數,另外還有1位是符號位,用來標識數的正負。例如:

00010100 00110010 01010001 00100000 00100101 00000001 00010001
-   4    3   2    5   1    2   0.    2   5 +   1.    1   1

     上面兩個二進制就分別表示-4325120.25和1.11。

2. 浮點數

     計算機中的浮點格式是藉助二進制數實現的科學計數法形式。

2.1 科學計數法

     科學計數法將每個數表示成有效位與10的冪的乘積形式,這樣子就可以避免寫一長串的0,採用科學計數法,數490,000,000,000可以記爲:4.9*10^{11},而數0.00000000026可以記爲:2.6*10^{-10}。其中4.9和2.6被稱作小數部分或者首數,而在計算機術語中這一部分被稱爲有效數(significand),11和-10則是指數(exponent)部分。

     爲了便於操作,一般規定有效數的取值範圍是大於或等於1且小於10。這種寫法有時被稱爲科學計數法的規範化式(normalized)

2.2 浮點格式(floating-point notation)

    浮點格式是對小數存儲除了定點格式外的另一種格式,它是基於科學計數法的。在十進制數中,小數點右邊的數字與10的負整數次冪相關聯,而在二進制數中,二進制小數點右邊的數字則和2的負整數次冪相關,例如101.1101就可以表示爲:

                                     1*2^{2}+0*2^{1}+1*2^{0}+1*2^{-1}+1*2^{-2}+0*2^{-3}+1*2^{-4}

     在二進制的科學技術法中,規範化式的有效數應該大於或等於1且小於10(二進制中的2),因此101.1101的規範化式爲:

                                                                                 1.011101_{2}*2^{2}

     這個規則暗示了這樣子一個現象:在規範化式二進制浮點數中,小數點的左邊通常只有一個1,除此之外沒有其他數字

2.3 IEEE浮點數標準

     當代大部分計算機和計算機程序在處理浮點數時所遵循的標準都是由IEEE與1985年制定的,ANSI/IEEE std 754-1985稱作IEEE二進制浮點數算術預算標準。該標準定義了兩種基本格式:以4個字節表示的單精度格式和以8個字節表示的雙精度格式,即我們常見的float的double。

     單精度格式的4個字節可以分爲三個部分:1位的符號位(0代表正數,1代表負數),8位用作指數,最後的23位用作有效數字,如下所示:

s = 1 位符號 e = 8 位指數 f = 23 位有效數

    這裏23位有效數實際上指的是23位小數部分,因爲規範化式二進制小數點左邊固定只有一位1,所以雖然存儲的只有23位,但仍然稱其精度爲24位。

    8位指數部分的取值範圍是0~255,稱爲偏移(bias)指數,意思是對有符號指數,爲了確定其實際所代表的值必須從指數中減去一個值——稱作偏移量(bias),對於單精度浮點數,其偏移量爲127,指數範圍爲1~254,而0和255用於特殊的目的。

     對於一個特定的數,可以用s、e以及f來描述:

                                                                           (-1)^{s}*1.f*2^{e-127}

    對於浮點數的e和f,有四種特殊情況

  1. 如果e=0且f=0,則該數爲0,。在這種情況下,通常把32位都設置爲0以表示該數爲0.但是符號位可以設置爲1,這種數可以解釋爲負0。負0可以用來表示非常小的數,這些數極小以至於不能在單精度格式下用數字和指數來表示,但它們仍然小於0。
  2. 如果e=0且f != 0,則該數是合法的,但不是規範化的,這類數可以表示爲:(-1)^{s}*0.f*2^{-127}
  3. 如果e=255且f=0,則該數被解釋爲無窮大或者無窮小,這取決於符號位s的值。
  4. 如果e255且f != 0,則該值被解釋爲“不是一個數”,通常被縮寫爲NaN(not a number)。NaN用來表示未知的數或非法操作的結果。

     單精度浮點格式下,可以表示的規格化的最小正、正負二進制數分別是:

                                                             1.00000000000000000000000_{2}*2^{-126}

                                                             1.11111111111111111111111_{2}*2^{127}

      分別對應e=1和e=254的情況,在十進制下,兩個數近似等於:

                                                                       1.175494351*10^{-38}

                                                                       3.402823466*10^{38}

      這兩個數就是單精度浮點數的有效表示範圍了。

      對雙精度浮點數(double-precision floating-point format),其結構如下所示:

s = 1位符號位 e = 11 位指數位 f = 52 位有效數

       雙精度浮點數的指數偏移量是1024(2^{e-1}-1 = 2^{10} - 1)所以該格式存儲的數可以表示爲:

                                                                    (-1)^{s}*1.f*2^{e-1023}

       表示範圍爲:

                                              2.2250738585072014*10^{-308} ~ 1.7976931348623158*10^{308}

3. 定點數 VS 浮點數

       由於定點數用4個位表示一個十進制的數,所以對於23000000000000這種後面帶很多0的數,它將會用很多的位去保存,而浮點數則不需要。對於定點數,還需要預先知道小數點的位置是在哪裏(即保留多少位有效數字)。

      而對於浮點數,最大的問題就是精度的問題,因爲有效數的原因,單精度浮點數的精度爲1/2^{24}或1/16777216,所以在單精度浮點格式下16,777,216和16,777,217將會被表示成同一個數,也就是:

                                                                   1.00000000000000000000000_{2}*2^{24}

       而下一個二進制浮點數可能表示的最大有效數是16,777,218,即爲:

                                                                    1.00000000000000000000001_{2}*2^{24}

       例如,我們無法用浮點數的格式表示出0.1和0.9,而只能無限接近。

       所以當我們對數據的精度要求很高不能用近似比如銀行中的錢款數目,用定點數就會好一些。

       並且上面講到的負0的情況,也會導致我們對浮點數是否爲0的判斷不能像整數那樣子,而需要用這種方式:-0.00001 < a && a < 0.00001來判斷。

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