我正在处理一个接收字节并需要更改该字节中某些位的函数。
例如,函数接收:
11001011
然后我需要将MSB设置为0,这很容易:
buffer[0] &= ~(1 << 7);
但是我需要将位 6到3 (我在这里将LSB称为位0)设置为提供给函数的参数。此参数可以是0到6之间的整数 。
重要的是我不应该改变任何其他位。
我尝试了掩盖和东西,但我失败了。然后作为最后的手段,我在下面痛苦地做了。它工作得很好......但它很难看并产生大量指令,使代码运行缓慢:
switch(regAddress) {
case 0:
buffer[0] &= ~(1 << 5);
buffer[0] &= ~(1 << 4);
buffer[0] &= ~(1 << 3);
break;
case 1:
buffer[0] &= ~(1 << 5);
buffer[0] &= ~(1 << 4);
buffer[0] |= (1 << 3);
break;
//YOU GOT THE IDEA!!.....
}
请用一行(或两行)代码让我知道这个问题,这样我就可以了解这个技巧。
我犯了一个错误,传递的参数总是0到6,所以我想要设置的4位的MSB总是为零,因此在切换情况之前我确实喜欢:
//because we only have 7 address, we already set the 4th bit to 0
buffer[0] &= ~(1 << 6);
答案 0 :(得分:4)
如果你有一个位字段,比如第6位到第3位(总共四位),打包成值w
(某种类型的无符号整数),那么你可以设置一个值{{1 with:
v
这假设w = (w & ~0x78) | (v << 3);
在要求的范围内。如果没有,您可以使用v
代替(v & 0xf)
。屏蔽操作v
清除位6到3,移位操作将w & ~0x78
移动到正确的位置,按位或操作将它们组合在一起。
要从v
中提取字段,您可以使用:
w
移位操作右对齐字段,掩码操作清除字段外的位。这相当于:
(w >> 3) & 0xf
此版本在移位前屏蔽该字段(因此它使用较大的掩码值)。
确保(w & 0x78) >> 3
具有无符号类型,以便移位无符号。
注意:此示例适用于占用位6,5,4,3的4位字段。w
掩码为0x78
,即((1 << 4) - 1) << 3
。 0xf << 3
掩码为0xf
。移位量(1 << 4) - 1
是字段右边的位数,即位2,1和0。
答案 1 :(得分:-2)
为什么不循环遍历这组位?
def setBits(i, bits):
for bit in bits:
i |= 1 << bit
return i
print(bin(setBits(0b11001011, [3, 4, 5, 6])))