几个典型的按位运算符示例


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

<span style="font-size:18px;">#include <stdio.h>
#include <stdlib.h>
#include "limits.h"
#include "float.h"

unsigned setbits(int x,int p,int n,int y)
{
    return x&~(~(~0<<n)<<(p + 1 - n))| (y & ~(~0 <<n )) << (p + 1 - n);
}
int main()
{
    printf("%u\n",setbits(5,4,3,6));
    int end = getchar();
    return 0;
}</span>


分析:
x的值:xxx...xnnnx...xxx     (n表示需要被替换的n位)
y的值:yy..............ynnn    
题目需要用y中的n位值替换x中的n位值。要实现该功能,需要以下几步:
我们需要对x中n位清零,把y中最右边n位其他以为的位都清零并左移到第p位处,然后进行or操作。
xxx....x000x...xxx |(or操作)
000...  nnn....000     
--------------------------
xxx....xnnnx...xxx  (操作完成,得到想要的值)


步骤分解:
1.对x中n位清零,得到【xxx....x000x...xxx】


a.得到 【111...000...111】这样的结果。一般都用0作为辅助来得到想要的结果。
~0<<n:得到【111......000】
~(~0<<n):得到【000......111】
~(~0<<n)<<(p + 1 - n):得到【000...111...000】
~(~(~0<<n)<<(p + 1 - n)):得到【111...000...111】


b.得到【xxx....x000x...xxx】结果。
上一步步骤a中的结果与【x的值:xxx...xnnnx...xxx】&与运算,得到
xxx...xnnnx...xxx
111....000....111 &
-----------------
xxx...x000x...xxx
总运算:
x &~(~(~0<< n) << (p + 1 -n))


2.对y处理,得到【000...  nnn....000】
~0<<n:得到【111......000】
~(~0<<n):得到【000......0111】
与y相与&,得到【000......0nnn】
移位运算<<(p + 1 - n)),得到:【000...  nnn....000】
总运算:
(y & ~(~0 <<n )) << (p + 1 - n)


3.合并步骤1,2,用与运算:

x &~(~(~0<< n) << (p + 1 -n)) | (y & ~(~0 <<n )) << (p + 1 - n)


二、编写函数invert(x,p,n),将函数返回对x执行下列操作后的结果值: 将x中从第p位开始的n个(二进制)位


求反(即1变成0, 0变成1), x的其余各位保持不变.
分析:
(~0<<n) : 1111 1000
~(~0<<n):0000 0111
~(~0<<n)<<(p + 1 - n):000...111...000
异或:
0^0 = 0, 
1^0 = 1, 
0^1 = 1, 
1^1 = 0
所以用【000...111...000】去和x异或,可得到想要的值。


<span style="font-size:18px;">unsigned int invert(int x,int p,int n)
{
    return x ^ (~(~0<<n)<<(p + 1 - n));
}
</span>



三、编写一个函数rightrot(x, n),该函数返回将x循环右移(即从最右端移出的位将从最左端再移入)n(二进制)位后所得到的值。
分析:
a.每次将取x最右端的那一位,将该位移到最左端
b.将x向右端移动一位
c.将a得到的值|b得到的值


<span style="font-size:18px;">int wordlength(void)
{
 int i;
 unsigned v = (unsigned) ~0;


 for(i = 1; (v = v >> 1) > 0; ++i)
  ;
 return i;
}
unsigned int rightrot(int x,int n)
{
    int ret;
    while(n-- > 0)
    {
        int rBit = (x & 1) << wordlength() - 1;
        ret = x>>1 | rBit;
    }
    return ret;
}</span>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值