C程序设计语言 (第二版) 练习2-7
练习 2-7 编写一个函数 invert(x, p, n),该函数返回对x 执行下列操作后的结果值:将x中从第p位开始的n个(二进制)位求反(即,1 变成0,0 变成1),x的其余各位保持不变。
注意:代码在win32控制台运行,在不同的IDE环境下,有部分可能需要变更。
IDE工具:Visual Studio 2010
代码块:
int invert(int x, int p, int n){
return (x ^ (x >> (p-n+1) << (p-n+1))) ^ (((~(x >> (p-n+1))) & (~(~0 << n))) << (p-n+1));
}
示例:
#include <stdio.h>
#include <stdlib.h>
int invert(int x, int p, int n){
return (x ^ (x >> (p-n+1) << (p-n+1))) ^ (((~(x >> (p-n+1))) & (~(~0 << n))) << (p-n+1));
}
int main(){
int x = 23;
printf("%d\n", invert(x, 4, 2));
system("pause");
return 0;
}
运行结果显示如下:
说明:
- 23的二进制表示为10111,p为4,n为2,也就是需要从第4位开始的2位替换,二进制最右边是第0位,那第4位就是1,第3位就是0,需要取反的是这两位。
- 先对23(10111)右移p-n+1位,即3位,变为10,再左移p-n+1位(3位),变为10000,与原先的23(10111)进行异或,即10000 ^ 10111 = 00111。
- 根据第1步取反的值,先对23(10111)右移p-n+1位,即3位,变为10,取反得01,然后进行屏蔽,即01 & ~(~0 << n) = 01 & 011 = 001,接着左移p-n+1位,得01000。
- 之前第2步的结果与第3步的结果进行异或,即00111 ^ 01000 = 01111(十进制15)。