本文为中科大研究生课程——计算机系统作业1的题目解答记录。使用的教材为《深入理解计算机系统》(第3版)。
题目与解答
2.58
编写过程is_little_endian, 当在小端法机器上编译和运行时返回1, 在大端法机器上编译运行时则返回0 。这个程序应该可以运行在任何机器上,无论机器的字长是多少。
解:
1 |
|
2.61
写一个C 表达式,在下列描述的条件下产生1, 而在其他情况下得到0 。假设x是int类型。
A. x的任何位都等于1 。
B. x的任何位都等于0 。
C. x的最低有效字节中的位都等于1 。
D. x的最高有效字节中的位都等于0 。
代码应该遵循位级整数编码规则,另外还有一个限制,你不能使用相等(==)和不相等(!=)测试。
解:
1 | !~x |
1 | !x |
1 | !((~x)&0xff) 或 |
1 | !((x >> ((sizeof(int)-1) << 3)) & 0xff) |
2.77
假设我们有一个任务:生成一段代码,将整数变量x 乘以不同的常数因子K 。为了提高效率,我们想只使用 + 、- 和<<运算。对于下列K的值,写出执行乘法运算的C表达式,每个表达式中最多使用3个运算。
A. K=17
B. K=-7
C. K=60
D. K=-112
解:
1 | (x<<4)+x |
1 | x-(x<<3) |
1 | (x<<6)-(x<<2) |
1 | (x<<4)-(x<<7) |
2.84
填写下列程序的返回值,这个程序测试它的第一个参数是否小于或者等于第二个参数。假定函数f2u 返回一个无符号32 位数字,其位表示与它的浮点参数相同。你可以假设两个参数都不是NaN 。两种0, +0 和-0 被认为是相等的。
1 | int float_le(float x, float y) |
解:
1 | unsigned f2u(float x) |
2.89
我们在一个int 类型为32 位补码表示的机器上运行程序。float类型的值使用32 位IEEE 格式,而double 类型的值使用64 位IEEE 格式。我们产生随机整数x 、y 和z, 并且把它们转换成double 类型的值:
1 | /*Create some arbitrary values*/ |
对于下列的每个C 表达式,你要指出表达式是否总是为1 。如果它总是为1, 描述其中的数学原理。否则,列举出使它为0的参数的例子。请注意,不能使用IA32 机器运行GCC 来测试你的答案,因为对于float 和double, 它使用的都是80 位的扩展精度表示。
1 | A. (float)x==(float)dx |
解:
A. 真。int类型转成double类型不会损失精度,此时,x 和 dx 转成float类型虽然可能会损失精度,但是在舍入原则相同的情况下得到的结果相同。
B. 假。当x-y得到的结果溢出时,转成double类型的结果与真实结果不同,如y=INT_MIN时。
C. 真。两个int类型转成double类型后,相加得到的结果仍然在double类型可表示范围内,且不会因为舍入丢失精度,所以是可以结合的。
D. 假。两个int类型转成double类型后,相乘得到的结果不一定在double类型可表示范围内,可能会发生溢出或者由于舍入导致失去精度,所以不具有结合性。
E. 假。当dx != 0 且 dz == 0时,左边结果为1,右边结果为无穷大,不相等。
2.91
大约公元前250 年,希腊数学家阿基米德证明了\(\frac{223}{71}<\pi<\frac{22}{7}\)。如果当时有一台计算机和标准库<math.h>, 他就能够确定\(\pi\)的单精度浮点近似值的十六进制表示为 0x40490FDB 。当然,所有的这些都只是近似值,因为\(\pi\)不是有理数。
A. 这个浮点值表示的二进制小数是多少?
B. \(\frac{22}{7}\)的二进制小数表示是什么?提示:参见家庭作业2. 83 。
C. 这两个\(\pi\)的近似值从哪一位(相对于二进制小数点)开始不同的?
解:
1 | 十六进制: |
B. \(\frac{22}{7}=3+\frac{1}{7}\)
1 | Y=1,2^k-1=7,k=3,y=001 |
C. 从小数点后第9位开始不同。