我正在尝试执行以下操作:
编写一个函数
setbits(x,p.n,y)
,返回x
,其中n
位开头 位置p
设置为n
的最右侧y
位,而保留其他位 不变?
我试过这样但没有得到正确的答案。谁能告诉我哪里错了?
unsigned setbits(unsigned x,int p,int n,unsigned y)
{
return (x>>p & (y|(~0<<n)));
}
答案 0 :(得分:3)
类似的东西:
unsigned setbits(unsigned x,int p,int n,unsigned y)
{
unsigned mask = (1U << n) - 1U; // n-bits
y &= mask; // rightmost n bits of y
y <<= p; // which begin at position p
mask <<= p; //idem
x &= ~mask; //set the 0s
x |= y; //set the 1s
return x;
}
或者如果你想用更少的线来做,更难调试,但是更酷:
unsigned setbits(unsigned x,int p,int n,unsigned y)
{
unsigned mask = (1U << n) - 1U; // n-bits
return (x & ~(mask << p)) | ((y & mask) << p);
}
答案 1 :(得分:1)
Kernighan和Ritchie,第2版,练习2-6。解决方案来自http://users.powernet.co.uk/eton/kandr2/krx206.html:
(x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n))))) | ((y & ~(~0 << n)) << (p + 1 - n))
答案 2 :(得分:1)
捕获y的最后n位:(将是最后n位等于y的数字,其他位设置为0)
last_n_bits_of_y = y & (((1<<(n+1))-1);
然后我们可以将它抵消(32-n-p + 1)(检查一下!)
last_n_bits_of_y_offset = last_n_bits_of_y << (32-n-p+1);
现在我们删除我们要更改的x位:
new_x = x & (~( (((1<<(n+1))-1) << (32-n-p+1) ) );
并用我们的位填充它:
new_x = new_x & last_n_bits_of_y_offset;
就是这样!没有真正测试它,但希望你能得到这个想法。
答案 3 :(得分:1)
x>>()
所以你松开了x
最右边的位,然后再也不会在你的函数中恢复它们。 &
设置位,因为结果取决于两个操作数,除非您知道其中一个只包含1
(y|(~0<<n))
应该从y
剪切位,但不是,这次|
不是正确的工具,使用&
和适当的第二个操作数。这是解决方案(我打赌有一个较短的解决方案,但这很简单):
(x & ~(~(~0<<n)<<p) | (y&~(~0<<n)) << p);
|
的左侧部分清除x
中的位置(位置p处的n位),右侧部分带来y
位。