更改字节中的特定位集 [英] Changing specific set of bits in a byte

查看:132
本文介绍了更改字节中的特定位集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个接收字节并需要更改该字节中某些位的函数.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