溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

浮點(diǎn)數(shù)如何在內(nèi)存中存儲

發(fā)布時間:2020-06-29 21:06:58 來源:網(wǎng)絡(luò) 閱讀:3428 作者:jetyi 欄目:編程語言

首先,將10進(jìn)制的小數(shù)0.1轉(zhuǎn)換為二進(jìn)制,方法如下:

0.1*2==0.2  取0.2的整數(shù)部分, 結(jié)果為0.0

0.2*2==0.4  取0.4的整數(shù)部分, 結(jié)果為0.00

0.4*2==0.8  取0.8的整數(shù)部分, 結(jié)果為0.000

0.8*2==1.6  取1.6的整數(shù)部分, 結(jié)果為0.0001

0.6*2==1.2  取1.6的整數(shù)部分, 結(jié)果為0.00011

0.2*2==0.4  取0.4的整數(shù)部分, 結(jié)果為0.000110

最后這一步開始循環(huán),因此0.1的二進(jìn)制為數(shù)為: 0.0001100110011...是一個無限循環(huán)小數(shù),二進(jìn)制數(shù)據(jù)無法精確表示.


當(dāng)然,有些小數(shù)是不循環(huán)的,可以用二進(jìn)制數(shù)據(jù)精確表示,如10進(jìn)制的0.5轉(zhuǎn)換為轉(zhuǎn)換為二進(jìn)制:

0.5*2=1.0 取1.0的整數(shù)部分, 結(jié)果為0.1

0.0*2=0.0 取0.0的整數(shù)部分, 結(jié)果為0.10

再進(jìn)行運(yùn)算下去,可以認(rèn)為0.5的二進(jìn)制數(shù)據(jù)為0.10000...,也就是1.0,不是循環(huán)小數(shù).


可見,按照上面的運(yùn)算方法,運(yùn)算結(jié)果不為0且循環(huán)的時候則是無限循環(huán)小數(shù),運(yùn)算結(jié)果為0,則不是循序小數(shù).


下面是幾個二進(jìn)制小數(shù)和10進(jìn)制小數(shù)對應(yīng)關(guān)系:

0.1 == 0*2^1 + 1*2^-1 == 1/2 == 0.5 == 0*10^1 + 5*10^-1

0.01 == 0*2^1 + 0*2^-1 + 1*2^-2 == 0.25 == 0*10^1 + 2*10^-1 + 5*10^-2

0.001 == 0*2^1 + 0*2^-1 + 0*2^-2 + 1*2^-3 == 1/8 == 0.125 == 0*10^1 + 1*10^-1 + 2*10^-2 + 5*10^-3

0.0001 ==  0*2^1 + 0*2^-1 + 0*2^-2 + 0*2^-3 + 1*10^-4 == 1*2^-4 == 1/16 == 0.0625 ==  0*10^1 + 0*10^-1 + 6*10^-2 + 2*10^-3 + 5*10^-4

... ...

從這幾個對應(yīng)關(guān)系可以看出二進(jìn)制和十進(jìn)制本質(zhì)是一樣的,用科學(xué)計數(shù)法來表示: 1*2^-m+...1*2^-n


那么,小數(shù)如何在內(nèi)存中存儲呢? 以float fpi=0.1415926為例說明

第一步: 將十進(jìn)制的0.141593轉(zhuǎn)換為二進(jìn)制數(shù)為: 0.001000011111101101001101000100...已經(jīng)舍去了一部分

第二步: 將第一步的二進(jìn)制小數(shù)點(diǎn)向右移動3位: 1.000011111101101001101000100 * 2^-3

第三步: 計算階碼,提取第二步中的指數(shù)-3,然后計算階碼: -3 + 127 == 124,124(小于127,說明是一個負(fù)數(shù))的二進(jìn)制數(shù)為: 1111 100,用8位表示就是0 1111 100

第四步: 獲取尾數(shù),將第二步中的1.000011111101101001101000100-1=000011111101101001101000100

第五步: 將第四步的獲取的結(jié)果舍掉多余的部分,僅保留高23位: 0000111111011010011010

第六步: 將第3,5步的結(jié)果拼接到一塊,并加上符號位(正號0): (符號)0 (階碼)01111100 (尾數(shù))0000111111011010011010

浮點(diǎn)數(shù)0.1415926在內(nèi)存中存儲的二進(jìn)制數(shù)為: 0 01111100 0000111111011010011010


