更改字节中的特定位集 [英] Changing specific set of bits in a byte
问题描述
我正在研究一个接收字节并需要更改该字节中某些位的函数.
I am working on a function that receives a byte and needs to change some of the bits in that byte.
例如,该函数接收:
11001011
然后我需要将MSB设置为0,这很容易:
Then I need to set the MSB to 0, its easy enough:
buffer[0] &= ~(1 << 7);
但是然后我需要将位 6到3 (这里我将LSB称为位0)设置为提供给函数的参数.此参数可以是从0到6 的整数.
But then I need to set bits 6 through 3 (I refer LSB as bit 0 here) to an argument that gets supplied to the function. This argument can be an integer from 0 to 6.
重要的是我不应该更改任何其他位.
我尝试了遮罩和填充物,但失败了.然后作为最后的手段,我像下面这样痛苦地做着.它可以正常工作...但是它很丑陋,并且会生成大量指令,从而使代码运行缓慢:
I tried with masking and stuff but I failed miserably. Then as last resort I did it painfully like below. It works fine...but it is ugly and generates tons of instructions, making the code run slow:
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!!.....
}
请让我知道很热,只需一行(或两行)代码即可完成操作,这样我就可以了解窍门.
Please let me know hot to do this in one (or two) line of code so I can learn the trick.
我做错了,传递的参数始终为0到6,所以我要设置的4位的MSB始终为零,因此在进行切换之前,我喜欢:
I did a mistake, the argument passed is alway 0 to 6, so the MSB of the 4bits that I want to set is always zero, therefore before the switch case I did like:
//because we only have 7 address, we already set the 4th bit to 0
buffer[0] &= ~(1 << 6);
推荐答案
如果您有位字段,则说位6至3(总共4位),打包成值w
(某种类型的无符号整数),那么您可以使用以下值将字段设置为v
:
If you have a bit field, say bits 6 though 3 (four bits total), packed into a value w
(some type of unsigned integer), then you can set the field with a value v
with:
w = (w & ~0x78) | (v << 3);
这假定v
在所需范围内.如果不是,则可以使用(v & 0xf)
代替v
.掩码操作w & ~0x78
清除第6位至第3位,移位操作将v
移动到适当位置,然后按位或运算将它们组合在一起.
This assumes that v
is within the required range. If not, you can use (v & 0xf)
in place of v
. The mask operation w & ~0x78
clears bits 6 through 3, the shift operation moves v
into the proper position, and the bitwise-or operation combines them.
要从w
中提取字段,可以使用:
To extract the field from w
, you can use:
(w >> 3) & 0xf
shift操作使该字段右对齐,而mask操作清除该字段之外的位.这等效于:
The shift operation right-justifies the field, and the mask operation clears the bits outside of the field. This is equivalent to:
(w & 0x78) >> 3
此版本在移位之前会屏蔽该字段(因此它使用较大的掩码值).
This version masks the field before shifting (so it uses a larger mask value).
确保w
具有无符号类型,以使移位无符号.
Make sure w
has an unsigned type so that the shifts are unsigned.
注意:此示例用于占用位6、5、4、3的4位字段.0x78
掩码为((1 << 4) - 1) << 3
,即0xf << 3
. 0xf
掩码是(1 << 4) - 1
.移位量3
是该字段右侧的位数,即第2、1、0位.
Note: This example is for the 4-bit field occupying bits 6, 5, 4, 3. The 0x78
mask is ((1 << 4) - 1) << 3
, i.e. 0xf << 3
. The 0xf
mask is (1 << 4) - 1
. And the shift amount, 3
, is the number of bits to the right of the field, i.e. bits 2, 1, and 0.
这篇关于更改字节中的特定位集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!