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之間的...