如果小數(shù)帶整數(shù)部分,如3.1415926,轉(zhuǎn)換過程差不過:

1.分別將整數(shù)和小數(shù)轉(zhuǎn)換為二進(jìn)制數(shù): 011.001000011111101101001101000100

2.將第1步中的二進(jìn)制數(shù)小數(shù)點(diǎn)向左移動1位: 1.1001000011111101101001101000100

3.計算階碼,提取第2步中的指數(shù)+2,然后計算階碼: +2 + 127 == 128,128(大于127,說明是一個正數(shù))的二進(jìn)制數(shù)為: 10000000,共8位(階碼是一個正數(shù),可省略符號位)

4.獲取尾數(shù),將第2步中的1.1001000011111101101001101000100-1=1001000011111101101001101000100

5.將第4步的獲取的結(jié)果舍掉多余的部分,僅保留高23位: 10010010000111111011010

6.將第3,5步的結(jié)果拼接到一塊,并加上符號位(正號0): (符號)0 (階碼)10000001 (尾數(shù))10010010000111111011010

浮點(diǎn)數(shù)3.1415926在內(nèi)存中存儲的二進(jìn)制數(shù)為: 0 10000000 10010010000111111011010


通過上面的例子,說明一下浮點(diǎn)數(shù)如何在內(nèi)存中存儲

C/C++編譯器標(biāo)準(zhǔn)都遵照IEEE制定的浮點(diǎn)數(shù)表示法來進(jìn)行float/double運(yùn)算,將浮點(diǎn)數(shù)轉(zhuǎn)換為二進(jìn)制的科學(xué)計數(shù)法: V = (-1)s * M * 2^E

(-1)s 表示符號位,當(dāng)s=0,V為正數(shù);當(dāng)s=1,V為負(fù)數(shù).

M表示有效數(shù)字,1<=M<2.

E表示指數(shù)位


float和double類型,s,M,E的位數(shù)為:

符號位s 階碼M   尾數(shù)M   長度  

float(32bits)      1        8     23

double(64bits)     1       11     52


尾數(shù)M的的規(guī)則

1.必須保證1≤M<2,也就是說,M可以寫成1.xxxxxx的形式,其中xxxxxx表示小數(shù)部分.在計算機(jī)內(nèi)部保存M時,默認(rèn)這個數(shù)的第一位總是1,因此可以被舍去,只保存后面的xxxxxx部分

等到讀取的時候,再把第一位的1加上去.這樣做的好處是節(jié)省1位有效數(shù)字.以32位浮點(diǎn)數(shù)為例,留給 M只有23位,將第一位的1舍去以后,等于可以保存24位有效數(shù)字.

2.尾數(shù)必須用原碼表示,無論浮點(diǎn)數(shù)是正數(shù)還是負(fù)數(shù).


注:

1985年IEEE(Institute of Electrical and Electronics Engineers)提出了IEEE754標(biāo)準(zhǔn).該標(biāo)準(zhǔn)規(guī)定基數(shù)為2,階碼E用移碼表示,尾數(shù)M用原碼表示,根據(jù)二進(jìn)制的規(guī)格化方法,最高數(shù)字位總是1,該標(biāo)準(zhǔn)將這個1缺省存儲,使得尾數(shù)表示范圍比實際存儲的多一位.


階碼的規(guī)則

階碼的本質(zhì)上是無符號整數(shù)(float 8位;double 11位),但它仍然可以表示負(fù)數(shù),其規(guī)則為:

對于float來說,階碼=E-127.

對于double來說,階碼=E-1023.

這樣,如果E為正數(shù),則階碼>127; 如果E為負(fù)數(shù),則階碼<127. 然后,指數(shù)E還可以再分成三種情況:

(1)E不全為0或不全為1.這時,浮點(diǎn)數(shù)就采用上面的規(guī)則表示,即指數(shù)E的計算值減去127(或1023),得到真實 值,再將有效數(shù)字M前加上第一位的1. 

(2)E全為0.這時,浮點(diǎn)數(shù)的指數(shù)E等于1-127(或者1-1023),有效數(shù)字M不再加上第一位的1,而是還原為 0.xxxxxx的小數(shù).這樣做是為了表示±0,以及接近于0的很小的數(shù)字.

(3)E全為1.這時,如果有效數(shù)字M全為0,表示±無窮大(正負(fù)取決于符號位s);如果有效數(shù)字M不全為0,表示 這個數(shù)不是一個數(shù)(NaN).


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI