几道位操作的题目思路与实现

1. 编写一个函数setbits(x,p,n,y),该函数返回对x执行下列操作后的结果值:将x中从第p位开始的n个二进制位设置为y中最右边n位的值,x的其余位保持不变。

这个问题,有如下两种思路:

1)最终&的形式:将x中从第p位开始的n位全部置1,其余位不变,而对于y,先将其最右边的n位移到第p位,这些位不变,其余位置1;最后将二者相与

  a).如何实现第一步?我们可以这样设置一个屏蔽码(让其与x相或):它的中间n位都是1,其余位都是0,然后与x相或,

       举例:设p=6,n=2,x和y都是8位,求掩码的推理过程如下

                  ~0=11111111

                  11111111<<2=11111100(左移的位数=n)

                  ~11111100=00000011

                 00000011<<5=01100000(左移的位数=p-n+1)

       结论:屏蔽码获取方式(~(~0<<n))<<p-n+1

       b).如何实现第二步?同样地,我们设计一个可以保持y移位之后,相应位不变而其余位置1的掩码:它的中间n位都是0,而其它位都是1,然后将掩码与y相或

       举例:设p=6,n=2,x和y都是8位,求掩码的推理过程如下

                   ~0=11111111

                  11111111<<2=11111100(左移的位数=n)

                   ~11111100=00000011

                   00000011<<5=01100000(左移的位数=p-n+1)

                  ~01100000=10011111

                 结论:屏蔽码获取方式~((~(~0<<n))<<p-n+1)

2)最终|的形式:将x中从第p位开始的n位全部清0,其余位不变,而对于y,先将其最右边的n位移到第p位,这些位不变,其余位清零;最后将二者相或

  同样地,根据最终选择相与还是相或,我们可以自己设置掩码。

       推理过程略。

        总结规律就是~0得到全为1的位,然后左移得到一定数目的0,然后在取反,移位以得到期望的掩码。


2. 编写一个函数invert(x,p,n),该函数返回对x执行下列操作后的结果值:将x中的第p位开始的n个二进制位求反(即,1变成0,0变成1),x的其余各位保持不变。

    利用性质:任何数与1异或等于其取反,任何数与0异或等于其本身。我们可以把中间的n位与1异或,剩下的位与0异或即可。掩码的求取方式仍遵循上述规律。


3.编写一个函数rightrot(x,p,n),该函数返回将x循环右移(即从最右端移出的位将从最左端移入)n(二进制)位后所得到的值。

   先截取x的低n位并保留,用作移位后的处理用。然后unsigned x右移n位,把截取的值左移到和x平行的高位处,将二者做异或处理。

   

  #include<stdio.h>

  int main()
  {
        int x=150;
	printf("%x\n",x);
	int n=3;
	int y=((~0<<n)^x)<<(sizeof(int)*8-n);
	x=x>>n;
	x^=y;
	printf("%x",x);
	return 0;	
  }


4.表达式x&=(x-1)可以删除x中最右边值为1(即从右往左数第一个为1 的位)的一个二进制位:x-1最右端为0的位在x中变为1,也就是说x中最右边为1的位与x-1在最左端为0的位在相同的位置上对应着,显然他们相与就会使x最右边值为1的位清零,而高于它们的位不受影响。

以下代码统计x中二进制1 的个数

   for(b=0;x!=0;x&(x-1))
         ++b;
   return b;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值