c - C 中的位运算和掩码

标签 c bit-manipulation byte bit

所以我在尝试通过屏蔽隔离一定数量的位时遇到了麻烦。本质上,我想从单个字节(即 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 类型中的位数。 1int ,如果意味着offset < 32 ,因此您无法通过这种方式计算 32 位字段的掩码。

此外,甚至31提出了一个问题,因为 (1 << 31)超出类型 int 的范围。为了避免这种情况,您应该写 (1U << offset) - 1并且您必须首先测试是否 offset < 32 .

适用于 offset 的更好替代方案值来自132是这样的:

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/

相关文章:

c - 如何将 putchar 的输出保存到变量中

c - 将 char * 重新解释为用于只读操作的另一种原始类型的数组的任何合法方法?

C - 解码 base64 时的位移位

MySQL位反转,如何只取反前x位?

c - 如果堆内存满了会发生什么?

c - 为什么我数为 0 个单词?

c - 位操作 :print the next smallest and largest numbers with same no of 1 bits

c++ - 在具有字节序兼容性的 C++ 中将 2 字节整数转换并分解为 2 个不同的字符

c - 在 C 中读取 "pure"字节

c# - 如何将 int 转换为字节数组然后再转换回来?