什么是Xor - >并且 - > Xor呢?

时间:2012-10-01 12:08:41

标签: c++ bitwise-operators

我遇到了算法问题。

我有一个用于IO的字节,其中某些位可以使用一个名为XorAndXor的方法设置。 该算法的工作原理如下:

newValue = (((currentValue XOR xorMask1) AND andMask) XOR xorMask2)

描述如下:

  

如果两个xor-mask具有相同的值,则此函数将插入   xor-mask的位到和掩码所在的位位置   1.其他位保持不变。

所以我对这个函数的期望是当我有以下字节时:00101101我使用01000000作为xor-mask和作为and-mask,只有第二个比特是设置为1,结果为01101101

但是,在进行数学运算并完成函数时,结果为00000000

我做错了什么或者有什么关于这个功能的东西我不明白?这种低级编程已经有一段时间了,所以我真的不知道这是一种经常使用的方法,以及为什么以及如何使用它。

我想问一下这个简单的问题:有没有办法有效地使用这个函数来设置(或取消设置/更改)一个位(没有专门询问当前值)?

例如:当前值为00101101(我不知道这一点),但我只是想确保第二位已设置,因此结果必须为{ {1}}。

重要信息在我的文档PDF中,似乎XOR与第一个xorMask1之间有一点空间,所以这可能是01101101~或某些地方其他否定标志可能已经存在,并且由于一些奇怪的编码问题很可能会丢失。所以我会测试函数是否符合文档说明或函数声明所说的内容。坚持你的头盔,将回复结果(请鼓)....

7 个答案:

答案 0 :(得分:4)

     00101101 
XOR  01000000
-------------
     01101101
AND  01000000
-------------
     01000000 
XOR  01000000
-------------
     00000000

文档不对。这不是我第一次看到一个完全偏离初始实现的实现,但没有人费心去更新文档。

我做了一个快速检查,所以我可能错了,但是跟随与文档一致:

newValue = (((currentValue XOR xorMask1) AND ~andMask) XOR xorMask2)

     00101101 
XOR  01100100
-------------
     01001001
AND  10011011
-------------
     00001001 
XOR  01100100
-------------
     01101101

这是表达式New = Curr XOR Xor1 AND ~And XOR Xor2的逻辑表,其中Xor1 == Xor2

CURR: 0 1 0 1   0 1 0 1 
XOR1: 0 0 1 1   0 0 1 1
AND:  0 0 0 0   1 1 1 1 
XOR2: 0 0 1 1   0 0 1 1 
-----------------------
NEW:  0 1 0 1   0 0 1 1 
      ---v---   ---v---
      same as   same as  
      current   xor mask
      where     where
      AND = 0   AND = 1

答案 1 :(得分:2)

我现在已经研究了一段时间了,我想我看到其他人没有。 XOR和XOR过程对于设置多个字节而不会打扰其他字节非常有用。例如,我们有一个给定的字节,我们要设置为1x1x xxx0,其中x是我们不关心的值。使用XOR和XOR过程,我们使用以下掩码来打开和关闭我们不关心的位。我们使用XOR掩码打开位,使用AND掩码关闭位,我们不关心掩码,我们保留默认值(0表示XOR掩码[x XOR 0 = x]和1对于AND掩码[x AND 1 = x])。因此,鉴于我们所需的价值,我们的面具看起来像这样:

XOR: 10100000
AND: 01011110

如果我们的神秘位读取10010101,则数学如下:

10010101
10100000 XOR
00110101 =
01011110 AND
00010100 =
10100000 XOR
10110100 =

我们想要的位是打开的,我们想要的位是关闭的,无论它们的先前状态如何。

这是管理多个位的一个很好的逻辑。

编辑:最后一次异或是用于切换。如果有一点你知道需要改变,但不知道要改变什么,那就让它成为1.所以我们想要切换第三位,或者掩码将是:

XOR1 10100000
AND  01011110
XOR2 10100100

最后一次互动将变为

00010100 =
10100100 XOR
10110000 =

并切换第三位。

答案 2 :(得分:1)

要回答你非常简单的问题,这就是如何设置一下:

value |=  0x100;  

这是如何清除一点:

value &= ~0x100;

在这个例子中,0x100是二进制的000100000000,所以它设置/清除第8位(从右边开始计算)。

其他人已经指出你的代码示例是如何做不到它声称的那样,所以我不会再详细说明了。

答案 3 :(得分:0)

让自己成为真理表,并在整个过程中遵循1和0。

  • 任何Xor 0都将保持不变(1 Xor 0为1; 0 Xor 0为0)
  • 任何Xor 1将被翻转(1 Xor 1为0; 0 Xor 1为1)
  • 当Anding,一切都变为0,除非在面具中有1位 - 那些保持不变

所以你的第一个Xor只能改变左边的第二位,因为那是你在面具中有1的位置。它将该位从0翻转到1.然后将该位单独留下并将所有其他位置设置为0.第二个Xor将您的1翻转为0并保持所有其他位置不变。

结果:像你说的所有零。

你的问题是什么Xor和And的组合会给你文档所说的行为?要仅打开一位,请使用按位或者掩码只有位1而其他位为零。要关闭一位,请使用按位并且掩码只有0位,其他位数为1.这很费力且有很多测试,所以如果你想打开2位和3位,这种欺骗可以节省很多“if”-ing,但是如果你只是想影响一点,那就按照简单的方式去做吧,然后忽略这个函数,这看起来写的不是很正确。

答案 4 :(得分:0)

XOR是逻辑异或。这意味着一个或另一个,但不是两个,也不是两个。 这是维基百科的真值表。

Input
A | B    Output
---------------
0 | 0 |  0
0 | 1 |  1
1 | 0 |  1
1 | 1 |  0

currentValue XOR xorMask1 = 
    00101101 xor 01000000 = 01101101

01010010 AND andMask = 
    01101101 and 01000000 = 01000000

01000000 XOR xorMask2 = 
    01000000 xor 01000000 = 00000000

答案 5 :(得分:0)

XOR是二进制异或,仅当一个或另一个位设置为1时才返回true,因此:

00101101 XOR 01000000 = 01101101
01101101 AND 01000000 = 01000000
01000000 XOR 01000000 = 00000000

答案 6 :(得分:0)

p|q|r|s|p^q|(p^q)&r|((p^q)&r)^s|
0|0|0|0| 0 |   0   |     0     |
0|0|0|1| 0 |   0   |     1     |
0|0|1|0| 0 |   0   |     0     |
0|0|1|1| 0 |   0   |     1     |
0|1|0|0| 1 |   0   |     0     |
0|1|0|1| 1 |   0   |     1     |
0|1|1|0| 1 |   1   |     1     |
0|1|1|1| 1 |   1   |     0     |
1|0|0|0| 1 |   0   |     0     |
1|0|0|1| 1 |   0   |     1     |
1|0|1|0| 1 |   1   |     1     |
1|0|1|1| 1 |   1   |     0     |
1|1|0|0| 0 |   0   |     0     |
1|1|0|1| 0 |   0   |     1     |
1|1|1|0| 0 |   0   |     0     |
1|1|1|1| 0 |   0   |     1     |

检查此表以获取位的输入值,以检查输出。相应地更换面罩,以满足您的输出需求。