22

我正在尝试使用掩码并操作字节中的特定位。例如:

我想用 C 编写一个程序,在特定位置翻转两位,例如位置 0 的位和第三位的位。所以,11100011,会变成01110011

我怎样才能交换这些位?

4

4 回答 4

34

翻转位是通过使用掩码进行异或运算来完成的:在要翻转的位置设置位,然后执行异或,如下所示:

int mask = 0x90; // 10010000
int num  = 0xE3; // 11100011
num ^= mask;     // 01110011

以下是一些注意事项:

  1. 位通常从最低有效位置开始计算,因此您的示例翻转位置 4 和 7 的位,而不是位置 0 和 4
  2. 要为单个位置构造位掩码,请使用表达式1 << n,其中n是从最低有效位开始计数的位置编号。
  3. 要在单个掩码中组合多个位,请使用|运算符。例如,(1 << 4) | (1 << 7)构造用于翻转第 4 位和第 7 位的掩码。
于 2013-10-27T10:57:04.650 回答
5

如果您的字节是 x,并且您想在第 i 个和第 j 个位置切换位:

x = x ^ ((1<<i) | (1<<j));

所以,在你的情况下,它只是 (1<<4) | (1<<7)。:)

于 2013-10-27T11:38:34.763 回答
1

首先,祝你好运!

一句话—​​—从右边而不是左边计算位更有用,因为有各种字节/字大小(8 位、16 位等),并且该计数可以更好地保持兼容性。因此,在您的情况下,您指的是#7 和#4 位(零计数)。

您的意思是“翻转”(更改 0<->1 位)还是在一个和另一个之间“切换”它们?

对于第一个选项,上面的答案(XOR with "int mask = 0x90; // 10010000")非常好。对于第二个,它有点棘手(但不多)。

于 2013-10-27T11:00:56.270 回答
1

要翻转位,您可以使用异或位运算符。这需要两个操作数(通常是您要操作的值和定义将翻转哪些位的掩码)。异或 (XOR) 运算符仅当且仅当两者之一设置为 1 而非两者都设置为 1 时才会翻转一点。请参见下面的(简单)示例:

#include <stdio.h>

int main(int argc, char** argv)
{
   int num = 7;   //00000111
   int mask = 3;  //00000011

   int result = num ^ mask; //00000100
   printf("result = %d\n", result); //should be 4

   return 0;
}
于 2013-10-27T11:19:14.253 回答