2

我遇到了算法问题。

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

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

描述如下:

如果两个异或掩码具有相同的值,则此函数将异或掩码的位插入与掩码为 1 的位位置。其他位保持不变。

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

但是,在进行数学运算并遍历函数时,结果是00000000.

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

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

例如:当前值为00101101(我不知道这个),但我只是想确保设置了第二位,所以结果必须是01101101.

重要信息在我的文档 PDF 中,XOR 和第一个 xorMask1 之间似乎有一点空间,所以这可能是一个~!其他否定符号可能存在​​的地方,并且很可能由于一些奇怪的编码问题而丢失。因此,我将测试该函数是否符合文档所述或函数声明所述。抓紧你的头盔,将返回结果(请鼓)....

4

7 回答 7

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 Xor2whereXor1 == 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
于 2012-10-01T12:19:21.203 回答
2

我已经研究了一段时间了,我想我看到了其他人没有看到的东西。XOR AND XOR 过程对于设置多个字节而不干扰其他字节很有用。例如,我们有一个给定的字节,我们希望将其设置为 1x1x xxx0,其中 x 是我们不关心的值。使用 XOR AND 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 =

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

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

编辑:最后一个 XOR 用于切换。如果您知道有一点需要更改,但不是什么,请将其设为 1。假设我们要切换第三位,或者掩码将是:

XOR1 10100000
AND  01011110
XOR2 10100100

然后最后一次交互将更改为

00010100 =
10100100 XOR
10110000 =

第三位被切换。

于 2012-10-05T16:18:53.360 回答
1

要回答您非常简单的问题,这是如何设置的:

value |=  0x100;  

这是如何清除一点:

value &= ~0x100;

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

其他人已经指出您的代码示例没有按照它声称的那样做,所以我不会进一步详细说明。

于 2012-10-01T12:32:48.420 回答
0

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

  • 任何 Xor 0 都将保持不变(1 Xor 0 为 1;0 Xor 0 为 0)
  • 任何 Xor 1 都将被翻转(1 Xor 1 为 0;0 Xor 1 为 1)
  • 当 Anding 时,除了 And 掩码中有 1 位之外,一切都变为 0 - 那些保持不变

所以你的第一个 Xor 只能改变左边的第二位,因为那是你在掩码中有一个 1 的地方。它将那个位从 0 翻转到 1。 And 不理会那个位并将所有其他位设置为 0。第二个 Xor 将您的 1 翻转回 0 并保持所有其他位不变。

结果:就像你说的那样全为零。

你的问题是 Xor 和 And 的组合会给你文档所说的行为吗?要仅打开一位,请使用按位或,其中掩码只有该位 1,其他位为零。只关闭一个位,使用按位 And 其中掩码只有那个位 0,其他位是 1。这很费力,而且有很多测试,所以如果你想打开 2 位和关闭 3 位,这种诡计节省了很多“如果”,但如果你只是想影响一点,那就用简单的方法来做,忽略这个功能,它似乎写得不太正确。

于 2012-10-01T12:20:22.857 回答
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
于 2012-10-01T12:21:11.147 回答
0

XOR 是二进制互斥的,只有当一个或另一个位设置为 1 时才会返回 true,因此:

00101101 XOR 01000000 = 01101101
01101101 AND 01000000 = 01000000
01000000 XOR 01000000 = 00000000
于 2012-10-01T12:21:38.303 回答
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     |

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

于 2012-10-01T12:22:03.043 回答