在Python中反转XOR和按位运算

dre*_*k01 9 python xor bitwise-operators

我尝试了很多搜索,但我无法找到一个解决方案来反转XOR和Bitwise操作的组合.

num[i] = num[i]^( num[i] >> 1 );
Run Code Online (Sandbox Code Playgroud)

如何使用Python反转此操作.我尝试了这里解释的XOR概念: XOR的反函数是什么?

还是无法解决数学问题.

har*_*old 5

这是格雷码.在Hackers'Delight中还有一章介绍它.维基百科文章中有一些代码,但为了避免仅链接答案,这里是你如何构建逆:
do x ^= x >> (1 << i)for i = 0 .. ceil(log_2(bits)) - 1.

所以对于32位整数,

x ^= x >> 1;
x ^= x >> 2;
x ^= x >> 4;
x ^= x >> 8;
x ^= x >> 16;
Run Code Online (Sandbox Code Playgroud)

对于n位整数:(未完全测试,但似乎到目前为止工作)

def gray2binary(x):
    shiftamount = 1;
    while x >> shiftamount:
        x ^= x >> shiftamount
        shiftamount <<= 1
    return x
Run Code Online (Sandbox Code Playgroud)


jfs*_*jfs 3

要获得更快的转换版本,请参阅@harold 的回答


让我们考虑 2 位数字:

00 = 00 ^ 00 (0 -> 0)
01 = 01 ^ 00 (1 -> 1)
11 = 10 ^ 01 (2 -> 3)
10 = 11 ^ 01 (3 -> 2)
Run Code Online (Sandbox Code Playgroud)

如果y[i]是第 i 位(小尾数),则如下y = x ^ (x >> 1)所示:

y[1]y[0] = x[1]x[0] ^ 0x[1] # note: y[1]y[0] means `(y[1] << 1) | y[0]` here
Run Code Online (Sandbox Code Playgroud)

代表着:

y[1] = x[1] ^ 0
y[0] = x[0] ^ x[1]
Run Code Online (Sandbox Code Playgroud)

如果我们知道y然后得到x

 y[i] = (y & ( 1 << i )) >> i
 x[1] = y[1] ^ 0
 x[0] = y[0] ^ x[1] = y[0] ^ (y[1] ^ 0)
 x = (x[1] << 1) | x[0]
Run Code Online (Sandbox Code Playgroud)

您可以将其概括为n- 位数字:

def getbit(x, i):
    return (x >> i) & 1

def y2x(y):
    assert y >= 0    
    xbits = [0] * (y.bit_length() + 1)
    for i in range(len(xbits) - 2, -1, -1):
        xbits[i] = getbit(y, i) ^ xbits[i + 1] 

    x = 0
    for i, bit in enumerate(xbits):
        x |= (bit << i) 
    return x
Run Code Online (Sandbox Code Playgroud)

y2x()可以简化为在没有位数组的情况下处理数字:

def y2x(y):
    assert y >= 0    
    x = 0
    for i in range(y.bit_length() - 1, -1, -1):
        if getbit(y, i) ^ getbit(x, i + 1):
            x |= (1 << i) # set i-th bit
    return x
Run Code Online (Sandbox Code Playgroud)

例子

print("Dec Gray Binary")
for x in range(8):
    y = x ^ (x >> 1)
    print("{x: ^3} {y:03b}  {x:03b}".format(x=x, y=y))
    assert x == y2x(y)
Run Code Online (Sandbox Code Playgroud)

输出

Dec Gray Binary
 0  000  000
 1  001  001
 2  011  010
 3  010  011
 4  110  100
 5  111  101
 6  101  110
 7  100  111
Run Code Online (Sandbox Code Playgroud)