linux C 中用float和double 表示浮點數,在32位電腦中 float 占4字節,double占8字節(可以使用printf(“%u %u \n”, (unsined int)sizeof(float), (unsined int)sizeof(double)); 語句來測試兩個數據類型占的內存空間大小)。那么具體float他能表示的數值取值范圍是多少呢?大家知道 int 整型在計算機中是以補碼的形式存儲,取值范圍是(-2147483648 ~ 2147483647),取值范圍和他在內存中的表示方式有直接的關系。
C語言中的浮點數遵循IEEE(美國電氣和電子工程師學會)二進制浮點數算術標準(IEEE754)是20世紀80年代以來最廣泛使用的浮點數運算標準。如果知道float 在內存是如何利用4個字節的內存空間的,那么就知道float他的取值范圍了。Float是有符號數,它在內存中是以符號位、指數位和尾數位三個部分的形式進行存儲的。其中最高位表示符號位占1bit表示正負,緊跟其后的8位表示指數部分以無符號形式存儲所以取值范圍是0-255,,剩余的23位表示尾數位 :
第31比特位:1bit(符號位S)
第30到23比特位 8bits(指數位P)
第22到0 比特位 23bits(尾數位M)
表示公式: v = ((-1)^S)*(2(P-126))*(0.M)
S是符號位,只有0和1,分別表示正負。
P是階碼,通常使用移碼表示(移碼和補碼只有符號位相反,其余都一樣。對于正數而言,原碼、反碼和補碼都一樣;對于負數而言,補碼就是其絕對值的原碼全部取反,然后加1)。階碼可以為正數,也可以為負數,為了處理負指數的情況,實際的指數值按要求需要加上一個偏差(Bias)值作為保存在指數域中的值,單精度數的偏差值為127,雙精度數的偏差值為1023。例如,單精度的實際指數值0在指數域中將保存為127,而保存在指數域中的64則表示實際的指數值-63,偏差的引入使得對于單精度數,實際可以表達的指數值的范圍就變成-127到128之間(包含兩端)。
M為尾數,其中單精度數為23位長,雙精度數為52位長。IEEE標準要求浮 點數必須是規范的。這意味著尾數的小數點左側必須為1,因此在保存尾數的時候,可以省略小數點前面這個1,從而騰出一個二進制位來保存更多的尾數。這樣實 際上用23位長的尾數域表達了24位的尾數。例如對于單精度數而言,二進制的1001.101(對應于十進制的9.625)可以表達為1.001101 × 23,所以實際保存在尾數域中的值為00110100000000000000000,即去掉小數點左側的1,并用0在右側補齊。
浮點數的表示約定
單精度浮點數和雙精度浮點數都是用IEEE 754標準定義的,其中有一些特殊約定,例如:
1、當P=0,M=0時,表示0。
2、當P=255,M=0時,表示無窮大,用符號位來確定是正無窮大還是負無窮大。
3、當P=255,M≠0時,表示NaN(Not a Number,不是一個數)。
等等。。。
將二進制轉換為 十進制浮點數 單精度
例子:
0x00280000
轉換成二進制
00000000001010000000000000000000
符號位 指數部分(8位) 尾數部分
0 00000000 01010000000000000000000
符號位=0;因指數部分=0,則:尾數部分M為:
0.01010000000000000000000=0.3125
該浮點數的十進制為:
(-1)^0*2^(-126)*0.3125
=3.6734198463196484624023016788195e-39
標準文檔 //754r.ucbtest.org/web-2008/drafts/archive/2006-10-04.pdf