6

我想计算一个无符号字符的反掩码。意思是如果原始掩码 0xc0 反掩码应该是 0x3f。也就是说所有位都应该被翻转或反转。我已经尝试了下面但似乎没有工作。

int flipBit(int x, unsigned char position)
{
  int mask = 1 << position;
  return x ^ mask;
}

int main(int argc , char* argv[])
{
        uint8_t mask = 0x03;
        uint8_t inverse_mask = 0;
        uint8_t temp = 0;
        int loop = 0;

        for (loop = 0; loop < 8 ; loop ++)
        {
                temp = flipBit(mask,loop);
                inverse_mask |= temp;
        }
        printf("mask 0x%x inv mask 0x%x \n",mask,inverse_mask);
        return 0;
}

我得到的结果是 mask 0x3 inv mask 0xff

我似乎无法在我的代码中找到错误。

4

5 回答 5

7

为什么你不能这样做:

uint8_t mask = 0x03;
uint8_t inverse_mask = ~mask;
于 2011-11-04T01:50:54.103 回答
6

使用 ~(按位非)运算符。

inverse_mask = ~mask;
于 2011-11-04T01:52:29.733 回答
3

有很多方法可以做到这一点。

假设你有这个二进制值:

x = 01110110

作为人类,我们可以将其“逆”识别为:

y = 10001001

现在让我们看看它的属性:

  • 的每一位y都是对应位的非x
    • 这个操作在 C 中是这样完成的:y = ~x;
    • 或者,我们知道一位 xor 1 没有给出那个位,所以y = x^0xFF;
  • 任何位加其非的总和为 1,没有进位。所以y+x == 0xFF
    • 所以,y = 0xFF-x;

至于为什么你的程序不起作用,让我们按照循环:

loop: 0
  mask:         0000 0011
  temp:         0000 0010
  inverse_mask: 0000 0010
loop: 1
  mask          0000 0011
  temp          0000 0001
  inverse_mask: 0000 0011
inverse_mask eventually: 0xFF

您可以在第一个循环中看到问题:您在第二个位置获得了一个inverse_mask您不应该拥有的问题。

如果您只想temp保留被翻转的位,您应该写 in flibBit,而不是:

return x ^ mask;

这一行:

return (x & mask) ^ mask;

这样您首先隔离该位,然后将其翻转。

我解释了,以便您了解程序中的错误,您仍然应该使用我首先提到的方法之一。

于 2011-11-04T02:06:49.553 回答
1

您的 flipBit 函数应最多返回一位,以便您的代码正常工作:

0x03 ^ 0x01 = 0x02
0x03 ^ 0x02 = 0x01
0x03 ^ 0x04 = 0x07
0x03 ^ 0x08 = 0x0b
0x03 ^ 0x10 = 0x13
0x03 ^ 0x20 = 0x23
0x03 ^ 0x40 = 0x43
0x03 ^ 0x80 = 0x83
0x2 ^ 0x1 ^ 0x7 ^ 0xb ^ 0x13 ^ 0x23 ^ 0x43 ^ 0x83 = 0xff

int flipBit(uint8_t x, unsigned char position)
{
  int mask = 1 << position;
  return (x & mask) ^ mask;
}
于 2011-11-04T02:02:44.327 回答
1

使用 XOR 非常简单。

uint8_t mask = 0x03;
uint8_t inverse_mask = mask ^ 0xFF;
于 2011-11-04T01:52:26.263 回答