理解浮點數的二進位制表示

2021-10-06 15:42:14 字數 2131 閱讀 6242

目錄

二進位制的科學計數法

浮點數的二進位制表示

符號位、尾數和指數(以64位浮點數為例)

0、規約數和非規約數

無窮大和空值nan

浮點數在電腦中用二進位制儲存,約定以二進位制的科學計數法來進行表示乙個浮點數,模擬十進位制的科學計數法,很容易知道,二進位制的科學計數法的首位數字一定為1,然後通過乘以相應的底數為2的指數來得到二進位制數,如下所示。

下面等號左邊是原二進位制數,右邊就是其二進位制的科學計數表示。和十進位制一樣,二進位制的科學計數表示之後,也具有有效數字(尾數)、底數和指數,只是二進位制的有效數字由0和1組成,底數為2。

所以,浮點數的二進位制表示包括符號、尾數和指數。比如對於32位浮點數來說,1位符號位、23為尾數字和8位指數字;對於64位浮點數來說,1位符號位、52位尾數字和11位指數字。尾數以二進位制的科學計數法約定表示,因為對於所有約定的規約數來說,首位都是1,所以首位的1會被預設省去,所以對於64位浮點數,其有效精度可以達到二進位制的53位;指數的底數為2,由於為了表示小數,故指數也有正負,為了表示負數,所以指數通過移碼的方式進行轉化。

以64位浮點數為例,如下所示。從0-63共有64個bit,其中首位用來表示符號,0為正,1為負。接下來11位bit用來儲存指數,剩下的52位用來儲存尾數。

符號位很簡單,就是約定0表示正,1表示負。對於尾數,其有52位bit,但是根據二進位制的科學計數法,首位都為1,因此我們可以省略掉這個1,這樣子52位都可以用來儲存尾數的小數部分,因此實際上52位尾數小數的有效尾數有共有53位,只是首位的1被省略了。對於指數,有11bit,但是為了表示負數,採用二進位制指數值-偏移量的計算方式得到計算中的指數值;比如64位的指數偏移量約定為1023,11bit可以表示的值的範圍為0~2047的整數,但是這裡真正被用作指數計算的只有1~2046,0和2047這兩個數字被剔除,以用來表示特殊值,這個文章後面再說明;因此,1~2016減去偏移量1023後,真正的指數取值範圍為-1022~1023。所以64位浮點數的具體的二進位制表示方式如下。

so far so good! 問題來了,怎麼表示0?由於上述定義中,尾數始終是大於1的,所以無論如何也無法得到0,因此0這個需要特殊定義。根據上述的定義,即指數範圍在1~2046之間,有效數字首位為1的浮點數,叫做規約數(normal numbers)。同時還注意到,上述在講指數的時候,有兩個值是沒有用到的,即0和2047,對應著指數部分11個bit分別全部為0和全部為1的情形。所以為了表示0,約定當指數部分全部為0,且尾數小數部分也全為0的時候,表示0;要注意的是,雖然本文這裡說的是尾數的小數部分全為0,但是實際上這時,首位隱藏的1變成了0。

接下來的問題是,如果指數部分全為0,但是尾數的小數部分不全為0,這時該表示什麼?因為對於規約數的定義,我們研究指數部分的值在1~2046之間,而指數為0時,就超出了規約數定義的範圍了,因此,當指數為0,但是尾數小數部分不全為0時,我們定義這樣的數為非規約數(denormal numbers or subnormal numers)。要注意的是,非規約數的指數一定是為0的,但是這時偏移量變成了1022;即當指數為0時,那麼不僅尾數首位隱藏值從1變成0,而且約定偏移量這時為1022,即移碼後的指數依然保持-1022不變(注意不是-1023),以該移碼後的指數(即-1022)去計算非規約數的大小。

至此,我們還有乙個數沒有說明,那就是指數的2047,即指數全為1時的情形。我們約定,當指數全為1,且尾數小數部分全為0時,表示無窮大,然後根據符號的不同,有正無窮大和負無窮大。但是當指數全為1,但是尾數的小數部分不全為0時,表示什麼呢?這樣的數字實際上是未定義的,所以約定其為nan(not a number),所以可知,實際上nan的情形是很多的,在對nan進行比較時,系統約定其是不相等的,因為我們不能通過等號來判斷nan值,由於nan實際上也有有二進位制表示的,所以其不是乙個空物件,也不能用是否為空物件來判斷;這也是為什麼pandas中判斷乙個值是否為nan需要使用規定的函式,不能直接使用等號判斷和空物件判斷的原因,具體的pandas中的判斷方式可以看這篇文章。

浮點數的二進位制表示

前幾天,我在讀一本c語言教材,有一道例題 includevoid main void 執行結果如下 num的值為 9 pfloat的值為 0.000000 num的值為 1091567616 pfloat的值為 9.000000 我很驚訝,num和 pfloat在記憶體中明明是同乙個數,為什麼浮點數...

浮點數的二進位制表示

日期 2010年6月 6日 1.前幾天,我在讀一本c語言教材,有一道例題 includevoid main void 執行結果如下 num的值為 9 pfloat的值為 0.000000 num的值為 1091567616 pfloat的值為 9.000000 我很驚訝,num和 pfloat在記憶...

浮點數的二進位制表示

1.前幾天,我在讀一本c語言教材,有一道例題 includevoid main void 執行結果如下 num的值為 9 pfloat的值為 0.000000 num的值為 1091567616 pfloat的值為 9.000000 我很驚訝,num和 pfloat在記憶體中明明是同乙個數,為什麼浮...