The Solution of Data Lab of CSAPP
一、实验内容
本实验内容为 CMU 的 CSAPP 课程的第一个Lab内容,名称为 Data Lab。授课教师为WHU yili老师。
本实验中,你需要利用整型及浮点数的位表达形式,来解开一些人工谜题,一共有15个需要补充的函数, 除了在线评测之外。
实验的必要内容存在于本人的github实验同名仓库。
二、报告要求
本报告要求学生把实验中实现的所有函数逐一进行分析说明,写出实现的依据,也就是推理过程, 可以是一个简单的数学证明,也可以是代码分析,根据实现中你的想法不同而异。
三、函数分析
bitXor函数
函数要求:
函数名 | bitNor |
---|---|
参数 | int , int |
功能实现 | ~(x | y) |
要求 | ~(x | y) using only ~ and & |
实现分析:
由德摩根律:
$ (x | y) = (x) & (~y) $
函数实现:
1 |
|
copyLSB函数
函数要求:
函数名 | copyLSB |
---|---|
参数 | int |
功能实现 | set all bits of result to least significant bit of x |
实现分析:
通过左移位31,使得最不重要位成为最重要位,然后通过算术右移31位,使得最不重要位填满整个32 bits。
函数实现:
1 |
|
isEqual函数
函数要求:
函数名 | isEqual |
---|---|
参数 | int, int |
功能实现 | return 1 if x == y, and 0 otherwise |
实现分析:
如果两个数相等,等价于bitwise相等,等价于互相异或等于零。
函数实现:
1 |
|
bitMask函数
函数要求:
函数名 | bitMask |
---|---|
参数 | int, int |
功能实现 | Generate a mask consisting of all 1’s lowbit and highbit |
实现分析:
即将全1的32-bits (~0) ,通过两端的零序列与之做与运算,屏蔽除了lowbit至highbit之间的 1。
函数实现:
1 |
|
bitMask函数
函数要求:
函数名 | bitCount |
---|---|
参数 | int |
功能实现 | returns count of number of 1’s in word |
实现分析:
分治思想,将32 bits每2 bits / 4 bits / 8 bits / 16 bits划分,对于 $ 2^n $ ,将此 int 向右移位 n 位, 然后利用 00…00 (n 个) 11…11 (n 个) … 的 mask 对其进行屏蔽后, 与x本身进行叠加,即得此 划分block内 的bit数, 最终通过 5 次移位叠加,得到最终的bit计数。
其中,mask的生成依靠对合适的 constant 进行移位。
函数实现:
1 |
|
bitMask函数
函数要求:
函数名 | tmax |
---|---|
参数 | void |
功能实现 | return maximum two’s complement integer |
实现分析:
考虑到最大数为1 后面跟 31个零,故对(1 << 31) 进行取反。
函数实现:
1 |
|
isNonNegative函数
函数要求:
函数名 | isNonNegative |
---|---|
参数 | int |
功能实现 | return 1 if x >= 0, return 0 otherwise |
实现分析:
通过右移31位,实现全为符号位,然后取否 或者 + 1 或者 & 1 都可。
函数实现:
1 |
|
addOK函数
函数要求:
函数名 | addOK |
---|---|
参数 | int, int |
功能实现 | Determine if can compute x+y without overflow |
实现分析:
针对符号位操作,如果两个加数的符号相反,则不会溢出,否则再判断和 和 某一加数的符号,如果相同则没有溢出。
函数实现:
1 |
|
rempwr2函数
函数要求:
函数名 | rempwr2 |
---|---|
参数 | int, int |
功能实现 | Compute x%(2^n), for 0 <= n <= 30 |
实现分析:
每有一个n,则通过mask屏蔽掉其他的位,最终得到余数结果。
其中,做特殊处理的是取余之后等于零的负数,由于补码不存在 -0,所以自行检测该情况进行置零。
函数实现:
1 |
|
isLess函数
函数要求:
函数名 | isLess |
---|---|
参数 | int, int |
功能实现 | if x < y then return 1, else return 0 |
实现分析:
针对x 、y 、 x - y 的符号位操作,x正y负必定返回 0,x负y正必定返回 1,其他情况判断 x - y的符号。
函数实现:
1 |
|
absVal函数
函数要求:
函数名 | absVal |
---|---|
参数 | int |
功能实现 | absolute value of x |
实现分析:
整数保持不变,负数取反加一。
函数实现:
1 |
|
isPower2函数
函数要求:
函数名 | isPower2 |
---|---|
参数 | int |
功能实现 | returns 1 if x is a power of 2, and 0 otherwise |
实现分析:
注意到,只有一个位为1的int有专有性质: 其加上全1得到的是前面全零,后面全1的数,或 原数恰好为0。
函数实现:
1 |
|
float_neg函数
函数要求:
函数名 | float_neg |
---|---|
参数 | unsigned |
功能实现 | Return bit-level equivalent of expression -f for floating point argument f. |
实现分析:
直接返回转置符号位结果,特别的,如果exp全1,frac非全0,则返回本身。
函数实现:
1 |
|
float_half函数
函数要求:
函数名 | float_half |
---|---|
参数 | unsigned |
功能实现 | Return bit-level equivalent of expression -f for floating point argument f. |
实现分析:
对于一般情况,直接把exp减一。
特别的exp = 1,将frac右移,并在二分位填充1。exp = 0,将frac右移,并在二分位填充0。 (同时需要处理舍入问题)
函数实现:
1 |
|
float_i2f函数
函数要求:
函数名 | float_i2f |
---|---|
参数 | int |
功能实现 | Return bit-level equivalent of expression (float) x |
实现分析:
- sign: 直接拷贝int的符号位。
- exp:基准位 0x4B000000,每次左移(右移)int,exp -=(+=) 0x00800000。
- frac: int通过移位使其对其float的frac位,同时注意舍入。
函数实现:
1 |
|
四、实验总结
总体实验比较考察技巧性,在全然不顾及可读性的前提下,尽可能的化约计算操作数。
化约方法:
- 可以简化的等价逻辑运算:当大量 & | ~ ! 出现时,往往可以通过布尔代数的公式进行等价简化。
- 可以改进的思路:问题考察的形参有多种方式检测是否符合条件,得到充要性条件以方便检测。譬如:对于float_neg中 NaN 的检测可以将检查「exp全一 and frac非全零」等价于检测除符号位外是否大于 0x7F800000。
时间花费
七个小时完成,两个小时优化操作数。