反转 Python 整数的位
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12681945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reversing bits of Python integer
提问by David Chouinard
Given a decimal integer (eg. 65), how does one reverse the underlying bits in Python? ie. the following operation:
给定一个十进制整数(例如 65),如何反转 Python 中的底层位?IE。以下操作:
65 → 01000001 → 10000010 → 130
It seems that this task can be broken down into three steps:
这个任务似乎可以分解为三个步骤:
- Convert the decimal integer to binary representation
- Reverse the bits
- Convert back to decimal
- 将十进制整数转换为二进制表示
- 反转位
- 转换回十进制
Steps #2 and 3 seem pretty straightforward (see thisand thisSO question related to step #2), but I'm stuck on step #1. The issue with step #1 is retrieving the full decimal representation with filling zeros (ie. 65 = 01000001, not 1000001).
第 2 步和第 3 步看起来很简单(请参阅与第 2 步相关的这个和这个SO 问题),但我被困在第 1 步。第 1 步的问题是检索填充零的完整十进制表示(即 65 = 01000001,而不是 1000001)。
I've searched around, but I can't seem to find anything.
我四处寻找,但似乎找不到任何东西。
采纳答案by nneonneo
int('{:08b}'.format(n)[::-1], 2)
You can specify any filling length in place of the 8. If you want to get really fancy,
你可以指定任何填充长度来代替 8。如果你想变得很花哨,
b = '{:0{width}b}'.format(n, width=width)
int(b[::-1], 2)
lets you specify the width programmatically.
允许您以编程方式指定宽度。
回答by Fred Foo
There's no need, and no way, to "convert a decimal integer to binary representation". All Python integers are represented as binary; they're just converted to decimal when you print them for convenience.
没有必要也没有办法“将十进制整数转换为二进制表示”。所有 Python 整数都表示为二进制;为方便起见,它们只是在您打印时转换为十进制。
If you want to follow this solutionto the reversal problem, you only need to find appropriate numbits. You can either specify this by hand, or compute the number of bits needed to represent an integer nwith n.bit_length()(new in Python 2.7 and 3.1).
如果你想按照这个解来解决反转问题,你只需要找到合适的numbits. 你可以手工或者指明,或计算来表示一个整数所需要的比特的数目n与n.bit_length()(在Python 2.7和3.1的新)。
However, for 65, that would give you 7, as there's no reason why 65 should require any more bits. (You might want to round up to the nearest multiple of 8...)
然而,对于 65,那会给你 7,因为没有理由 65 需要更多位。(您可能想要四舍五入到最接近的 8 倍数...)
回答by Bruce
If you are after more speed, you can use the technique described in http://leetcode.com/2011/08/reverse-bits.html
如果您追求更高的速度,可以使用http://leetcode.com/2011/08/reverse-bits.html 中描述的技术
def reverse_mask(x):
x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1)
x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2)
x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4)
x = ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8)
x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16)
return x
回答by Paul Hankin
You can test the i'th bit of a number by using a shift and mask. For example, bit 6 of 65 is (65 >> 6) & 1. You can set a bit in a similar way by shifting 1 left the right number of times. These insights gives you code like this (which reverses x in a field of 'n' bits).
您可以使用移位和掩码来测试数字的第 i 位。例如,65 的第 6 位是(65 >> 6) & 1。您可以通过将 1 左移正确的次数以类似的方式设置位。这些见解为您提供了这样的代码(在“n”位字段中反转 x)。
def reverse(x, n):
result = 0
for i in xrange(n):
if (x >> i) & 1: result |= 1 << (n - 1 - i)
return result
print bin(reverse(65, 8))
回答by Jay Wong
def reverse_bit(num):
result = 0
while num:
result = (result << 1) + (num & 1)
num >>= 1
return result
We don't really need to convert the integer into binary, since integers are actually binary in Python.
我们真的不需要将整数转换为二进制,因为整数在 Python 中实际上是二进制的。
The reversing idea is like doing the in-space reversing of integers.
反转的想法就像在空间中对整数进行反转。
def reverse_int(x):
result = 0
pos_x = abs(x)
while pos_x:
result = result * 10 + pos_x % 10
pos_x /= 10
return result if x >= 0 else (-1) * result
For each loop, the original number is dropping the right-most bit(in binary). We get that right-most bit and multiply 2 (<<1) in the next loop when the new bit is added.
对于每个循环,原始数字丢弃最右边的位(二进制)。<<1当添加新位时,我们得到最右边的位并在下一个循环中乘以 2 ( )。
回答by bluefoggy
One more way to do it is to loop through the bits from both end and swap each other. This i learned from EPI python book.
另一种方法是循环遍历两端的位并相互交换。这是我从 EPI python 书中学到的。
i = 0; j = 7
num = 230
print(bin(num))
while i<j:
# Get the bits from both end iteratively
if (x>>i)&1 != (x>>j)&1:
# if the bits don't match swap them by creating a bit mask
# and XOR it with the number
mask = (1<<i) | (1<<j)
num ^= mask
i += 1; j -= 1
print(bin(num))
回答by Sudip Ghimire
best way to do is perform bit by bit shifting
最好的方法是逐位执行
def reverse_Bits(n, no_of_bits):
result = 0
for i in range(no_of_bits):
result <<= 1
result |= n & 1
n >>= 1
return result
# for example we reverse 12 i.e 1100 which is 4 bits long
print(reverse_Bits(12,4))
回答by Sof
Regularly there is the need to apply this operation on array of numbersand not for single number. To increase speed, it's probably better to use NumPy array. There are two solutions.
通常需要将此操作应用于数字数组而不是单个数字。为了提高速度,最好使用 NumPy 数组。有两种解决方案。
x1.34 faster than second solution:
x1.34 比第二个解决方案快:
import numpy as np
def reverse_bits_faster(x):
x = np.array(x)
bits_num = x.dtype.itemsize * 8
# because bitwise operations may change number of bits in numbers
one_array = np.array([1], x.dtype)
# switch bits in-place
for i in range(int(bits_num / 2)):
right_bit_mask = (one_array << i)[0]
left_bit = (x & right_bit_mask) << (bits_num - 1 - i * 2)
left_bit_mask = (one_array << (bits_num - 1 - i))[0]
right_bit = (x & left_bit_mask) >> (bits_num - 1 - i * 2)
moved_bits_mask = left_bit_mask | right_bit_mask
x = x & (~moved_bits_mask) | left_bit | right_bit
return x
Slower, but more easy to understand (based on solution proposed by Sudip Ghimire):
更慢,但更容易理解(基于Sudip Ghimire 提出的解决方案):
import numpy as np
def reverse_bits(x):
x = np.array(x)
bits_num = x.dtype.itemsize * 8
x_reversed = np.zeros_like(x)
for i in range(bits_num):
x_reversed = (x_reversed << 1) | x & 1
x >>= 1
return x_reversed
回答by personal_cloud
An inefficient but concise method that works in both Python 2.7 and Python 3:
一种低效但简洁的方法,适用于 Python 2.7 和 Python 3:
def bit_reverse(i, n):
return int(format(i, '0%db' % n)[::-1], 2)
For your example:
对于您的示例:
>>> bit_reverse(65, 8)
130

