所以我在尝试通过屏蔽隔离一定数量的位时遇到了麻烦。本质上,我想从单个字节(即 8 位)中屏蔽一定数量的位(我们称之为偏移量)。我需要帮助使用两种 mask :
第一个:假设偏移量= 4,我有一个二进制为1110 0001的字节。我想屏蔽大小偏移量的最后位,这样我就可以得到最后一个字节1110 0000(所以屏蔽最后 4 位)。
第二个:假设偏移量为 3,我有一个二进制为 1011 0010 的字节。我现在想屏蔽大小偏移量的前几位,以便最终字节为 0001 0010 .
我已经粘贴了到目前为止的代码。目前它不适用于我想要创建的第一个掩码,因为它掩码了前几位而不是最后一位。我不确定我是否正确创建了蒙版。
uint8_t mask = (1 << offset) - 1;
byte = (byte & mask);
最佳答案
掩盖低点offset
位,您对 mask
的计算可以,但表达不行。应该是:
byte = (byte & ~mask);
或者简单地说:
byte &= ~mask;
根据 (1 << offset) - 1
的偏移量计算掩码,您应该注意 offset 必须小于 1
类型中的位数。 1
是 int
,如果意味着offset < 32
,因此您无法通过这种方式计算 32 位字段的掩码。
此外,甚至31
提出了一个问题,因为 (1 << 31)
超出类型 int
的范围。为了避免这种情况,您应该写 (1U << offset) - 1
并且您必须首先测试是否 offset < 32
.
适用于 offset
的更好替代方案值来自1
至32
是这样的:
unsigned mask = ~0U >> (sizeof(unsigned) * CHAR_BIT - offset);
bits &= ~mask;
或者使用相反的掩码更简单:
bits &= ~0U << offset;
以下是用于获取、清除和设置 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)))
关于c - C 中的位运算和掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62035498/