为什么在与 1 进行异或运算时取反值会改变结果?

Why does negating a value change the result when XORing it with 1?

我知道 XOR 的工作原理,

Console.WriteLine(1^1);  // returns 0

结果

00000001
00000001 
--------
00000000 

但这 return 2 是怎么回事?

Console.WriteLine(-(-1^1)); // returns 2

这个表达式被编译器解释为:

-((-1)^1)

这是: - ((11111111) XOR (00000001)) = -(11111110) = - (-2) = 2

要了解为什么编译器选择 -((-1)^1) 而不是 -(-(1^1)),请查看有关 C# 运算符优先级的 this 文章。最相关的部分是一元 - 运算符(粗体:-( - 1^1) )比 XOR 运算符 ^ 具有更高的优先级.因此否定发生在 XOR 之前,我们最终得到 -((-1)^1).

我在这里每个整数使用 8 位。通常你应该期望每个数字有 32 或 64 位,但在这种情况下它是无关紧要的;


要更好地理解为什么 11111111 是 -1,而 11111110 是 -2,请阅读有关二进制补码的更多信息 - https://en.wikipedia.org/wiki/Two%27s_complement。简而言之,您将除了最左边的所有位都视为 2 的连续幂。最左边的位被视为下一个幂,但为负数。

示例:

10001100 = 1 * (-(2^7)) + 0 * 2^6 + 0 * 2^5 + 0 * 2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0

-1 存储为所有位都设置为 1 的值。如果我们继续使用您的 8 位示例,则 -1 将等于 11111111。因此 -1^1 给出以下内容:

11111111
00000001 
--------
11111110

等于-2。当你用另一个减号反转它时,你得到 2.

负数以我们称之为two's complement的方式存储。如果你想在脑海中快速计算它,你可以翻转你的数字的正等价的所有位,然后加一。所以对于 -1:

 1: 00000001
    --------
    11111110
   +       1
    --------
-1: 11111111

解释为什么 -1 存储为 11111111。

如果你想更深入地了解二进制的补码,this question也可能对你有所帮助。

-111111111(检查二进制补码) 当您使用 1 进行异或时,即 00000001 您有: 11111110-2(同样是二进制补码)

为了更好地理解二进制补码(数学可以很抽象),这是我记住的:

0 = 00...00

1 = 00...001

...

max - 1 = 011...110

max = 011...11

min = 100...00

min + 1 = 100...001

...

-1 = 11...11

显然,minmax 取决于您用来表示整数的位数

在二进制中使用二进制补码; 11111111^00000001=11111110。 二进制补码 11111110 是十进制 -2.

负数表示为binary complement,即

-x == ~x + 1

所以我们有

 -(-1 ^ 1) ==
 -(0b11111...1111 ^ 1) ==
 -(0b11111...1110) ==
  2

int 有 32 位。

-1 等于 1111 1111 1111 1111 1111 1111 1111 1111

1 等于 0000 0000 0000 0000 0000 0000 0000 0001

所以 -1 ^ 1 等于 1111 1111 1111 1111 1111 1111 1111 1110 等于 -2

所以 (-(-1^1)) = 2

查看整数和浮点数的位表示以获取更多信息。

我假设已签名 Int32s.

   -1   11111111111111111111111111111111 (two's complement)
    1   00000000000000000000000000000001
-----------------------------------------
  -1^1  11111111111111111111111111111110
-(-1^1) 00000000000000000000000000000010 --> 2

参见C# operator precedence and two's complement