中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

浮點數如何在內存中存儲

發布時間:2020-06-29 21:06:58 來源:網絡 閱讀:3428 作者:jetyi 欄目:編程語言

首先,將10進制的小數0.1轉換為二進制,方法如下:

0.1*2==0.2  取0.2的整數部分, 結果為0.0

0.2*2==0.4  取0.4的整數部分, 結果為0.00

0.4*2==0.8  取0.8的整數部分, 結果為0.000

0.8*2==1.6  取1.6的整數部分, 結果為0.0001

0.6*2==1.2  取1.6的整數部分, 結果為0.00011

0.2*2==0.4  取0.4的整數部分, 結果為0.000110

最后這一步開始循環,因此0.1的二進制為數為: 0.0001100110011...是一個無限循環小數,二進制數據無法精確表示.


當然,有些小數是不循環的,可以用二進制數據精確表示,如10進制的0.5轉換為轉換為二進制:

0.5*2=1.0 取1.0的整數部分, 結果為0.1

0.0*2=0.0 取0.0的整數部分, 結果為0.10

再進行運算下去,可以認為0.5的二進制數據為0.10000...,也就是1.0,不是循環小數.


可見,按照上面的運算方法,運算結果不為0且循環的時候則是無限循環小數,運算結果為0,則不是循序小數.


下面是幾個二進制小數和10進制小數對應關系:

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

... ...

從這幾個對應關系可以看出二進制和十進制本質是一樣的,用科學計數法來表示: 1*2^-m+...1*2^-n


那么,小數如何在內存中存儲呢? 以float fpi=0.1415926為例說明

第一步: 將十進制的0.141593轉換為二進制數為: 0.001000011111101101001101000100...已經舍去了一部分

第二步: 將第一步的二進制小數點向右移動3位: 1.000011111101101001101000100 * 2^-3

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

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

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

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

浮點數0.1415926在內存中存儲的二進制數為: 0 01111100 0000111111011010011010


如果小數帶整數部分,如3.1415926,轉換過程差不過:

1.分別將整數和小數轉換為二進制數: 011.001000011111101101001101000100

2.將第1步中的二進制數小數點向左移動1位: 1.1001000011111101101001101000100

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

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

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

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

浮點數3.1415926在內存中存儲的二進制數為: 0 10000000 10010010000111111011010


通過上面的例子,說明一下浮點數如何在內存中存儲

C/C++編譯器標準都遵照IEEE制定的浮點數表示法來進行float/double運算,將浮點數轉換為二進制的科學計數法: V = (-1)s * M * 2^E

(-1)s 表示符號位,當s=0,V為正數;當s=1,V為負數.

M表示有效數字,1<=M<2.

E表示指數位


float和double類型,s,M,E的位數為:

符號位s 階碼M   尾數M   長度  

float(32bits)      1        8     23

double(64bits)     1       11     52


尾數M的的規則

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

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

2.尾數必須用原碼表示,無論浮點數是正數還是負數.


注:

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


階碼的規則

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

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

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

這樣,如果E為正數,則階碼>127; 如果E為負數,則階碼<127. 然后,指數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).


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

思南县| 阳城县| 南开区| 潜江市| 宜兴市| 贵阳市| 河源市| 临夏县| 砚山县| 汶上县| 阜平县| 铁岭市| 从江县| 延寿县| 广元市| 宁海县| 聂荣县| 手游| 杭州市| 普宁市| 安平县| 马鞍山市| 隆安县| 峡江县| 随州市| 洪雅县| 四会市| 韶关市| 泰安市| 大田县| 江源县| 台湾省| 亚东县| 威海市| 永年县| 仁怀市| 宝清县| 夹江县| 濉溪县| 攀枝花市| 普兰店市|