CSAPP Data Lab
Data Lab 的内容是仅采用有限制的位运算符实现一些函数。
bitXor
实现按位异或。
\(x\oplus y = (x\wedge \neg y)\vee(\neg x\wedge y)=\neg(\neg(x\wedge \neg y)\wedge\neg(\neg x\wedge y))\)
1 | int bitXor(int x, int y) |
tmin
计算\(T_{min}\)。
其位级表示为0x80000000
,即1 << 31
。
1 | int tmin(void) |
isTmax
判断\(x\)是否是\(T_{max}\)。
\(T_{max}\)和-1 均满足\(\neg x = x + 1\),判断\(x\)和\(y\)相等可以用!(x ^ y)
,判断不为-1 可以按位取反之后取两次非(不取两次非的话可能会取到\(>1\)的值)。
1 | int isTmax(int x) |
allOddBits
判断\(x\)的奇数位上是否都为 1。
将\(x\)的每个字节都或0x55
,如果奇数位上都为 1 的话会得到0xFFFFFFFF
也就是-1,之后判断是否为-1。
1 | int allOddBits(int x) |
negate
计算\(x\)的相反数。
取反+1,书上有写。
1 | int negate(int x) |
isAsciiDigit
判断\(x\)是否在0x30
到0x39
之间。
\(x\)右移四位,必须和 3 相等,之后\(x\)的(低位起)第 4 位为 0,或者第 4 位为 1 并且第 2、3 位为 0。
1 | int isAsciiDigit(int x) |
conditional
实现x ? y : z
。
首先通过\(x\)计算\(a\),如果\(x\)不为 0 则\(a\)为0xFFFFFFFF
,否则\(a\)为 0。观察得到a = !x - 1
。之后利用0xFFFFFFFF & x == x
和0 & x == 0
即可。
1 | int conditional(int x, int y, int z) |
isLessOrEqual
判断x <= y
。
一般来说计算y - x
,判断符号位为 0 即可,对于溢出的情况,比较\(x\)和\(y\)的符号位,如果\(x\)为负并且\(y\)非负,则答案必为 1,如果\(x\)非负并且\(y\)为负,则答案必为 0。
1 | int isLessOrEqual(int x, int y) |
logicalNeg
实现!x
。
~0 == -1
,即检查~x
的每一位是否都为 1。
1 | int logicalNeg(int x) |
howManyBits
以补码方式表示\(x\)的最小位数。
注意非负数需要以符号位 0 开头,负数的位数是取反后的位数加上一个符号位。
首先根据利用之前的条件判断计算\(y\),如果\(x\)是非负数,y = x
,否则y = ~x
。
答案初始为 1(符号位),之后不考虑符号位看表示\(y\)需要多少位即可。
对于答案的每一位,看它是 1 还是 0,比如如果答案的第 5 位为 1,则\(y\)的长度大于 16,即y >> 16
不为 0,下一步迭代\(y\)的高 16 位,反之迭代\(y\)的低 16 位。
1 | int howManyBits(int x) |
floatScale2
计算2 * f
。
根据规格化、非规格化、特殊情况三种来判断,注意非规格化转化到规格化和规格化溢出的情况。
1 | unsigned floatScale2(unsigned uf) |
floatFloat2Int
浮点数转整数。
非规格化的数返回 0,特殊情况返回\(T_{min}\);规格化的指数\(E<0\)的情况返回 0,\(E>31\)的情况返回\(T_{min}\),其余的情况正常计算。
1 | int floatFloat2Int(unsigned uf) |
floatPower2
计算\(2.0^x\)。
最小非规格化数为\(2^{-23}\times2^{-126}\),最小规格化数为\(1\times2^{-126}\),最大规格化数为\((2-\varepsilon)\times2^{127}\)。
1
2
3
4
5
6
7
8
9
10
11unsigned floatPower2(int x)
{
if (x < -149)
return 0;
else if (x < -126)
return 1 << (x + 149);
else if (x < 128)
return (x + 127) << 23;
else
return 0x7f800000;
}
总结
难度比预想大一些,尤其是整数部分的最后几道题,有很多小 trick,但是感觉收获不大,可能用处比较局限。
CSAPP Data Lab