什么是位屏蔽?

时间:2012-05-08 06:07:29

标签: c bit-manipulation bitwise-operators terminology bitmask

我对C编程很新,我遇到了掩码。有人可以向我解释位屏蔽的一般概念和功能吗?非常感谢例子。

2 个答案:

答案 0 :(得分:178)

掩码定义了要保留的位以及要清除的位。

遮罩是将遮罩应用于值的行为。这可以通过以下方式完成:

  • 按位AND运算以提取值
  • 中的位子集
  • 按位ORing以设置值
  • 中的位的子集
  • 按位异或,以切换值
  • 中的位的子集

以下是提取值中的位子集的示例:

Mask:   00001111b
Value:  01010101b

将掩码应用于值意味着我们要清除第一个(更高)4位,并保留最后(较低)4位。因此我们提取了低4位。结果是:

Mask:   00001111b
Value:  01010101b
Result: 00000101b

使用AND实现掩蔽,因此在C中我们得到:

uint8_t stuff(...) {
  uint8_t mask = 0x0f;   // 00001111b
  uint8_t value = 0x55;  // 01010101b
  return mask & value;
}

这是一个相当常见的用例:从较大的单词中提取单个字节。我们将字中的高位定义为第一个字节。我们使用两个运算符&>>(右移)。这就是我们如何从32位整数中提取四个字节:

void more_stuff(uint32_t value) {             // Example value: 0x01020304
    uint32_t byte1 = (value >> 24);           // 0x01020304 >> 24 is 0x01 so
                                              // no masking is necessary
    uint32_t byte2 = (value >> 16) & 0xff;    // 0x01020304 >> 16 is 0x0102 so
                                              // we must mask to get 0x02
    uint32_t byte3 = (value >> 8)  & 0xff;    // 0x01020304 >> 8 is 0x010203 so
                                              // we must mask to get 0x03
    uint32_t byte4 = value & 0xff;            // here we only mask, no shifting
                                              // is necessary
    ...
}

请注意,您可以切换上面运算符的顺序,您可以先执行掩码,然后再进行移位。结果是一样的,但现在你必须使用不同的掩码:

uint32_t byte3 = (value & 0xff00) >> 8;

答案 1 :(得分:18)

屏蔽是指保留/更改/删除所需的信息部分。让我们看一下图像遮罩操作;喜欢-此遮罩操作将删除所有非皮肤的东西-

enter image description here

在此示例中,我们正在执行 AND 操作。还有其他屏蔽运算符- OR XOR


位掩码是指在位上加上掩码。这是 AND -

的位掩码
     1 1 1 0 1 1 0 1   [input]
(&)  0 0 1 1 1 1 0 0    [mask]
------------------------------
     0 0 1 0 1 1 0 0  [output]

因此,仅剩下中间的4位(因为这些位在此掩码中为1)。

让我们用 XOR -

看到
     1 1 1 0 1 1 0 1   [input]
(^)  0 0 1 1 1 1 0 0    [mask]
------------------------------
     1 1 0 1 0 0 0 1  [output]

现在,中间4位被翻转(1变成了00变成了1)。


因此,使用位掩码,我们可以访问各个位[examples]。有时,此技术也可以用于提高性能。以这个为例-

bool isOdd(int i) {
    return i%2;
}

此函数告诉整数是否为奇/偶。使用bit-mask-

可以更高效地达到相同的结果
bool isOdd(int i) {
    return i&1;
}

简短说明:如果二进制数的least significant bit1,则为奇数; 0会是偶数。因此,通过对1进行 AND ,我们将除去最低有效位(即:

)之外的所有其他位
     55  ->  0 0 1 1 0 1 1 1   [input]
(&)   1  ->  0 0 0 0 0 0 0 1    [mask]
---------------------------------------
      1  <-  0 0 0 0 0 0 0 1  [output]