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