问题描述
编写一个函数 invert(x, p, n),该函数返回对 x 执行下列操作后的结果值:将 x 中从第 p 位开始的 n 个(二进制)位求反(即,1 变成 0,0 变成 1),x 的其余各位保持不变。
问题分解
- 主函数main
- 工具函数 setbits(x,p,n,y), 算法解析可以看上一篇文章
-
核心函数 invert(x, p ,n)。 这道题其实不难,只要联想一下2-6解决的问题,即可快速得到答案。我们来回顾一下2-6解决的问题:编写一个函数setbits(x, p ,n, y),该函数返回对x执行下列操作后的结果值: 将x中从第p位开始的n个(二进制)位设置为y中最右边n位的值,x的其余各位保持不变。 可以发现,我们只要拿到一个y,满足y的最右边的n位的值正是 x 中需要求反的位即可。因此算法描述可以为:
- 求得x的指定位求反并右移至尾部: (~x >> (p - n + 1)) & ~(~0 << n)
- 调用setbits 即可求得
代码实现
#include<stdio.h>
unsigned setbits(unsigned x, int p, int n, unsigned y);
unsigned invert(unsigned x, int p, int n);
int main()
{
unsigned x, r;
int p, n;
x = 21;
p = 4;
n = 3;
r = invert(x, p, n);
printf("The result is: %u \n", r);
return 0;
}
unsigned setbits(unsigned x, int p, int n, unsigned y)
{
return (x & (~(~(~0 << n) << (p - n + 1)))) | ((y & ~(~0 << n)) << (p - n + 1));
}
unsigned invert(unsigned x, int p, int n)
{
unsigned y;
y = (~x >> (p - n + 1)) & ~(~0 << n);
return setbits(x, p, n, y);
}