随笔-15  评论-2  文章-0  trackbacks-0

研究了一下浮点型在内存中的表示方法,终于明白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 阅读(990) 评论(0)  编辑 收藏 引用 所属分类: C/C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理