CSAPP实验——datalab
官网
http://csapp.cs.cmu.edu/3e/labs.html
Students implement simple logical, two’s complement, and floating point functions, but using a highly restricted subset of C. For example, they might be asked to compute the absolute value of a number using only bit-level operations and straightline code. This lab helps students understand the bit-level representations of C data types and the bit-level behavior of the operations on data.
参考
Introduction to CSAPP(八):Datalab
《深入理解计算机系统》(CSAPP)实验一 —— Data Lab
bitXor
/* |
用~
和&
表示异或运算。根据异或运算公式Y = A'·B + A·B' = (A'·B)' · (A·B')'
即可。
tmin
/* |
返回补码的最小值,补码最小值就是符号位为1,其余全为0。直接位移可得。
isTmax
/* |
通过位运算计算是否是补码最大值。最大值为符号位为0,其余全1。最后两行是排除x=0xffff
的情况,因为0xffff
也有前三行的性质。
allOddBits
/* |
mask变量的所有奇数位都为1,偶数位为0。经过与运算和异或运算后,只有在x为0的奇数位上,mask ^ (mask & x)
值为1。若x的所有奇数位都为1,则最终结果mask ^ (mask & x)
为全0,经过非运算后返回值为1。
negate
/* |
重要结论:x + ~x + 1 = 0
。已知x补码,求-x的补码:将x补码各位取反(包括符号位)再加1。
isAsciiDigit
/* |
分别计算x-'0'
和'9'-x
,两结果的符号位皆为0即返回1。
conditional
/* |
使用位级运算实现三目运算符。根据 x
的布尔值转换为全0或全1来解决。
isLessOrEqual
/* |
二者的差值可能过大而溢出,所以仅通过subtractionSign来判断是不行的。
logicalNeg
/* |
0和最小数的补码是本身,二者的补码一个全0,一个全1。如果是0,位或操作之后符号位为0,位移后为0,返回值1。如果非0,位或操作之后符号位为1,位移后为全1,即值为-1,返回值为0。
howManyBits
/* howManyBits - return the minimum number of bits required to represent x in |
如果是正数,则需要找最高的为1的一位数是第几位,再加上符号位,结果为n+1;如果是负数,则需要知道其最高的一位是0的(例如4位的1101和三位的101补码表示的是一个值:-3,最少需要3位来表示),按位取反转换为正数做同样处理。
floatScale2
/* |
复习了一下32位浮点数的表达方式。NaN:阶码全为1,尾数非0;无穷大:阶码全1,尾数全0;非规格化的值:阶码全0。
根据输入的数值,可以分为三种情况:
- 输入uf为无穷大和NaN,直接返回uf
- uf为0或无穷小,返回2*uf | sign
- 若exp+1 == 255,返回无穷大,否则返回 exp+1。(exp为浮点数编码的整数部分,exp+1相当于uf*2。)
floatFloat2Int
/* |
- 非规格化,表示非常接近0的数,转换为int值后为0
- 规格化,数的分布从接近0到无穷越来越稀疏,当f不超过int型表示的范围时,转换为int;当超过int型表示的范围时返回0x80000000u
- 特殊,返回0x8000000u
在规格化的float转换为int型整数时,
- 如果E >= 31,小数点右移31位,此时隐含的1和frac占32位,另外还需要一个符号位,超出了int型范围
- 如果E < 0,小数点左移1位后为0.1frac,转换为int后为0
- 如果0 < E < 23, 小数点左移E位后需要舍弃frac中部分位,此时直接将frac右移23-E位,抹去小数部分
- 如果23 <= E < 31,此时小数点右移后frac全部移到小数点以左,将frac左移E-23位,在后面补零
floatPower2
/* |
2.0^x = (1.0 * 2^1)^x = 1.0 * 2^x
,x就是真正指数。由于测试样例数量过多,btest文件中的限时设定为默认10s时可能会超时,使用-T
命令或修改默认值即可。