0%

2-6:setbits(x,p,n,y)

文章时效性提示

本文发布于 469 天前,部分信息可能已经改变,请注意甄别。

题目

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

分析

例如:setbits(200,5,2,195)
200的二进制数是:1100 1000
这个二进制数的的第p位,开始的第n个二进制位。也就是第5位开始数2位(从右往左数)。
即:1100 1000,加粗的10就是要替换的。
替换为195的二进制数最右边2位的值:1100 0011
也就是将00替换为11,即替换后的x为1111 1000,即十进制的248。

位操作符(按位与、按位或、按位异或)
移位操作符(左移、右移)

代码

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
unsigned setbits(unsigned int x,int p,int n,unsigned int y);
int main()
{
    printf("%d",setbits(200, 5, 2, 195));
    return 0;
}
unsigned int setbits(unsigned int x,int p,int n,unsigned int y)
{
    return x & ~(~(~0 << n) << (p+1-n)) | (y & ~(~0 << n)) << (p+1-n);
}

(~0 << n) 先把0按位取反,变成二进制位全都是1的二进制数,即1111 1111,再向右移n位(2位),变成1111 1100。

~(~0 << n) 把上面获得的1111 1100 再次按位取反,得到0000 0011。

~(~0 << n) << (p+1-n) 把0000 0011右移p+1-n位,即4位,得到0011 0000。

~(~(~0 << n) << (p+1-n)) 再次按位取反,得到 1100 1111。

x & ~(~(~0 << n) << (p+1-n))x与得到的二进制数进行按位与操作,有0则0,全1为1。得到
1100 1000。

(y & ~(~0 << n)) y与0000 0011进行按位与操作,得到0000 0011。

(y & ~(~0 << n)) << (p+1-n) 把0000 0011右移4位,得到0011 0000。

x & ~(~(~0 << n) << (p+1-n)) | (y & ~(~0 << n)) << (p+1-n)0011 0000和1100 1000进行按位与操作,得到1111 1000,十进制就是248。