练习 2-6
编写一个函数 setbits(x, p, n, y),该函数返回对 x 执行下列操作后
的结果值:将 x 中从第 p 位开始的 n 个(二进制)位设置为 y 中最右边 n 位的值,x 的其余
各位保持不变。
主要的算法其实就两句话:
int setbits(x, p, n, y)
{
int a;
a = ~(~(~0 << n) << (p - 1));
y = (y & ~(~0 << n)) << (p - 1);
return x & a | y;
}
多注释完整版
#include <stdio.h>
int setbits(x, p, n, y);
main()
{
int x, y, z;
x = 123; // 0000-0111-1011
y = 456; // 0001-1100-1000
z = setbits(x, 2, 5, y);//0000-0101-0001
printf("%d\n", z);
}
/*
把x
从p开始n位清掉,
然后用y的后n位补上
*/
int setbits(x, p, n, y)
{
int a;
/*
a : 清除用过滤器
a = p(2)开始清掉n(5)位
a = ~(~(~0 << n) << (p - 1))
a = ~(~(1111-1111-1111-1111 << 5) << (2 - 1))
a = ~(~(1111-1111-1110-0000) << 1)
a = ~(0000-0000-0001-1111 << 1)
a = ~(0000-0000-0011-1110)
a = 1111-1111-1100-0001
*/
a = ~(~(~0 << n) << (p - 1));
/*
y : 补上的数据
y = 取y右边的(n)位,移动到要补的位置上
y = (y & ~(1111-1111-1111-1111 << 5)) << (2 - 1);
y = (y & ~(1111-1111-1110-0000)) << 1;
y = (y & 0000-0000-0001-1111) << 1;
y = (0000-0001-1100-1000 & 0000-0000-0001-1111) << 1;
y = 0000-0000-0000-1000 << 1;
y = 0000-0000-0001-0000
*/
y = (y & ~(~0 << n)) << (p - 1);
/*
先清后补
x & a | y
= 0000-0000-0111-1011 & 1111-1111-1100-0001 | 0000-0000-0001-0000
0000-0000-0111-1011
& 1111-1111-1100-0001
| 0000-0000-0001-0000
-----------------------------------------------------------------------
清完开始补
x & a | y
= 0000-0000-0100-0001 | 0000-0000-0001-0000
0000-0000-0100-0001
| 0000-0000-0001-0000
-----------------------------------------------------------------------
结果
x & a | y
= 0000-0000-0101-0001
*/
return x & a | y;
}
注释写的我好恶心啊…(`Д´)