float double 的儲存方式

2021-07-10 16:57:24 字數 2762 閱讀 5336

float 和 double 的表示法:

都是二進位制的科學表示法:

± mantissa × 2 exponent

(mantissa:尾數,

exponent:指數,均使用二進位制表示)

float(浮點型)在記憶體中佔4個位元組(byte),即32位(bit)

儲存方式如下:

1 bit(符號位)

8 bit(指數字)

23 bit(尾數字)

符號位:1   bit,0表正,1表負

指數為:8   bit,推算的8個bit能表示的範圍為0 - 2的8次方減1,即0 - 255,但是這裡的值都是加了127的,所以實際能表示的範圍為:-127 - 128

尾數字:23 bit,推算得23個bit能表示的範圍為0 - 2的23次方減1,即0 - 8388607,最大值為7位數,但是不能表示所有的7位數,不過所有的6位數是可以包含的,所以精度為6個有效數字(注:這也就是為什麼說float的精度為6-7位,但實際能確定的只有6位)

所以我們比較兩個float是否相等時,常常這樣寫:

const float epsilon = 0.000001;

float f1 = 123.234567;

float f2 = 123.234568;

if (fabs(f1-f2) <= epsilon)

{ cout<

最大值:由上面得指數最大為128,即此時最大值為2的128次方,為 3.402823466e+38

最小值:符號位為1時,表負,所以最小值即最大值取負的即可,為 -3.402823466e+38

當指數為-127時,決定了浮點數所能表達的絕對值最小的非零數,為1.175494351e-38

double(雙精度浮點型)在記憶體中佔8個位元組(byte),即64位(bit)

儲存方式如下:

1 bit(符號位)

11 bit(指數字)

52 bit(尾數字)

符號位:1   bit,0表正,1表負

指數為:11 bit,推算的11個bit能表示的範圍為0 - 2的11次方減1,即0 - 2047,但是這裡的值都是加了1023的,所以實際能表示的範圍為:-1023 - 1024

尾數字:52 bit,推算得52個bit能表示的範圍為0 - 2的52次方減1,即0 - 4503599627370495,最大值為16位數,但是不能表示所有的16位以內的數,但是所有的15位數是可以包含的,所有精度為15個有效數字

最大值:由上面得指數最大為1024,即此時最大值為2的1024次方,為 1.7976931348623158e+308

最小值:符號位為1時,表負,所以最小值即最大值取負的即可,為 - 1.7976931348623158e+308

當指數為-1023時,決定了浮點數所能表達的絕對值最小的非零數,為2.2250738585072014e-308

舉個例子:

1.得到float型別的 -10.5 的記憶體表示

首先得到-10.5的二進位制表示法,- 1010.1,二進位制的科學表示法為:- 1.0101 * 2的3次方

這樣可以得到

符號位:因為是負的,所以為1

指數字:上面得到指數為3,加上127得到130,二進位制表示為10000010

尾數字:只表示小數點後面的即可,即0101,後面補0即可,一共23位,需補19個0,最終二進位制表示為:0101 0000 0000 0000 0000 000

最後把上面的符號位,指數字,尾數字加起來就得到了二進位制表示:(紅色表符號位,綠色表指數為,藍色表尾數字) 1

10000010

01010000000000000000000

按照8個bit乙個byte,區分開來得到 1

100 0001 0

010 1000 0000 0000 0000 0000

十六進製制表示即為:0x c1 28 00 00

由於機器為小端,低位先存,高位後存,所以記憶體中實際儲存為:

0000 0000 0000 0000

0010 1000

1100 0001

十六進製制表示即為:0x 00 00 28 c1

可以寫個程式測試下,你會發現-10.5的記憶體表示確實是0x 00 00 28 c1

2.乙個小端機器中,float的記憶體資料為 0x 00 00 85 41,求這個float數

首先,由於是小端,得到原本的十六進製制:0x 41 85 00 00 

得到二進位制資料:0100 0001 1000 0101 0000 0000 0000 0000

再以顏色區分(紅色表符號位,綠色表指數為,藍色表尾數字)

得到資料:

0100 0001 1

000 0101 0000 0000 0000 0000

然後提取得到:

符號位:0,表正數

指數字:10000011,即十進位制數131,減去127後得到4

尾數字:000 0101 0000 0000 0000 0000  捨去後面多餘的0,即0000101

由上面公式得到,該float資料為 1.0000101 * 2的4次方,小數點右移4位,即10000.101

小數點左邊資料,10000即16

小數點右邊資料,0.101即1*2^-1 +0 * 2^-2 +1* 2^-3  = 0.5 + 0 + 0.125 = 0.625

最後左右加後邊,即16+0.625 = 16.625

可以寫個程式測試下,你會發現16.625的記憶體表示確實是0x 00 00 85 41

float,double在記憶體中的儲存方式

將17.625換算成 float型。首先,將17.625換算成二進位制位 10001.101 0.625 0.5 0.125,0.5即 1 2,0.125即 1 8 如果不會將小數部分轉換成二進位制,請參考其他書籍。再將 10001.101 向右移,直到小數點前只剩一位 成了 1.0001101 x...

C語言float double的記憶體表示

在記憶體中,小數是以指數形式存在的。float double 在記憶體中的形式如下所示 小數在被儲存到記憶體前,首先轉換為下面的形式 a 2 n 其中 a 為尾數,是二進位制形式,且 1 a 2 n 為指數,是十進位制形式。例如對於 19.625,整數部分的二進位制形式為 19 1 24 0 23 ...

用float double作為中轉型別的「雷區」

n由於lua用double作為number型別的底層資料中轉型別。而實際應用中多以int型別作為函式呼叫的引數 特別是c實現的api 因而,double int unsigend int之間的數值轉換在接入lua的專案中應用十分廣泛。實際專案發現,double int unsigend int之間的...