我在纸上进行了几次测试,但似乎无法在任何地方找到确认。
假设我有几个独特的8位数字,我将它们混合在一起存储在某个地方。如果我,那么,稍后,将那些相同的数字与存储的数字一起,我将总是得到0?
基本上我有一个条件的枚举,其中一些条件需要在操作发生之前完成。作为一个完整性检查,并确保我不会意外地回来并在以后破坏此代码,我正在考虑将所需的条件一起开始,然后在满足条件时对存储的值进行异常处理。然后就在操作发生之前,确保我们回到0。
类似
sanity_check = C1 ^ C3 ^ C5
...
//Condition one is met
sanity_check ^= C1
...
//Condition 3 is met
sanity_check ^= C3
...
//Condition 5 is met
sanity_check ^= C5
...
if( sanity_check == 0 )
Do operation
我知道它并非完美无瑕,因为在合适的条件下,我可能会在那里找到一个中间0状态。但它更适合我自己使用,以防止将来意外移动其中一个条件。
答案 0 :(得分:6)
是的,XOR是可交换和关联的,x ^ x == 0
,因此您可以通过再次执行相同的序列来撤消一系列XOR。
答案 1 :(得分:3)
最好使用位字段,其中每个位代表一个条件:
C1 = 1; // 1 << 0
C2 = 2; // 1 << 1
C3 = 4; // 1 << 2
C4 = 8; // 1 << 3
C5 = 16; // 1 << 4
// Condition one is met
sanity_check |= C1;
....
// If Conditions 1 2 and 4 passed
if((sanity_check & (C1 | C2 | C4)) == (C1 | C2 | C4))
// If Conditions 1 and 2 passed and 3 failed
if((sanity_check & (C1 | C2 | C3)) == (C1 | C2))
这样,当您到达代码中要检查它们的点时,可以使用按位运算符检查不同的条件集。您也可以保证只有满足所有要求时才会输入if语句(而不是误报的可能性)。
答案 2 :(得分:1)
是。 Daniel的回答为直观地理解为什么XOR是完全可逆的提供了一个很好的基础。我觉得你要确定这是 始终 的情况。是时候走下兔子洞了!
二进制数字(ints
以及其他所有内容都归结为)和^
运算符形成了一个名为group的内容。这意味着对于ints
a
,b
和c
。
a ^ b
始终也是int
。a ^ b ^ c
始终相同,无论您先计算哪一对。这就是丹尼尔所说的“联想”。int
(0
)0 ^ a = a ^ 0 = a
。这是身份,因为带有int
的XORing 0不会改变它。a
,始终总是 b
,以便a ^ b = b ^ a = 0
。在这种情况下,b
被称为a
的倒数,因为它会中和a
以提供身份。您还可以证明每个数字只有一个这样的反转,但我不打算这样做。现在,特定的ints
和^
对有两个属性可以实现您所说的可能。
a ^ b == b ^ a
适用于任何a
&amp; b
。这就是丹尼尔所说的“交换”。a ^ a = 0
,这意味着int
与^
相关,它是自己的逆。使用这个,我们以你的表达为例。所有操作后得到的最终结果是:
C1 ^ C3 ^ C5 ^ C1 ^ C3 ^ C5
现在,因为我们有交换性,我们可以切换它们并将它们配对以获得:
C1 ^ C1 ^ C3 ^ C3 ^ C5 ^ C5
由于相关性和自相反的东西,我们得到:
(C1 ^ C1) ^ (C3 ^ C3) ^ (C5 ^ C5) = 0 ^ 0 ^ 0 = 0
您可以使用相同的逻辑来确保任何表达方式。这将始终为真。你获得中间0的事实并不重要。事实上,任何价值观都无关紧要。数学让你满意。