data lab
data lab是对应于csapp第二章——信息的表示与处理对应的实验。在限定操作符和操作次数的前提下,使用位级运算来实现一定功能的函数。题目及要求如下图。
函数实现有一定的条件限制(什么运算符都能用,那所有函数都能轻易实现)。
整数规则,如下,耐心看,其实计算机的英文超容易懂。规则有用到的常数在0~0xFF之间,用到的操作符限于& ^ | + << >> ! ~,不能使用if、do、while、for、switch等控制关键字,不能使用宏,不能定义或调用其他函数,不能使用强制类型转换,不能使用除int外的其他数据类型。表1、2中函数的实现要遵循此规则。
浮点数处理规则。规则有不能使用if、do、while、for、switch等控制关键字,不能使用宏,不能定义或调用其他函数,不能使用强制类型转换,不能使用除int或unsigned外的其他数据类型。表3中函数的实现要遵循此规则。
一、表1,位级操作函数
1. bitAnd
此题十分简单,仅用~和|来实现&操作,不细说。
2. getByte
从一个word(32位)x中提取第n个byte(n范围为0~3)。限定运算符为! ~ & ^ | + << >> 。只需将x右移n<<3(相当于*8),然后与0xFF位与即可获得x的第n个byte。
3. logicalShift
因为>>对于有符号数来说表示算术右移(对于符号位为1的数右移位用1填充),题目要求仅用! ~ & ^ | + << >>这些运算符来实现对int类型x逻辑右移x位的函数。事实上无论正负只要将x右移位全部置0。可以构造一个数00...011111(共有n位0)。
4. bitCount
计算一个word x中1的总位数。
5. bang
不采用!来实现!x,要判别x是否所有位都为0,若是返回1,否则返回0。方法时将高16位与低16位相或,如果不全为0,那么低16位中必然有1,然后将8~15位与0~7位相或,如果不全为0,则0~7位中必然有1,依此类推,直到将0位和1位相或,如果0位为0则返回1,否则返回0。
二、 表2,算术函数
6. tmin
返回最小补码,只要返回0x80000000。
7. fitsBits
如果x能够被表示为n-bit的补码就返回1否则返回0,n-bit补码能够表示的数在-2^(n-1) ~ 2^(n-1)-1之间。通过判断x的高(32-n)位是否与n-1位相同来判断x能否被表示为n-bit的补码。
8. divpwr2
计算x/(2^n),其中0 <= n <= 30。对于正数,可直接用>>n实现,对于负数先加2^n-1再>>n来实现。
9. negate
求-x,不能使用"-",再简单不过了,~n+1即可。
10. isPositive
若为正数,返回1。检查符号位是否为0,对于0特殊检查。
11. isLessOrEqual
如果x <= y,返回1,否则返回0。最基本的判断条件是y-x>=0,但是在x,y不同号时存在可能溢出的情况。当y<0,x>0时y-x可能负溢出使得y-x>=0,这种情况要排除;当y>0, x<0时,y-x可能发生正溢出使得y-x<0,但y>=x显然成立,这种情况要考虑进来。
12. ilog2
返回log2 (i)(以2为底,i的对数)的向下取整,题目保证x>0。获得从低到高最后一个1的位号(自0开始统计),如log2 (0b101),log2 (5)得到2,因为1的最高位位号是2。
三、浮点函数
13. float_neg
求-f。f为float类型,但是以unsigned形式传入。十分简单 ,直接将符号位求反。对于NaN,返回原值。
14. float_i2f
将整型转换为浮点型。如1转为1.0,-1转为-1.0。要相对应的从整型数里计算出浮点型的符号位,介码与尾数。并且负数转换为正数求解,对于正整数来说,其解码就是最高为1的位的位号,尾数则是该位以下的所有位,取23位,不足补0,多余则向偶数舍入。
15. float_twice
不用*获得2*f。f为float类型,但是以unsigned形式传入。
总结
实验挺有意思的,比较好地回顾使用了学习到的位级运算、补码、整数和浮点数的表示。读完csapp中第二章后来品用风味更佳哦。