返回x,其中n位从位置p开始,设置为y的最右边n位,其他位保持不变
我的解决方案
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))
这是一个相当长的陈述。 我们有更好的吗?
ie 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
我写了类似的一篇:
unsigned setbits (unsigned x, int p, int n, unsigned y) { return (x & ~(~(~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很快就能做到这一点;你的应用程序的性能不太可能受到这种function的限制。至少它是“无罪的,直到被certificate有罪”。)
看看下面的描述性代码:
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
s的字符串),将它们移动到x
中间位置,通过使用0
s(反转位掩码)字符串来核对x
那些位,最后|
是y
的正确位置的那个位置。