在Python中将整数转换为二进制字符串

807

如何在Python中将整数转换为二进制字符串?

37   →   '100101'

对于相反的方法,请参见纯字符串处理算法此处 - CopyPasteIt
36个回答

12

替代方案摘要:

n=42
assert  "-101010" == format(-n, 'b')
assert  "-101010" == "{0:b}".format(-n)
assert  "-101010" == (lambda x: x >= 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:])(-n)
assert "0b101010" == bin(n)
assert   "101010" == bin(n)[2:]   # But this won't work for negative numbers.

贡献者包括John Fouhy, Tung Nguyen, mVChr, Martin Thoma和Martijn Pieters。


7
仅仅为了格式化一个值而使用str.format()太过繁琐,直接使用format()函数即可: format(n, 'b')。不需要解析占位符并将其与参数匹配。 - Martijn Pieters

11
>>> format(123, 'b')
'1111011'

10

对于我们这些需要将带符号整数(范围为-2 **(digits-1)至2 **(digits-1)-1)转换为二进制补码字符串的人,可以使用以下方法:

def int2bin(integer, digits):
    if integer >= 0:
        return bin(integer)[2:].zfill(digits)
    else:
        return bin(2**digits + integer)[2:]

这将产生:

>>> int2bin(10, 8)
'00001010'
>>> int2bin(-10, 8)
'11110110'
>>> int2bin(-128, 8)
'10000000'
>>> int2bin(127, 8)
'01111111'

8
你可以这样做:

像这样:

bin(10)[2:]

或:
f = str(bin(10))
c = []
c.append("".join(map(int, f[2:])))
print c

1
bin(n).replace("0b", "") - sanner little

7
使用numpy pack / unpackbits,它们是您最好的朋友。
Examples
--------
>>> a = np.array([[2], [7], [23]], dtype=np.uint8)
>>> a
array([[ 2],
       [ 7],
       [23]], dtype=uint8)
>>> b = np.unpackbits(a, axis=1)
>>> b
array([[0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8)

这个问题涉及到一个字符串表示。不过,这正是我所需要的,而无需先转换为字符串! :) - Tom Hale
1
doco 表示:将 uint8 数组的元素解压缩为一个二进制值输出数组。因此适用于值高达255。 - Tom Hale

6

接受的答案没有涉及负数,我会讲一下。 除了上面的答案,您还可以使用binhex函数。而在相反的方向上,则使用二进制表示法:

>>> bin(37)
'0b100101'
>>> 0b100101
37

但是对于负数,情况就会变得有些复杂了。这个问题并没有说明你希望如何处理负数。
Python只是添加一个负号,因此-37的结果将是这样的:
>>> bin(-37)
'-0b100101'

在计算机/硬件二进制数据中,不存在负号。我们只有1和0。因此,如果您正在读取或生成要由其他软件/硬件处理的二进制数据流,则需要先了解所使用的符号表示法。
一种表示法是 符号-数值表示法,其中第一个位表示负号,其余部分是实际值。在这种情况下,-37将是 0b1100101 ,而37将是 0b0100101 。这看起来像Python生成的内容,但对于正/负数,只需在前面添加0或1即可。
更常见的是 二进制补码表示法,它似乎更复杂,并且结果与Python的字符串格式化非常不同。您可以在链接中阅读详细信息,但对于8位有符号整数,-37将是 0b11011011 ,而37将是 0b00100101

Python没有简单的方法来生成这些二进制表示。您可以使用numpy将二进制补码值转换为Python整数:

>>> import numpy as np
>>> np.int8(0b11011011)
-37
>>> np.uint8(0b11011011)
219
>>> np.uint8(0b00100101)
37
>>> np.int8(0b00100101)
37

但是我不知道有什么内置函数可以轻松地完成相反的操作。bitstring包可以提供帮助。

>>> from bitstring import BitArray
>>> arr = BitArray(int=-37, length=8)
>>> arr.uint
219
>>> arr.int
-37
>>> arr.bin
'11011011'
>>> BitArray(bin='11011011').int
-37
>>> BitArray(bin='11011011').uint
219

5

numpy.binary_repr(num, width=None)

上面链接中的示例:

>>> np.binary_repr(3)
'11'
>>> np.binary_repr(-3)
'-11'
>>> np.binary_repr(3, width=4)
'0011'

The two’s complement is returned when the input number is negative and width is specified:

>>> np.binary_repr(-3, width=3)
'101'
>>> np.binary_repr(-3, width=5)
'11101'

5
使用位运算符的另一种算法,提供了另一个解决方案。
def int2bin(val):
    res=''
    while val>0:
        res += str(val&1)
        val=val>>1     # val=val/2 
    return res[::-1]   # reverse the string

一种更快的版本,不需要反转字符串。

def int2bin(val):
   res=''
   while val>0:
       res = chr((val&1) + 0x30) + res
       val=val>>1    
   return res 

第二个版本肯定不会更快,因为你最终得到的是类似于O(N^2)算法而不是O(N)。我见过像这样的事情杀死一个应用程序(在性能方面),因为开发人员认为在结尾处进行额外的遍历比在第一个循环中做一些额外的工作要慢。一旦修复,运行时间从几天降至几秒钟。 - Andreas Magnusson

5

Python 3.6 新增了一种名为格式化字符串字面量或 "f-strings" 的新的字符串格式化方法。
示例:

name = 'Bob'
number = 42
f"Hello, {name}, your number is {number:>08b}"

输出结果将是'Hello, Bob,您的号码是00001010!'

这个问题的讨论可以在此处找到 - 这里


4
n=input()
print(bin(n).replace("0b", ""))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接