C语言中的位运算和掩码

问题描述 投票:0回答:1

因此,我在试图通过掩码隔离一定数量的比特时遇到了麻烦。本质上,我有一定数量的比特,我想屏蔽(让我们称之为偏移)从一个单一的字节(所以8位)。有2种掩码我需要帮助。

第一种: 假设偏移量为4,我有一个二进制1110 0001的字节。我想掩码 最后的 位的大小偏移,这样我就可以有一个1110 0000的最终字节(所以掩盖最后4位)。

第二种:比如偏移量是3,我有一个二进制为1011 0010的字节。我现在要屏蔽 第一 几位的大小偏移,所以我有一个0001 0010的最后一个字节。

我已经把我目前的代码粘贴上去了。目前,我想创建的第一个掩码不工作,因为它掩码的是前几位而不是最后一位。我不知道我是否正确创建了掩码。

uint8_t mask = (1 << offset) - 1;
byte = (byte & mask);
c bit-manipulation byte bit
1个回答
1
投票

要屏蔽掉低位的 offset 位,你的计算方式为 mask 是可以的,但表达方式却不可以。应该是。

byte = (byte & ~mask);

或简单的。

byte &= ~mask;

要从偏移量中计算出一个掩码 (1 << offset) - 1你应该注意,偏移量必须小于类型中的位数。1. 1 作为 int,如果是指 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)))
© www.soinside.com 2019 - 2024. All rights reserved.