我正在寻找一个灵活的功能,可以反转数字二进制表示的数字。
如果f
是这样的功能,我会
int(reversed(s),2) == f(int(s,2))
每当s是一串零和一个以1开头的。
现在我正在使用lambda x: int(''.join(reversed(bin(x)[2:])),2)
就简洁而言,这是好的,但这似乎是一种相当迂回的方式。
我想知道是否有一个更好的(也许更快)的方式与位运算符,什么不是。
答案 0 :(得分:7)
您可以使用这样的移位运算符来实现:
def revbits(x):
rev = 0
while x:
rev <<= 1
rev += x & 1
x >>= 1
return rev
它似乎没有比你的方法快得多(事实上,对我来说稍慢)。
答案 1 :(得分:6)
怎么样
int('{0:b}'.format(n)[::-1], 2)
或
int(bin(n)[:1:-1], 2)
第二种方法似乎是两者中较快的一种,但两者都比你当前的方法快得多:
import timeit
print timeit.timeit("int('{0:b}'.format(n)[::-1], 2)", 'n = 123456')
print timeit.timeit("int(bin(n)[:1:-1], 2)", 'n = 123456')
print timeit.timeit("int(''.join(reversed(bin(n)[2:])),2)", 'n = 123456')
1.13251614571 0.710681915283 2.23476600647
答案 2 :(得分:2)
这是我的建议:
In [83]: int(''.join(bin(x)[:1:-1]), 2)
Out[83]: 9987
相同的方法,稍微简化。
答案 3 :(得分:2)
我认为你当前的方法非常好,但你可能会失去list()
调用,因为str.join()
会接受任何可迭代:
def binary_reverse(num):
return int(''.join(reversed(bin(num)[2:])), 2)
除了最简单的函数之外,它还建议不要使用lambda
,只使用一次,并通过内联使周围的代码更清晰。
我觉得这很好,因为它描述了你想做什么 - 采用数字的二进制表示,反转它,然后再次得到一个数字。这使得这段代码非常易读,这应该是一个优先事项。
答案 4 :(得分:1)
使用二进制运算,位移和其他好东西,Hacker's Delight的整个半章专门讨论了这个问题(第7-1节:反转位和字节)。看起来像these are all possible in Python,它应该比二进制到字符串和反向的方法快得多。
这本书不公开,但我发现这篇博文讨论了其中的一些内容。博客文章中显示的方法遵循本书的以下引用:
通过相邻交换可以非常有效地完成位反转 单个位,然后交换相邻的2位字段,依此类推 如下所示。这五个赋值语句可以在任何语句中执行 顺序。
http://blog.sacaluta.com/2011/02/hackers-delight-reversing-bits.html
答案 5 :(得分:1)
>>> def bit_rev(n):
... return int(bin(n)[:1:-1], 2)
...
>>> bit_rev(2)
1
>>>bit_rev(10)
5