4 经验总结:预防措施和规范建议
这是一个比较隐蔽的传入参数数值溢出引起的问题。该问题给我们的经验是:
1) 函数处理中要特别关注传入参数可能出现的数值溢出,对可能的溢出做好保护逻辑处理,避免发生一些意想不到的异常,甚至core。
2) 浮点数表示。
5 备注
附:查询资料浮点数表示相关资料
浮点数是这样表示的:
sign exponent mantissa(符号|指数|尾数),有些地方sign也叫做base,mantissa也叫做fraction
简写为S|E|F
正常情况下(除了0、太小的数字以及特殊意义数值之外),一个实数a将被表示成如下形式:
a = S (1.F)*2^E
指数部分E用 移码 表示。
设指数位的位数为p,指数和指数部分数值之间的换算关系为"指数=指数部分数值-2^(p-1)+1",
单精度的指数部分有8位,于是 指数 =指数部分数值-127
这样32位(1+8+23)的float浮点数的结构是这样的:(从左到右的四个字节对应地址从高到低)
1 8 23
S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
^ ^ ^ ^ ^
31 30 23 22 0
The value V represented by the word may be determined as follows:
? If E = 255 and F is nonzero, then V = NaN ("Not a number")
? If E = 255 and F is zero and S is 1, then V = ?1
? If E = 255 and F is zero and S is 0, then V = 1
? If 0 < E < 255 then V = (?1)S 2E?127 1:F where 1:F is intended to represent
the binary number created by pre?xing F with an implicit leading 1 and a binary
point.
? If E = 0 and F is nonzero, then V = (?1)S 2?126 0:F These are sub-normal
("unnormalized") values.
? If E = 0 and F is zero and S is 1, then V = ?0
? If E = 0 and F is zero and S is 0, then V = 0
In particular,
0 00000000 00000000000000000000000 = 0
1 00000000 00000000000000000000000 = -0
1
0 11111111 00000000000000000000000 = Infinity
1 11111111 00000000000000000000000 = -Infinity
0 11111111 00000100000000000000000 = NaN
1 11111111 00100010001001010101010 = NaN
0 10000000 00000000000000000000000 = +1 * 2**(128-127) * 1.0 = 2
0 10000001 10100000000000000000000 = +1 * 2**(129-127) * 1.101 = 6.5
1 10000001 10100000000000000000000 = -1 * 2**(129-127) * 1.101 = -6.5
0 00000001 00000000000000000000000 = +1 * 2**(1-127) * 1.0 = 2**(-126)
0 00000000 10000000000000000000000 = +1 * 2**(-126) * 0.1 = 2**(-127)
0 00000000 00000000000000000000001 = +1 * 2**(-126) *
0.00000000000000000000001 =
2**(-149) (Smallest positive value)
6 考核点
传入参数数值越界。
7 试题
Solaris 32位平台,如下程序执行后,变量 szTmpVal 的值是
…
float fVauleOne = 0;
float fVauleTwo = 0;
float fVauleThree = 0;
char szTmpVal[100] = {0};
fVauleOne = MAX_FLOAT_VALUE-1;( MAX_FLOAT_VALUE表示最大浮点数)
fVauleTwo = MAX_FLOAT_VALUE-1;
fVauleThree = fVauleOne * fVauleTwo
ACE_OS::sprintf(szTmpVal,"%f", fVauleThree);
…
A:"0";
B:"-1";
C:"Inf";
D:""
答案:C
阅读(406) | 评论(0) | 转发(0) |