深入理解计算机系统 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;
}
posted @ 2021-01-18 16:27  alexhe101  阅读(629)  评论(1编辑  收藏  举报