算法竞赛入门经典第二版(刘汝佳)第一章思考题
deran pan, blg-007
1. int型整数的最小值和最大值是多少(需要精确值)?
int类型长度为4字节(32 bit)。最高位为符号位,0表示整数,1表示负数。另外31 bit用来表示数值。故int型的最大值为 0x7fffffff(2147483647) 。最大值加1为 0x7fffffff+0x1=0x80000000 。 0x80000000(−2147483648) 是int型所能表示的最小值。0xffffffff表示-1。
2. double型浮点数能精确到多少位小数?或者这个问题本身值得商讨。
3. double型浮点数最大正数和最小负数值分别是多少(不必特别精确)?
第二和第三题在这里统一叙述一下,double类型长度较大有64bit,为了简明期间先叙述float类型的浮点数,也就是单精度。C语言的浮点数表示符合IEEE 754规范。其中对浮点数的定义如下表所示:
长度 | 符号 | 指数 | 尾数 | 有效位数 | 指数偏移 | 说明 |
---|---|---|---|---|---|---|
单精度 | 32 bit | 1 | 8 | 23 | 24 | 127 |
双精度 | 64 bit | 1 | 11 | 52 | 53 | 1023 |
也就是说32 bit的单精度浮点数其中低一位为符号位,0表示正,1表示负。接着后8 bit为指数位,因为其阶码采用移码表示,偏移量为 27−1=127 ,故指数0其阶码应当位127。剩下的23位用来表示尾数,用原码表示且采用隐藏位。其所表示的位标准化的后的浮点数,因此含有一位隐含位。C语言表示如下:
typedef struct _FP_SINGLE {
uint32_t nFraction : 23;
uint32_t nExponent : 8;
uint32_t nSign : 1;
} FP_SINGLE;
一个示例程序如下:
示例中可知浮点数0.5所对应的符号位为0,指数为-1,尾数为0。计算过程如下,小数部分十进制转换位二进制采用乘二取整法,
0.510=0.12
。规格化后为
1.02×2−1
。由此可知1为隐含位,尾数为0,指数位-1。这就是0.5浮点数的表示。
另外再举一个例子:
−19.12510=−10011.0012
,规格化后为
−1.00110012×24
。由此可知符号位为1表示负,指数为4,尾数为
0.1001100100000000000000002=163840010
。该结果可由上述程序验证。
到此已经大概知道单精度浮点数的在计算机中的表示格式,再来看看单精度能精确到多少小数。在有效位为24 bit的前提下,能精确到多少小数是与指数相关,确切的应该问单精度能表示多少有效数字位。首先理论上一个有限的二进制数肯定可以转换位一个有限的十进制数,但是一个有限的十进制数不一定可以转换为一个有限的二进制数。因此如果能提供足够多的二进制位数,那么肯定可以精确的转换为一个十进制数。然而单精度数只有24 bit表示尾数。由于 107<0xffffff<108 ,故单精度可以表示7~8位的有效位。
接下来再讨论单精度所能表示的范围,由之前叙述的可知浮点数的表示由1位符号,8位阶码,23位尾数组成。在IEEE 745还规定的有一些特殊值如下表所示:
形式 | 指数 | 尾数 |
---|---|---|
零 | 0 | 0 |
非正规形式 | 0 | 非0 |
正规形式 | 1~2e−2 | 任意 |
无穷 | 2e−1 | 0 |
NaN(Not a Number) | 2e−1 | 非0 |
故由此可得浮点数的表示范围如下:
指数 | 尾数 | 数值 |
---|---|---|
最大数 | 0xFE | 0x7FFFFF |
最小规范数 | 0x01 | 0x000000 |
最小非规范数 | 0x00 | 0x000001 |
C语言实践如下图所示:
到此单精度就记录完了,double类型的双精度也是与之类似的,所以就不在详细记录了。
4. 逻辑运算符“&&”、“||”和“!”(表示逻辑非)的相对优先级是怎么样的?也就是说,a&&b||c应该理解成(a&&b)||c还是a&&(b||c),或者随便怎么理解都行?
运算符的优先级和结合性如下表所示,从上至下优先级递减。
运算符 | 结合性 |
---|---|
()、[]、->、. | 从左至右 |
!、~、++、–、+、-、*、&、sizeof | 从右至左 |
×、/、% | 从左至右 |
+、- | 从左至右 |
<<、>> | 从左至右 |
<、<=、>、>= | 从左至右 |
==、!= | 从左至右 |
& | 从左至右 |
^ | 从左至右 |
| | 从左至右 |
&& | 从左至右 |
|| | 从左至右 |
?、: | 从右至左 |
=、+=、-=、*=、/=、%=、&=、^=、|=、<<=、>>= | 从右至左 |
, | 从左至右 |
5. if(a) if(b) x++;else y++的确切含义是什么?这个else应该和那个if配套?有没有办法明确表达出配套方法?
这个else应该和if(a)配套。使用恰当的缩进、换行和花括号可以明确的表达出配套。代码如下:
if (a) {
if (b)
x++;
}
else {
y++;
}