Assembly 浮點表示法

2018-11-01 09:55 更新

非整形的二進制數(shù)

在第一章討論數(shù)制的時候,我們只討論了整形。顯然,和十進制一樣,其它進制必須也能表示非整形數(shù)。在十進制中,在小數(shù)點右邊的數(shù)字關聯(lián)了10的負乘方值:

10的負乘方值

不必驚訝,二進制也是以同樣的方法表示:

二進制表示

這個辦法與第一章中的整形辦法相結合就可以用來轉換一個一般數(shù)值:

一般數(shù)值

將十進制轉換成二進制也不是很難。一般來說,需將十進制數(shù)分成兩塊:整數(shù)部分和分數(shù)部分。使用第一章中的方法來將整數(shù)部分轉換成二進制。分數(shù)部分的轉換可以使用下面描述的方法。

考慮一個用a、b、c···標記比特位的二進制分數(shù)。這個數(shù)用二進制表示為:

0.abcdef...

將此數(shù)乘2.新得到的數(shù)的二進制表示將是:

a.bcdef...

注意,第一個比特位現(xiàn)在在權值為1的位置。用0替換a得到:

0.bcdef...

再乘以2得到:

b.cdef...

現(xiàn)在第二個比特位(b)在權值為1的位置。重復這個過程,直到得到了需要的盡可能多的比特位。圖6.1展示了一個實例:將0.5625轉換成二進制。這種方法當分數(shù)部分為0了才停止。

將0.5625轉換成二進制

另一個例子,將23.85轉換成二進制。將整數(shù)部分轉換成二進制是容易的,但是分數(shù)部分呢?圖6.2展示了這個計算的開始部分。如果你仔細看了這個數(shù)值,就會發(fā)現(xiàn)一個無限循環(huán)。這就意味著0.85是一個無限循環(huán)的二進制數(shù)(與基數(shù)為10的無限循環(huán)十進制數(shù)相對應)。這里顯示了這個數(shù)的計算模式。在這個模式中,你可以看到。因此,。

將0.85轉換成二進制
上面計算的一個重要結論是23.85不可以用有限的比特位來精確表示成二進制數(shù)。(就像不能表示成有限的十進制數(shù)。)正如這一章展示的,C語言中的float和double變量是以二進制儲存的。因此,類似23.85的數(shù)值不能精確地儲存到這些變量中。只能儲存23.85的近似值。

為了簡化硬件,采用固定的格式來儲存浮點數(shù)。這種格式采用科學計數(shù)法(但是是在二進制中,是2的乘方,不是10)。例如,23.85或10111.11011001100110...?將儲存為:



(其中指數(shù)(100)是二進制形式)。規(guī)范的浮點數(shù)有下面的形式:



其中1:sssssssssssss是有效數(shù)而eeeeeeee是指數(shù)。

IEEE浮點表示法

IEEE(Institute of Electrical and Electronic Engineers,電氣與電子工程師學會)是一個國際組織,它已經設計了存儲浮點數(shù)的特殊的二進制格式。這種格式應用在大多數(shù)(但不是全部)現(xiàn)在的電腦上。通常電腦本身的硬件就支持它。例如,Intel的數(shù)學協(xié)處理器(從Pentium開始,就嵌入到所有它的CPU中了)就使用它。IEEE為不同的精度定義了不同的格式:單或雙精度。在C語言中,float變量使用單精度,而double變量使用雙精度。

Intel數(shù)學協(xié)處理器使用第三種,更高的精度,稱為擴展精度。事實上,在數(shù)學協(xié)處理器自身里的所有數(shù)據(jù)都是這種格式。當數(shù)據(jù)從協(xié)處理器儲存到內存中時,將自動轉換成單或雙精度。跟IEEE的浮點雙精度格式相比,擴展精度使用了一種有細微差別的格式,所以將不在這討論。

IEEE單精度

IEEE單精度

