CSAPP整数位操作实验

整数位操作实验


实验目的

整数的二进制表示及操作更为熟悉

实验内容

  • 本实验由一组程序实现问题构成
  • 仅利用位操作符来实现特定的功能
    • 位操作符:! ~ & ^ | + << >>
    • 特定的功能:大小比较、条件判断、浮点乘法等
  • 每个题目可能包含着一些特别设定的规则
    • 运算符的数量(见分发布的代码中函数注释)
    • 可使用的常量需在8比特可表述的范围内,即0x00 (0)到0xFF (255)

实验步骤

bitXor

  1. 按照ppt上打就行。

    int32_t bitXor(int32_t x, int32_t y)
    {
      int32_t res =~ (~(x & ~y) & ~(~x & y));
      return res;
    }
    

Tmin

  1. 1左移31位即可。

    int32_t tmin(void)
    {
      int32_t res = 1 << 31;
      return res;
    }
    

isTMax

  1. 由ppt得(!(~(x+x+1)))

  2. 排除0xffffffff即判断(x+1)!=0,可用!!(x+1)

  3. &将二者并起来就行。

    int32_t isTmax(int32_t x)
    {
      int32_t res = (!(~ (x+x+1)))&(!!(x+1));
      return res;
    }
    

allOddBits

  1. 获得0x55555555可用移位操作

  2. 与x进行|,符合条件,返回0xffffffff

  3. 判断0xffffffff,如果x=0xffffffff,则!~(x)=1,否则为0。

    int32_t allOddBits(int32_t x)
    {
      int32_t res =!(~(x | ((0x55<<24)+(0x55<<16)+(0x55<<8)+0x55)));
      return res;
    }
    

Negate

  1. 取反加一

    int32_t negate(int32_t x)
    {
      int32_t res = ~x+1;
      return res;
    }
    

isAsciiDigit

  1. (x+(~0x30+1))即为(x-0x30),右移31位得到符号位,若在范围内,返回0,再取!,得1.

  2. !((0x39+(~x+1)))>>31同理

  3. 二者取&即可

    int32_t isAsciiDigit(int32_t x)
    {
      int32_t res = !((x + (~ 0x30+1))>>31) & !((0x39 + (~ x+1))>>31);
      return res;
    }
    

Conditional

  1. 现将x转化为0或1,用(!!x),0返回0,非0返回1。

  2. 1取反加1得0xffffffff,0取反加1得0x00000000,则mask=~(!!x)+1,相反,mask2=~(mask1)

  3. 使用ppt的公式代入即可

    int32_t conditional(int32_t x, int32_t y, int32_t z)
    {
      int32_t res = ((~(!!x)+1) & y) | (~(~(!!x)+1) & z);
      return res;
    }
    

isLessOrEqual

  1. 由ppt可知,得分同号和异号的情况,取符号x_sgin=x>>31,y_sign=y>>31

  2. 可以使用类似函数7的公式mask1 & y | mask2 & z

  3. 若同号,即~(x_sign^y_sign)=0xffffffff,!!((x+~y+1)>>31)在x>=y时为0,二者取&得同号情况

  4. 若异号,即~(x_sign^y_sign)=0x0000000,!!(s_sign)在x>y时为0。

  5. 若相等,即!!(x+~y+1)=1

  6. 3.4.5.取|得结果。

    int32_t isLessOrEqual(int32_t x, int32_t y)
    {
      int32_t x_sign = x>>31;
      int32_t y_sign = y>>31;
      int32_t res = (~(x_sign ^ y_sign) & !!((x+~y+1)>>31)) | ((x_sign ^ y_sign) & !!(x_sign)) | !(x+~y+1); 
      return res;
    }
    

logicalNeg

  1. 由ppt可知,x和-x符号相同为0,返回1,排除0x8000000

  2. x_sign^neg_x_sign+1 = 1

  3. 若是x=0x80000000,即x_sign+1 = 0,x_sign^neg_x_sign+1x_sign+1& 会返回0,而x=0的时候返回1。这样就排除了0x80000000

    int32_t logicalNeg(int32_t x)
    {
      int32_t x_sign = x>>31;
      int32_t neg_x = ~x+1;
      int32_t neg_x_sign = neg_x>>31;
      int32_t res = ((x_sign^neg_x_sign)+1) & (x_sign+1);
      return res;
    }
    

howManyBits

  1. 分析:即正数求最前面的1的位置加1,负数求最前面的0的位置,可对负数取反,便和正数一样求解。

  2. 使用Condition()函数的思想,令x=(x_sign & ~x) | (~x_sign & x),可对负数取反。

  3. 如果一次右移一位,操作符过多。可以使用二分法思想,将x右移16位,如果x不为0,则说明至少16位前有1,将x的值改为x>>16,结果加上16,否则移动0位。一直右移8,4,2,1位,直到移动1位。最后如果x=1,结果加上1;x=0,结果加上0。最后结果加1(符号位)。

    int32_t howManyBits(int32_t x)
    {
      int32_t res,x_sign,b1,b2,b3,b4,b5;
      x_sign = x>>31;
      x = (x_sign & ~x) | (~x_sign & x);
      b1 = !!(x>>16)<<4;
      x = x>>b1;
      b2 = !!(x>>8)<<3;
      x = x>>b2;
      b3 = !!(x>>4)<<2;
      x = x>>b3;
      b4 = !!(x>>2)<<1;
      x = x>>b4;
      b5 = !!(x>>1);
      x = x>>b5;
      res = b1+b2+b3+b4+b5+x+1;
      return res;
    }
    

实验结果和总结

运行结果截图

实验结果

实验总结

  1. 判断一个数是否为0,!x;判断一个数是否不为0,!!x
  2. 判断一个数是否为-1,!(x+1)或者!~x
  3. 8字节的数构造32字节的数可以用左移和加法
  4. 判断正负数,利用符号位,即x>>31,正数结果为0x00000000,负数结果为0xffffffff
  5. 减法可用加上一个数的负数实现,即取反加一
  6. 三元运算符x?y:z的实现,使用格式res = mask1 & y | mask2 & z,其中mask2=~mask1,当x不为0时mask10xffffffff,x为0时mask10x00000000
  7. 判断两个数a,b是否相等使用异或操作!(a^b),如果相等返回1,不等返回0。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值