【问题标题】:Reversing XOR and Bitwise operation in Python在 Python 中反转 XOR 和按位运算
【发布时间】:2014-12-16 09:00:30
【问题描述】:

我尝试了很多搜索,但我无法找到组合反转 XOR 和按位运算的解决方案。

num[i] = num[i]^( num[i] >> 1 );

如何使用 Python 反转此操作。我尝试了这里解释的 XOR 概念: What is inverse function to XOR?

仍然无法解决数学问题。

【问题讨论】:

  • 能提供输入输出的例子吗?
  • XOR 是二元运算符。它需要两个操作数才能工作。要反转它的效果,您至少需要两个操作数。但是你只有一个操作数。所以,会有很多数字组合可以产生结果。
  • 异或的逆是异或,伙计!

标签: python bitwise-operators xor


【解决方案1】:

有关更快的转换版本,请参阅@harold's answer


让我们考虑 2 位数字:

00 = 00 ^ 00 (0 -> 0)
01 = 01 ^ 00 (1 -> 1)
11 = 10 ^ 01 (2 -> 3)
10 = 11 ^ 01 (3 -> 2)

如果 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

意思是:

y[1] = x[1] ^ 0
y[0] = x[0] ^ x[1]

如果我们知道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]

您可以将其概括为n-bit number:

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

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

示例

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)

输出

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

【讨论】:

    【解决方案2】:

    那是Gray code。在 Hackers' Delight 中也有一章关于它。在那篇维基百科文章中有一些代码,但为了避免仅使用链接的答案,以下是构建逆向的方法:
    i = 0 .. ceil(log_2(bits)) - 1x ^= x &gt;&gt; (1 &lt;&lt; i)

    所以对于 32 位整数,

    x ^= x >> 1;
    x ^= x >> 2;
    x ^= x >> 4;
    x ^= x >> 8;
    x ^= x >> 16;
    

    对于 n 位整数:(尚未完全测试,但目前似乎可以工作)

    def gray2binary(x):
        shiftamount = 1;
        while x >> shiftamount:
            x ^= x >> shiftamount
            shiftamount <<= 1
        return x
    

    【讨论】:

    • +1 用于识别格雷码。您应该添加一个适用于任意精度 Python 整数的小型 Python sn-p。
    • @J.F.Sebastian 好的,我可以试试,不过我不太懂 Python
    • 我添加了代码示例。你可以用你的代码替换它。
    • @J.F.Sebastian 好的,谢谢,应该可以让它在对数时间内运行
    • 我已经测量了 30 次梅森素数格雷码 (p = 2 ** 132049 - 1) 的时间性能。您的代码速度提高了 1000 倍(731 毫秒对 280 微秒)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 2017-02-27
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    相关资源
    最近更新 更多