我的解决方案
get the rightmost n bits of y
a = ~(~0 << n) & y
clean the n bits of x beginning from p
c = ( ~0 << p | ~(~0 << (p-n+1))) & x
set the cleaned n bits to the n rightmost bits of y
c | (a << (p-n+1))
这是一个相当长的陈述。我们有更好的吗?
i.e
x = 0 1 1 1 0 1 1 0 1 1 1 0
p = 4
y = 0 1 0 1 1 0 1 0 1 0
n = 3
the 3 rightmost bits of y is 0 1 0
it will replace x from bits 4 to bits 2 which is 1 1 1
答案 0 :(得分:1)
我写了类似的一篇:
unsigned setbits (unsigned x, int p, int n, unsigned y)
{
return (x & ~(~(~0<<n)<<(p+1-n)))|((y & ~(~0<<n))<<(p+1-n));
}
答案 1 :(得分:0)
有两种合理的方法。
一个是你的:抓取y
的低n位,核对x的中间n
位,然后“或”将它们放到位。
另一个是从三个部分构建答案:低位“或”中间位“或”高位。
我认为我真的更喜欢你的版本,因为我打赌n
和p
更可能是编译时常量而不是x
和y
。所以你的答案变成了两个使用常数和一个“或”的掩蔽操作;我怀疑你会做得更好。
我可能会略微修改它以便于阅读:
mask = (~0 << p | ~(~0 << (p-n+1)))
result = (mask & a) | (~mask & (y << (p-n+1)))
...但是当mask
是常量时,这与你的速度(实际上是代码)相同,而当mask
是变量时,速度可能会慢一些。
最后,请确保您有充分的理由担心这一点。干净的代码是好的,但对于这么短的东西,把它放在一个记录良好的函数中,并没有那么重要。快速代码很好,但在您的分析器告诉您之前,不要尝试微观优化这样的东西。 (现代CPU可以非常快速地完成这些工作;应用程序的性能不太可能受到这种功能的限制。至少在被证明有罪之前它是“无辜的”。)
答案 2 :(得分:0)
看看下面的描述性代码:
int setbitsKR(int x, int p, int n, int y){
int shiftingDistance = p - n + 1,
bitmask = (1 << n) - 1, // example, 11
digitsOfY = (y & bitmask) << shiftingDistance, // whatever
bitmaskShiftedToLeft = bitmask << shiftingDistance, // 001100
invertedBitmaskShiftedToLeft = ~bitmaskShiftedToLeft; // 110011
// erase those middle bits of x
x &= invertedBitmaskShiftedToLeft;
// add those bits from y into x
x |= digitsOfY;
return x;
}
简而言之,它将创建一个位掩码(1
的字符串),将其移位到x
的中间位置,将x
的那些位加{{1} } &
(反向位掩码)的字符串,最后0
的位置是|
的正确数字。