CSAPP Data Lab

CSAPP Data Lab Solution

less or euqal than

isLessOrEqual - if x <= y then return 1, else return 0

Example: isLessOrEqual(4,5) = 1.

Legal ops: ! ~ & ^ | + << >>

Max ops: 24

Rating: 3

  • 判断一个数是否less or equal than 另一个数可以使用 -x + y 判断结果的符号位是否为0即可(可以涵盖x == y的情况)
  • 但是涉及到加减运算就要考虑sign bit overflow的情况。
  • $-2^{w-1} \leq x, y \leq 2^{w-1}-1$ 如果同符号的两个数做减法一定不会出现越界的情况。而不同符号做减法则大概率出现越界的情况。(位运算得到了与我们期待值不符的值一定是我们期待的结果越界了)
  • 上述分析我们可以把问题拆分为两部分判断
    • 如果是同符号则判断~x+1+y的符号位是否为0
    • 如果是不同符号的情况,我们则要屏蔽掉~x+1+y得到的结果,单纯以符号位判断结果
int isLessOrEqual(int x, int y) {
  /* 1.如果符号位相同判断 ~x+1+y符号位是否为0; 2.如果符号位不同则以符号位判断大小 */
  int res = ~x + 1 + y; // y - x 期待结果为正数或者0 两种情况符号位为都0
  int signX = x >> 31;
  int signY = y >> 31;
  //符号相同不会出现溢出的情况,结果一定在[-2^(w-1), 2^(w-1)-1]内。此时只需要判断y - x符号位是否为0即可
  res = (!(res >> 31)) & (~(signX^signY));// 如果符号位不同 &(~(signX^signY))会把res结果屏蔽掉
  //符号位不同的情况下只需要看x的符号位是否为0即可
  int signRes = (signX ^ signY)&(!~signX);
  return  res| signRes;
}

logicalNeg

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 x只要bit位上存在1取!值即为0,所以只保留住1个1就可以代表整个数值
    • x&(~x+1)可以保留最右一位1(Tmin也适用);对于0来说 x&(~x+1) 仍然是0
    • 保留最右位1后对整个数再取反加1,非0的数一定不会出现最高位进位的现象,而~0的最高位一定会进位
    • 将数值»31判断最高位的值即可
int logicalNeg(int x) {
  /*只保留右侧第一个1; 取反+1; 取最高位的符号*/
  x = x & (~x + 1); 
  x = ~x + 1;
  x = ~x >> 31 & 0x01;
  return x;
}