我遇到了算法问题。
我有一个用于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
或~
或某些地方其他否定标志可能已经存在,并且由于一些奇怪的编码问题很可能会丢失。所以我会测试函数是否符合文档说明或函数声明所说的内容。坚持你的头盔,将回复结果(请鼓)....
答案 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只能改变左边的第二位,因为那是你在面具中有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 |
检查此表以获取位的输入值,以检查输出。相应地更换面罩,以满足您的输出需求。