课中的例子:
unsigned getbits(unsigned x, int p, int n) {
return (x >> (p + 1 - n)) & ~(~0 << n);
//~0 1111 1111 <<3 1111 1000 ~(~0<<3) 0000 0111
//4+1-3 =2 x>>2 移到最右侧,再与0000 0111 保留右三位
}
练习 2-6
将 x 中从第 p 位开始的 n 个(二进制)位设置为 y 中最右边 n 位的值,x 的其余各位保持不变。
unsigned setbits(unsigned x, int p, int n, unsigned y) {
return (getbits(y, n - 1, n) << (p + 1 - n)) |
(x & ~((~(~0 << n)) << (p + 1 - n)));
}
/* ~(~0 << 3) 得 0000 0111
(~(~0 << n)) << (4 + 1 - 3) 得 0001 1100
~((~(~0 << n)) << (p + 1 - n)) 得 1110 0011
(x & ~((~(~0 << n)) << (p + 1 - n))) &有0出0 全1出1
***000** 所要的那几位变成0,其它位保持不变
getbits(y, n - 1, n)得最右边的n位。<< (p + 1 - n) 左移,让
|或两边保持对应的位 00010100 左右两边都补0
| 有1出1 全0出0
如y=5 n=3 0001 0100 | 1110 0011 得 1111 0111
*/
练习 2-7
将 x 中从第 p 位开始的 n 个(二进制)位求反(即,1 变成 0,0 变成 1),x 的其余各位保持不变。
unsigned invert(unsigned x, int p, int n) {
return (getbits(~x, p, n) << (p + 1 - n)) |
(x & ~((~(~0 << n)) << (p + 1 - n)));
}
练习 2-8
该函数返回将 x 循环右移(即从最右端移出的位将从最左端移入)n(二进制)位后所得到的值。
#define WEI 8 //限定 8位二进制
unsigned rightrot(unsigned x, int n) {
return (x >> n) | (getbits(x, n - 1, n) << (WEI - n));
}
测试
int main() {
unsigned x = 255;
unsigned y = 5;
printf("\tx=%d ,y=%d \n", x, y);
printf(" setbits(x, 4, 3, y)\t=%d\n", setbits(x, 4, 3, y));
printf("\tinvert(x, 4, 3)\t=%d\n", invert(x, 4, 3));
printf("\trightrot(x, 3)\t=%d\n", rightrot(x, 3));
printf("\trightrot(45, 3)\t=%d\n", rightrot(45, 3));
return 0;
}
255 1111 1111
5 0000 0101
247 1111 0111
227 1110 0011
45 0010 1101
165 1010 0101
山就在那,爬就是了……