# 计算机系统基础:lab 1

/* 
 *   lsbZero - set 0 to the least significant bit of x 
 *   Example: lsbZero(0x87654321) = 0x87654320
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 1
 */
int lsbZero(int x) {
  return x>>1<<1;// 右移再左移,最后一位补 0
}
/* 
 * byteNot - bit-inversion to byte n from word x  
 *   Bytes numbered from 0 (LSB) to 3 (MSB)
 *   Examples: getByteNot(0x12345678,1) = 0x1234A978
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 6
 *   Rating: 2
 */
int byteNot(int x, int n) {
  //n<<3 = 乘 8, 让 0xff 移位后对应字节为 1, 其余为 0, 异或取反
  return x^(0xff<<(n<<3));
}
/* 
 *   byteXor - compare the nth byte of x and y, if it is same, return 0, if not, return 1
 *   example: byteXor(0x12345678, 0x87654321, 1) = 1
 *			  byteXor(0x12345678, 0x87344321, 2) = 0
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 2 
 */
int byteXor(int x, int y, int n) {
  return !!((x^y)&(0xff<<(n<<3)));
}
/* 
 *   logicalAnd - x && y
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 3 
 */
int logicalAnd(int x, int y) {
  return (!!x)&(!!y);// 使用!!获得 0 和 1
}
/* 
 *   logicalOr - x || y
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 3 
 */
int logicalOr(int x, int y) {
  return (!!x)|(!!y);
}
/* 
 * rotateLeft - Rotate x to the left by n
 *   Can assume that 0 <= n <= 31
 *   Examples: rotateLeft(0x87654321,4) = 0x76543218
 *   Legal ops: ~ & ^ | + << >> !
 *   Max ops: 25
 *   Rating: 3 
 */
int rotateLeft(int x, int n) {
  return (x<<n)|((~((~0)<<n))&(x>>(32+(~n+1))));// 将 x 左移 n 位和 x 右移 32-n 位通过或运算拼接
}
/*
 * parityCheck - returns 1 if x contains an odd number of 1's
 *   Examples: parityCheck(5) = 0, parityCheck(7) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 4
 */
int parityCheck(int x) {
  x=(x>>16)^x;// 中间折叠,对称位都为 1 则异或后为 0
  x=(x>>8)^x;// 再次折叠
  x=(x>>4)^x;
  x=(x>>2)^x;
  x=(x>>1)^x;
  return x&1;// 剩余的最后一位是否为 1
}
/*
 * mul2OK - Determine if can compute 2*x without overflow
 *   Examples: mul2OK(0x30000000) = 1
 *             mul2OK(0x40000000) = 0
 *         
 *   Legal ops: ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 2
 */
int mul2OK(int x) {
  return 1^((1&(x>>31))^(1&(x>>30)));// 取出 x 第一位和第二位判断
}
/*
 * mult3div2 - multiplies by 3/2 rounding toward 0,
 *   Should exactly duplicate effect of C expression (x*3/2),
 *   including overflow behavior.
 *   Examples: mult3div2(11) = 16
 *             mult3div2(-9) = -13
 *             mult3div2(1073741824) = -536870912(overflow)
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 12
 *   Rating: 2
 */
int mult3div2(int x) {
  x=(x<<1)+x;
  x=x+(1&(x>>31));// 负数 + 2*2-1
  return x>>1;
}
/* 
 * subOK - Determine if can compute x-y without overflow
 *   Example: subOK(0x80000000,0x80000000) = 1,
 *            subOK(0x80000000,0x70000000) = 0, 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 3
 */
int subOK(int x, int y) {
  int r=x+(~y+1);
  int a=(x>>31)&1;
  int b=(y>>31)&1;
  int c=(r>>31)&1;
  return !((a^b)&(a^c));// 正数减负数结果为负 或者 负数减正数结果为正
}
/* 
 * absVal - absolute value of x
 *   Example: absVal(-1) = 1.
 *   You may assume -TMax <= x <= TMax
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 10
 *   Rating: 4
 */
int absVal(int x) {
  int s=(x>>31);// 取符号位
  return (x^s)+!!s;// 正数不变,负数取反 + 1
}
/* 
 * float_abs - Return bit-level equivalent of absolute value of 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 representations of
 *   single-precision floating point values.
 *   When argument is NaN, return argument..
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 10
 *   Rating: 2
 */
unsigned float_abs(unsigned uf) {
  int s=uf&0x7fffffff;// 去掉符号位
  if(s>0x7f800000)// 阶码为 1, 尾数不为 0,NAN
    return uf;
  return s;
}
/* 
 * float_f2i - 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 float_f2i(unsigned uf) {
  int e=((uf&0x7f800000)>>23)-127;// 阶码
  int m=(uf&0x007fffff)|0x00800000;// 尾数
  if((e>31)||((uf&(0x7fffffff))>0x7f800000))
    return 0x80000000u;
  if(e<0)// 小于 1 直接返回 0
    return 0u;
  if((uf>>31)&1){// 负数要取反再加 1
    if(e>23) return (~(m<<(e-23)))+1;
    else return (~(m>>(23-e)))+1;
  }else{// 正数
    if(e>23) return m<<(e-23);
    else return m>>(23-e);
  }
}
更新于