C学习——位移

1.将x执行以下操作

第p位开始的n(二进制)个位,设置为y中最右边的n位,x的其余位不变

x: xxxm mxxx
y: yyyy yynn

思路:将x中的m变为0,将y中的y变为0,再左移至相应位置,然后再 与 。
x: xxx0 0xxx
y: 0000 00nn

x: xxx0 0xxx
y: 000n n000
x: xxxn nxxx

unsigned setbits(unsigned x, int p, int n, unsigned y){
    return x & ~(~(~0 << n) << (p+1-n)) | (y & ~(~0 << n)) << (p+1-n);
}
~0 << n//把全1的屏蔽码左移n位,右边出现n个0
~(~0 << n)//取反,右边出现n个1,其余位为0
~(~0 << n) << (p+1-n)//把屏蔽码右边的n个1左移至对应位置
~(~(~0 << n) << (p+1-n))//再取反
x & ~(~(~0 << n) << (p+1-n))//用屏蔽码和x进行与操作

~(~0 << n)//右边n位为1,其余为0
y & ~(~0 << n)//与y相与,将y的无关位置0
y & ~(~0 << n) << (p+1-n)//把y左移至对应位置

x & ~(~(~0 << n) << (p+1-n)) | y & ~(~0 << n) << (p+1-n)//或,得到结果

设p=4,n=2
x屏蔽码:
1111 1111
1111 1100
0000 0011
0001 1000
1110 0111
x:
xxxm mxxx
xxx0 0xxx
y屏蔽码:
1111 1111
1111 1100
0000 0011
y:
yyyy yynn
0000 00nn
000n n000
最终x: xxxn nxxx

2.将x执行以下操作

第p位开始的n(二进制)个位,取反,x的其余位不变

x: xxxn nxxx
xxx~n ~nxxx
思路:还是用屏蔽码与x进行异或(^)

unsigned invert(unsigned x, int p, int n){
    return x ^ (~(~0 << n) << (p+1-n));
}

可以借鉴上面的思路分析

~0 << n//把全1的屏蔽码左移n位,右边出现n个0
~(~0 << n)//取反,右边出现n个1,其余位为0
~(~0 << n) << (p+1-n)//把屏蔽码右边的n个1左移至对应位置
x ^ (~(~0 << n) << (p+1-n))//用屏蔽码和x进行异或操作

3.将x执行以下操作

将x循环右移n位(最右边移出的值将从最左端移入)
此处为真循环

//将x循环右移n位(最右边移出的值将从最左端移入)
unsigned rightrot(unsigned x, int n){
    int wordlength(void);
    int rbit;

    while(n-- >0){
        rbit = (x & 1) << (wordlength() - 1);
        x = x >> 1;
        x = x | rbit;
    }
    return x;
}
//计算运行程序的计算机所使用的的字长
int wordlength(void){
    int i;
    unsigned v = (unsigned) ~0;

    for(i = 1;(v = v >> 1) > 0;i++)
        ;
    return i;
}

用rebit将x最右端移到最左端位置(wordlength() - 1),然后将x右移一位,再与rebit进行或操作。即完成一次右移,如此循环n次。
假循环,就是将右端n位全部移到左端。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值