[英]Bitwise operations and masking in C
So I'm having trouble trying to isolate a certain amount of bits through masking.所以我在尝试通过屏蔽来隔离一定数量的位时遇到了麻烦。 Essentially I have a certain amount of bits I want to mask (let's call it offset) from a single byte (so 8 bits).
本质上我有一定数量的位我想从单个字节(所以 8 位)中屏蔽(我们称之为偏移量)。 There are 2 kinds of masks I need help with:
有 2 种口罩我需要帮助:
First one: say the offset = 4 and I have a byte with binary 1110 0001. I want to mask the last bits of size offset such that I can have a final byte of 1110 0000 (so mask the last 4 bits).第一个:假设偏移量 = 4,我有一个字节为二进制 1110 0001。我想屏蔽大小偏移量的最后一位,这样我就可以得到最后一个字节 1110 0000(因此屏蔽最后 4 位)。
Second one: say the offset is 3 and I have a byte with binary 1011 0010. I want to now mask the first few bits of size offset so that I have a final byte of 0001 0010.第二个:假设偏移量为 3,我有一个字节为二进制 1011 0010。我现在想屏蔽大小偏移量的前几位,以便我有一个 0001 0010 的最后一个字节。
I've pasted the code I have so far.我已经粘贴了到目前为止的代码。 Currently it does not work for the first mask I want to create as it masks the first few bits not the last.
目前它不适用于我要创建的第一个掩码,因为它掩码了前几位而不是最后一位。 I'm not sure if I'm creating the mask correctly.
我不确定我是否正确创建了面具。
uint8_t mask = (1 << offset) - 1;
byte = (byte & mask);
To mask off the low offset
bits, your computation for mask
is OK, but the expression is not.要屏蔽掉低
offset
位,您对mask
的计算是可以的,但表达式不是。 It should be:它应该是:
byte = (byte & ~mask);
or simply:或者简单地:
byte &= ~mask;
To compute a mask from an offset with (1 << offset) - 1
, you should beware that offset must be less than the number of bits in the type of 1
.要使用
(1 << offset) - 1
从偏移量计算掩码,您应该注意 offset 必须小于1
类型中的位数。 1
being an int
, if means offset < 32
, so you cannot compute the mask for a 32-bit field this way. 1
是一个int
, if 意味着offset < 32
,所以你不能用这种方式计算 32 位字段的掩码。
Furthermore, even 31
poses a problem because (1 << 31)
exceeds the range of type int
.此外,即使是
31
也会带来问题,因为(1 << 31)
超出了int
类型的范围。 To avoid this, you should write (1U << offset) - 1
and you must first test if offset < 32
.为避免这种情况,您应该编写
(1U << offset) - 1
并且您必须首先测试offset < 32
。
A better alternative that works for offset
values from 1
to 32
is this:适用于从
1
到32
的offset
值的更好替代方法是:
unsigned mask = ~0U >> (sizeof(unsigned) * CHAR_BIT - offset);
bits &= ~mask;
or simpler with an opposite mask:或者使用相反的掩码更简单:
bits &= ~0U << offset;
Here are macros to get, clear and set a bitfield in an unsigned int
:以下是用于获取、清除和设置
unsigned int
中的位域的宏:
#define GET_MASK(width) (~0U >> (sizeof(unsigned) * CHAR_BIT - (width)))
#define GET_FIELD(x, pos, width) (((x) >> (pos)) & GET_MASK(x, width))
#define CLEAR_FIELD(x, pos, width) (((x) &= ~(GET_MASK(x, width) << (pos)))
#define SET_FIELD(x, pos, width, val) ((x) = ((x) & ~(GET_MASK(x, width) << (pos))) | ((val) << (pos)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.