深入理解计算机系统 csapp datalab 详解
深入理解计算机系统 csapp datalab 详解
实验链接:教材网站
educoder在线测评平台:educoder
题解
bitXor
//1
/*
* bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1
* Legal ops: ~ &
* Max ops: 14
* Rating: 1
*/
int bitXor(int x, int y) {
return ~((~(~x&y))&(~(x&~y)));
}
/*使用离散数学的方法,列出真值表,得到
xor = (~x&y)|(x&~y)
再使用德摩根律消去或即可
tmin
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {
return 0x1<<31;
}
//很简单,没什么好说的
isTmax
//2
/*
* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x) {
int eqz = !!((~x)^0x0);//如果x=ffffffff,eqz = 0,否则eqz = 1
return (!((x+1)^(~x)))&(eqz);
}
/*
首先整体的思路是,如果一个数+1和取反后得到的结果一样,那么说明是最大值或者最小值(ffffffff+1 = 00000000)
同时,再排除掉ffffffff的情况即可判断是否为最大值
*/
allOddBits
/*
* allOddBits - return 1 if all odd-numbered bits in word set to 1
* where bits are numbered from 0 (least significant) to 31 (most significant)
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x) {
int tmp;
int detect = 0xAA<<8|0xAA;
detect = detect<<16|detect;
tmp = x|detect;
return !(tmp^x);
}
/*
思路:先构造出一个全部奇数位为1,偶数位为0的数字detect用于检测
将x|detect,若x全部奇数位都为1,那么使用或操作不会使tmp和x有差别,否则tmp!=x
最后,检测tmp和x是否相等即可
*/
negate
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return (~x)+0x1;
}
//按位取反+1
isAsciiDigit
//3
/*
* isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
* Example: isAsciiDigit(0x35) = 1.
* isAsciiDigit(0x3a) = 0.
* isAsciiDigit(0x05) = 0.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 3
*/
int isAsciiDigit(int x) {
int xt = x&0xff;
int xh = xt>>4;
int xl = xt&0x0f;
int smaller = ((0x9+(~xl+1))>>31)&0x1;
return !(xt^x)&!(xh^0x3)&(!smaller);
}
/*
首先取出x的最低8位,作为xt
xt的高4位,作为xh,低4位作为xl
smaller用来判断9是否<smaller,若是,则取1
最终的条件是,x>0(通过xt^x判断),xh==3(通过xh^0x3判断),以及xl<=9
*/
conditional
/*
* conditional - same as x ? y : z
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int conditional(int x, int y, int z) {
int t= !!x;
t = (t<<31)>>31;
return (t&y)+(~t&z);
}
/*
思路
由x!=0,return y,x=0时return z可知
仅需构造ret = t*y+(1-t)*z即可
t = (x!=0)
*/
isLessOrEqual
int isLessOrEqual(int x, int y) {
int subFlag = !((y+((~x)+0x1))&(0x1<<31));//判断y-x是否为正数,有可能溢出 溢出情况为 y正 x负,或y负x正
int ySignal = (y>>31)&0x1;
int xSignal = (x>>31)&0x1;
int yBig = !ySignal&xSignal;
int xBig = !xSignal&ySignal;
return subFlag&(!(xBig))|yBig;;
}
/*
思路:
直接将x,y相减,判断符号大小,并且可能有溢出,因此需要对溢出进行单独判断
*/
logicalNeg
//4
/*
* logicalNeg - implement the ! operator, using all of
* the legal operators except !
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int logicalNeg(int x) {
int negx = ~x+1;
int ret = negx^x;
return 0x1^(((ret>>31)&0x1)|((x>>31)&0x1));
}
/*
思路
0和其他数字的一个重大区别是 0取补码之后还是和自身相等
当然,0xffffffff也有可能取补码后和自身相等。因此对0xffffffff进行单独判断((x>>31)&0x1)
*/
howManyBits
int howManyBits(int x) {
int b16,b8,b4,b2,b1,b0;
int sign=x>>31;
x = (sign&~x)|(~sign&x);//如果x为正则不变,否则按位取反(这样好找最高位为1的,原来是最高位为0的,这样也将符号位去掉了)
// 不断缩小范围
b16 = !!(x>>16)<<4;//高十六位是否有1
x = x>>b16;//如果有(至少需要16位),则将原数右移16位
b8 = !!(x>>8)<<3;//剩余位高8位是否有1
x = x>>b8;//如果有(至少需要16+8=24位),则右移8位
b4 = !!(x>>4)<<2;//同理
x = x>>b4;
b2 = !!(x>>2)<<1;
x = x>>b2;
b1 = !!(x>>1);
x = x>>b1;
b0 = x;
return b16+b8+b4+b2+b1+b0+1;//+1表示加上符号位
}
/*
代码来源于网络
通过二分法,查找出1的最高位
*/
floatScale2
//float
/*
* floatScale2 - Return bit-level equivalent of expression 2*f for
* floating point argument f.
* Both the argument and result are passed as unsigned int's, but
* they are to be interpreted as the bit-level representation of
* single-precision floating point values.
* When argument is NaN, return argument
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatScale2(unsigned uf) {
int signal = (uf)&(1<<31);
unsigned exp = (uf>>23);
unsigned clearBits;
if((exp&0xff)==0x0)
{
return (uf<<1)|signal;
}
//NAN
if((exp&0xff)==0xff)
{
return uf;
}
exp = exp+1;
//NAN
if((exp&0xff)==0xff)
{
return 0x7f800000|signal;
}
exp = exp<<23;
clearBits = 0x807fffff;
uf = uf&clearBits;
uf = uf|exp;
return uf;
}
/*思路
取符号位,exp,若为NAN或0,可简单操作后直接返回。
若exp+1后成为nan,也可直接范围。
否则将exp替换为新的exp即可。
*/
floatFloat2Int
/*
* floatFloat2Int - Return bit-level equivalent of expression (int) f
* for floating point argument f.
* Argument is passed as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point value.
* Anything out of range (including NaN and infinity) should return
* 0x80000000u.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
int floatFloat2Int(unsigned uf) {
unsigned exp = (uf>>23)&0xff;
unsigned tmp;
int shift;
int signal;
int clearBits;
int setBits;
if((exp)<127) return 0;
if((exp)>159) return 0x80000000u;
tmp = uf;
signal = (uf>>31)&0x1;
shift = 23-(exp-127);
if((exp&0xff)!=0)
{
exp = exp-127;
tmp = tmp>>shift;
clearBits = ~(0xffffffff<<(exp));
setBits = 0x1<<(exp);
tmp = tmp&clearBits;
tmp = tmp|setBits;
if(signal==0) return tmp;
else return (~tmp)+1;
}else
{
return 0;
}
}
floatPower2
/*
* floatPower2 - Return bit-level equivalent of the expression 2.0^x
* (2.0 raised to the power x) for any 32-bit integer x.
*
* The unsigned value that is returned should have the identical bit
* representation as the single-precision floating-point number 2.0^x.
* If the result is too small to be represented as a denorm, return
* 0. If too large, return +INF.
*
* Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatPower2(int x) {
unsigned exp;
unsigned signal;
unsigned ret;
if(x>127) return 0x7f800000;
if(x<-126) return 0;
exp = x+127;
signal = 0x0<<31;
exp = exp<<23;
ret = 0;
return ret|exp|signal;
}