繁体   English   中英

C中的按位运算和掩码

[英]Bitwise operations and masking in C

所以我在尝试通过屏蔽来隔离一定数量的位时遇到了麻烦。 本质上我有一定数量的位我想从单个字节(所以 8 位)中屏蔽(我们称之为偏移量)。 有 2 种口罩我需要帮助:

第一个:假设偏移量 = 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 , if 意味着offset < 32 ,所以你不能用这种方式计算 32 位字段的掩码。

此外,即使是31也会带来问题,因为(1 << 31)超出了int类型的范围。 为避免这种情况,您应该编写(1U << offset) - 1并且您必须首先测试offset < 32

适用于从132offset值的更好替代方法是:

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)))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM