研究了一下浮點型在內(nèi)存中的表示方法,終于明白fortify果然不是吃素的,原來double型數(shù)字真的有可能超過200位的。。
一、浮點型在內(nèi)存中的表示
單精度float型: 1位符號位, 8位階碼(固定偏移 7F), 尾數(shù)23, 固定隱含位有
雙精度double型: 1位符號位, 11位階碼(固定偏移 3FF), 尾數(shù)52, 固定隱含位有
long double型: 1位符號位, 15位階碼(固定偏移3FFF), 尾數(shù)64, 固定隱含位無
某些編譯器中把long double作double處理
其中,
符號位s:0表示正,1表示負(fù);
階碼e:表示指數(shù),需要減去固定偏移de;
尾數(shù)x:表示純小數(shù)位,固定隱含位z是指整數(shù)位的1或者0。
表示成十進(jìn)制就是(-1)^s * 2^(e-de) * (z+x)
對于32位系統(tǒng),float占32位,double占64位
舉例來說,在BIG ENDIAN中二進(jìn)制表示為01000001 00100000 00000000 00000000的浮點數(shù),根據(jù)上面的規(guī)則,可以寫成:
0,10000010,0100000 000000000 0000000
符號位s=0,階碼e=10000010b=130,固定偏移de=0x7F=127,尾數(shù)x=0.01000000000000000000000b=0.25,固定隱含位有,z=1
根據(jù)公式可以算出這個數(shù)的十進(jìn)制表示為:(-1)^0 * 2^(130-127) * (1+0.25) = 10.0
二、一些特殊的浮點數(shù)
0,00000000,0000000 00000000 00000000和1,00000000,0000000 00000000 00000000均表示0(階碼和尾數(shù)都是0)
*,11111111,******* ******** ******** 表示非法數(shù)字(階碼是255時)
最大的float數(shù):0,11111110,1111111 11111111 11111111 用10進(jìn)制表示約為 +3.4e38
最小的float數(shù):1,11111110,1111111 11111111 11111111 用10進(jìn)制表示約為 -3.4e38
絕對值最小的float數(shù):0,00000000,0000000 00000000 00000001和1,00000000,0000000 00000000 00000001
三、浮點數(shù)的精度
單精度數(shù)的尾數(shù)用23位存儲,加上默認(rèn)的小數(shù)點前的1位1,2^(23+1) = 16777216。因為 10^7 < 16777216 < 10^8,所以說單精度浮點數(shù)的有效位數(shù)是7位。
雙精度的尾數(shù)用52位存儲,2^(52+1) = 9007199254740992,10^16 < 9007199254740992 < 10^17,所以雙精度的有效位數(shù)是16位。
如果你在浮點數(shù)的有效位后增加數(shù)字的話,結(jié)果是不會變化的。
四、浮點數(shù)的取值范圍
float取值范圍:
負(fù)數(shù)取值范圍為 -3.4028235E+38 到 -1.401298E-45,正數(shù)取值范圍為 1.401298E-45 到 3.4028235E+38。
double取值范圍:
負(fù)值取值范圍-1.79769313486231570E+308 到 -4.94065645841246544E-324,正值取值范圍為 4.94065645841246544E-324 到 1.79769313486231570E+308。
所以說,double型在sprintf的時候,要么想辦法回避Buffer Overflow的問題,要么就...給字符數(shù)組分配308以上的空間...
posted on 2010-02-11 23:49
RayRiver 閱讀(1031)
評論(0) 編輯 收藏 引用 所屬分類:
C/C++