1. 程式人生 > >計算機中浮點數的儲存方式

計算機中浮點數的儲存方式

參考網址:http://blog.chinaunix.net/uid-28458801-id-3507427.html

根據國際標準IEEE 754,任意一個二進位制浮點數V可以表示成下面的形式:
  V = (-1)^s×M×2^E
  (1)(-1)^s表示符號位,當s=0,V為正數;當s=1,V為負數。
  (2)M表示有效數字,大於等於1,小於2。

  (3)2^E表示指數位。

IEEE關於浮點數的定義標準了,0.0f是一個特殊的數,階碼和尾數全為0來表示浮點的0,這是規定.

  舉例來說,

        十進位制的5.0,寫成二進位制是101.0,相當於1.01×2^2。那麼,按照上面V的格式,可以得出s=0,M=1.01,E=2。

        十進位制的-5.0,寫成二進位制是-101.0,相當於-1.01×2^2。那麼,s=1,M=1.01,E=2。

IEEE 754規定,對於32位(如 float)的浮點數,最高的1位是符號位s,接著的8位是指數E,剩下的23位為有效數字M。

儲存的結構:1位符號+8位介碼+23位有效數字M

 

        對於64位(如 double)的浮點數,最高的1位是符號位S,接著的11位是指數E,剩下的52位為有效數字M。

儲存的結構:1位符號+11位介碼+52位有效數字M

 

IEEE 754對有效數字M和指數E,還有一些特別規定。
  前面說過,1≤M<2,也就是說,M可以寫成1.xxxxxx的形式, 其中xxxxxx表示小數部分。IEEE 754規定,在計算機內部儲存M時,預設這個數的第一位總是1,因此可以被捨去,只儲存後面的xxxxxx部分。比如儲存1.01的時候,只儲存01

,等 到讀取的時候,再把第一位的1加上去。這樣做的目的,是節省1位有效數字。以32位浮點數為例,留給M只有23位,將第一位的1捨去以後,等於可以儲存 24位有效數字。
  至於指數E,情況就比較複雜
  首先,E為一個無符號整數(unsigned int)。這意味著,如果E為8位,它的取值範圍為0~255;如果E為11位,它的取值範圍為0~2047。但是,我們知道,科學計數法中的E是可以出 現負數的,所以IEEE 754規定,E的真實值必須再減去一箇中間數,對於8位的E,這個中間數是127;對於11位的E,這個中間數是1023。

  比如,2^10的E是10,所以儲存成32位浮點數時,必須儲存成10+127=137,即10001001。


  然後,指數E還可以再分成三種情況:
  (1)E不全為0或不全為1。這時,浮點數就採用上面的規則表示,即指數E的計算值減去127(或1023),得到真實值,再將有效數字M前加上第一位的1
  (2)E全為0。這時,浮點數的指數E等於1-127(或者1-1023),有效數字M不再加上第一位的1,而是還原為0.xxxxxx的小數。這樣做是為了表示±0,以及接近於0的很小的數字。
  (3)E全為1。這時,如果有效數字M全為0,表示±無窮大(正負取決於符號位s);如果有效數字M不全為0,表示這個數不是一個數(NaN)

為什麼0x00000009還原成浮點數,就成了0.000000?
  首先,將0x00000009拆分,得到第一位符號位s=0,後面8位的指數E=00000000,最後23位的有效數字M=000 0000 0000 0000 0000 1001。
  由於指數E全為0,所以符合上一節的第二種情況。因此,浮點數V就寫成:
  V=(-1)^0×0.00000000000000000001001×2^(-126)=1.001×2^(-146)
  顯然,V是一個很小的接近於0的正數,所以用十進位制小數表示就是0.000000。

請問浮點數9.0,如何用二進位制表示?還原成十進位制又是多少?
  首先,浮點數9.0等於二進位制的1001.0,即1.001×2^3。
  那麼,第一位的符號位s=0,有效數字M等於001後面再加20個0,湊滿23位,指數E等於3+127=130,即10000010。
  所以,寫成二進位制形式,應該是s+E+M,即010000010 001 0000 0000 0000 0000 0000。這個32位的二進位制數,還原成十進位制,正是1091567616。

十進位制的0.5,寫成二進位制是0.1,相當於1.0* 2^(-1)。那麼,s=0,M=1.0,E=-1。

    則:1≤M<2,只需儲存M中小數點後的數值,此時為 0,則 第22位為0,填充第0~21位為0;

           E = -1;儲存時為 127+(-1)=126(十進位制)=111 1110(二進位制)

    二進位制結果為: 符號     階碼       有效數值

                            0 01111110  00000000000000000000000

請問浮點數1.0,如何用二進位制表示?還原成十進位制又是多少?
    首先,浮點數1.0等於二進位制的1.0,即1.0×2^0。
  那麼,第一位的符號位s=0,有效數字M等於0, 23個0,,指數E等於0+127=127,即01111111。
  所以,寫成二進位制形式,應該是s+E+M,即0 011 11111 000 0000 0000 0000 0000 0000這個32位的二進位制數。也就是03f800000,還原成十進位制,正是1065353216。

測試程式碼:

int main()

{

       float a =1.0f;

       cout <<(int)a<< endl;

       cout <<&a << endl;

       cout <<(int&)a<< endl;

       return 0;

}

執行結果:

1

0077F79C

1065353216

請按任意鍵繼續. . .