單精度浮點使用32個比特位來編碼數(shù)字。通常它精確到小數(shù)點后七位。相比于整數(shù),浮點數(shù)的儲存格式更復雜。圖6.3展示了IEEE單精度數(shù)的基本格式。這種格式有幾個古怪的地方。負的浮點數(shù)并不使用補碼表示法。它們使用符號量值表示法。如圖顯示,第31位決定數(shù)的符號。二進制的指數(shù)并不會直接儲存。取而代之的是將指數(shù)和7F的和儲存到位23 30中。這個偏置指數(shù)總是非負的。

分數(shù)部分假定是一個規(guī)范的有效數(shù)(格式為1:sssssssss)。因為第一個比特位總是1,所以領頭的1是不儲存的!這就允許在后面儲存一額外的比特位,稍微地擴展了精度。這個想法稱為隱藏一的表示法。

怎樣儲存23.85呢? 首你必須永遠記?。哼@些字 先,它是個正數(shù),所以符號位為0。其次,真實的指數(shù)為4,所以偏置指數(shù)為。最后,分數(shù)部分應表示為01111101100110011001100 (記住領頭的1是隱藏的)。把這些放到一起得到(為了幫助澄清浮點格式的不同部分,符號位和分數(shù)部分都加了下劃線,而且所有的比特位都分成了四個比特位一組。):



這不是準確的23.85(因為它是一個無限循環(huán)的二進制數(shù))。如果你將上面的數(shù)值轉換回十進制形式,你會發(fā)現(xiàn)它大約等于23.849998474。這個數(shù)與23.85非常接近,但是它并不準確。實際上,在C語言中,23.85的描述和上面的是一樣的。因為該數(shù)的精確描述被截去后的最左邊的位為1,所以最后一個比特位經四舍五入后為1。因此單精度數(shù)23.85將表示成十六進制41 BE CC CD。將這個轉換成十進制得23.850000381,這個數(shù)就更接近23.85。怎么描述-23.85呢?只需要改變符號位得:C1 BE CC CD。不要使用補碼!

IEEE浮點格式中,e和f 的某些組合有特殊的含義。表6.1描述了這些特殊的值。溢出或除以0將產生一個無窮數(shù)。一個無效的操作將產生一個不確定的結果,例如:試圖求一個負數(shù)的平方根,將兩個無窮數(shù)相加,等等。規(guī)范的單精度數(shù)的數(shù)量級范圍為從

f和e的特殊值

非規(guī)范化數(shù)

非規(guī)范化數(shù)可以用來表示那些值太小了以致于不能以規(guī)范格式描述的數(shù)(也就是小于)。例如:考慮下數(shù)。在約定的規(guī)范格式中,這個指數(shù)太小了。但是,它可以用非規(guī)范的格式來描述:。為了儲存這個數(shù),偏置指數(shù)被置為0(看表6.1),而且分數(shù)部分是以方式書寫得到的所有有效數(shù)(也就是說儲存了所有的比特位,包括小數(shù)點左邊的1).將表示成:



IEEE雙精度

IEEE雙精度使用64位來表示數(shù)字,而且通常精確到小數(shù)點后15位。如圖6.4所示,基本的結構和單精度是非常相似的。只是相比于單精度,它使用了更多的位來描述偏置指數(shù)(11)和分數(shù)(52)。

IEEE雙精度

更大范圍的偏置指數(shù)會導致兩個后果。一是計算的將是真實指數(shù)和3FF(1023)的和(而不是單精度中的7F)。二是,允許描述更大范圍的真實的指數(shù)(因此也可以描述更大范圍的數(shù)量級)。雙精度的數(shù)量級范圍大約為。

雙精度值中增加的有效位是增大分數(shù)字段的原因。

作為一個例子,再次考慮下。偏置指令用十六進制表示為4 + 3FF =403。因此,該數(shù)用雙精度表示為:


或在十六進制中為40 37 D9 99 99 99 99 9A。如果你將它轉換回十進制,你將得到23.8500000000000014 (這有12個0!),這個數(shù)就更接近23.85。

雙精度和單精度一樣有一些特殊的值3。非規(guī)范化數(shù)同樣也是一樣的。
最主要的區(qū)別是雙精度的非規(guī)范數(shù)使用。
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號