Python int到二进制字符串?

是否有任何固定的Python方法可以将整数(或长)转换为Python中的二进制字符串?

Google上有无数dec2bin()函数……但我希望我可以使用内置函数/库。

1089730 次浏览

除非我误解了你所说的二进制字符串的意思,否则我认为你要找的模块是struct

Python的字符串格式方法可以采用格式规范。

>>> "{0:b}".format(37)
'100101'

Python 2的格式规范文档

Python 3的格式规范文档

如果您正在寻找与hex()等价的bin(),它是在python 2.6中添加的。

示例:

>>> bin(10)
'0b1010'

Python实际上确实已经为此内置了一些东西,能够执行'{0:b}'.format(42)等操作,这将为您提供42101010的位模式(在字符串中)。


更一般的理念是,没有任何语言或库会为其用户提供他们想要的一切。如果你在一个不能完全提供你需要的环境中工作,你应该在开发时收集代码片段,以确保你永远不必编写两次同样的事情。例如,伪代码:

define intToBinString, receiving intVal:
if intVal is equal to zero:
return "0"
set strVal to ""
while intVal is greater than zero:
if intVal is odd:
prefix "1" to strVal
else:
prefix "0" to strVal
divide intVal by two, rounding down
return strVal

它将根据十进制值构造您的二进制字符串。请记住,这是一段通用的伪代码,可能不是大多数有效的方法,尽管您似乎提出的迭代,它不会有太大的区别。这实际上只是作为如何完成的指南。

一般的想法是使用来自(按偏好顺序)的代码:

  • 语言或内置库。
  • 具有适当许可证的第三方库。
  • 自己的收藏。
  • 你需要写的新东西(并保存在你自己的收藏中以备后用)。

作为参考:

def toBinary(n):
return ''.join(str(1 & int(n) >> i) for i in range(64)[::-1])

此函数可以转换大到18446744073709551615的正整数,表示为字符串'1111111111111111111111111111111111111111111111111111111111111111'

可以修改它以提供更大的整数,尽管它可能不如"{0:b}".format()bin()方便。

如果你想要一个没有0b前缀的文本表示,你可以使用:

get_bin = lambda x: format(x, 'b')


print(get_bin(3))
>>> '11'


print(get_bin(-3))
>>> '-11'

当你想要一个n位表示时:

get_bin = lambda x, n: format(x, 'b').zfill(n)
>>> get_bin(12, 32)
'00000000000000000000000000001100'
>>> get_bin(-12, 32)
'-00000000000000000000000000001100'

或者,如果您更喜欢具有函数:

def get_bin(x, n=0):
"""
Get the binary representation of x.


Parameters
----------
x : int
n : int
Minimum number of digits. If x needs less digits in binary, the rest
is filled with zeros.


Returns
-------
str
"""
return format(x, 'b').zfill(n)

这是我刚刚实现的代码。这不是方法,但您可以将其用作即用型功能

def inttobinary(number):
if number == 0:
return str(0)
result =""
while (number != 0):
remainder = number%2
number = number/2
result += str(remainder)
return result[::-1] # to invert the string

与Yusuf Yazici的回答相似

def intToBin(n):
if(n < 0):
print "Sorry, invalid input."
elif(n == 0):
print n
else:
result = ""
while(n != 0):
result += str(n%2)
n /= 2
print result[::-1]

我调整了它,使唯一被改变的变量是结果(当然还有n)。

如果您需要在其他地方使用此函数(即,让另一个模块使用结果),请考虑以下调整:

def intToBin(n):
if(n < 0):
return -1
elif(n == 0):
return str(n)
else:
result = ""
while(n != 0):
result += str(n%2)
n //= 2            #added integer division
return result[::-1]

所以-1将是您的前哨值,表示转换失败。(这是假设您只转换正数,无论是整数还是长整数)。

类似的解决方案

def to_bin(dec):
flag = True
bin_str = ''
while flag:
remainder = dec % 2
quotient = dec / 2
if quotient == 0:
flag = False
bin_str += str(remainder)
dec = quotient
bin_str = bin_str[::-1] # reverse the string
return bin_str

这是一个简单的解决方案,使用divmod()函数返回提醒和没有分数的除法结果。

def dectobin(number):
bin = ''
while (number >= 1):
number, rem = divmod(number, 2)
bin = bin + str(rem)
return bin
def binary(decimal) :
otherBase = ""
while decimal != 0 :
otherBase  =  str(decimal % 2) + otherBase
decimal    //=  2
return otherBase


print binary(10)

输出:

1010

通过使用按位运算符,使用另一种算法的另一种解决方案。

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
n=input()
print(bin(n).replace("0b", ""))

替代品概述:

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.

贡献者包括johnfouhyTung NguyenmVChrmartinthoma

lambda的单行代码:

>>> binary = lambda n: '' if n==0 else binary(n/2) + str(n%2)

测试:

>>> binary(5)
'101'



编辑

但随后:(

t1 = time()
for i in range(1000000):
binary(i)
t2 = time()
print(t2 - t1)
# 6.57236599922

在比较

t1 = time()
for i in range(1000000):
'{0:b}'.format(i)
t2 = time()
print(t2 - t1)
# 0.68017411232

使用numpy pack/unpack bit,他们是你最好的朋友。

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)

这是使用常规数学的另一种方法,没有循环,只有递归。(琐碎的情况0不返回任何内容)。

def toBin(num):
if num == 0:
return ""
return toBin(num//2) + str(num%2)


print ([(toBin(i)) for i in range(10)])


['', '1', '10', '11', '100', '101', '110', '111', '1000', '1001']

一种简单的方法是使用字符串格式,请参阅此页面

>> "{0:b}".format(10)
'1010'

如果你想有一个固定长度的二进制字符串,你可以使用:

>> "{0:{fill}8b}".format(10, fill='0')
'00001010'

如果需要2的补码,则可以使用以下行:

'{0:{fill}{width}b}'.format((x + 2**n) % 2**n, fill='0', width=n)

其中n是二进制字符串的宽度。

如果你愿意放弃“纯”Python但获得大量火力,那是Sage-这里的例子

sage: a = 15
sage: a.binary()
'1111'

您会注意到它作为字符串返回,因此要将其用作数字,您需要执行以下操作

sage: eval('0b'+b)
15

这是一个简单的二进制到十进制转换器,连续循环

t = 1
while t > 0:
binaryNumber = input("Enter a binary No.")
convertedNumber = int(binaryNumber, 2)


print(convertedNumber)


print("")
try:
while True:
p = ""
a = input()
while a != 0:
l = a % 2
b = a - l
a = b / 2
p = str(l) + p
print(p)
except:
print ("write 1 number")

具有DEC、BIN、HEX所有必要功能的计算器: (使用Python 3.5制作并测试)

您可以更改输入的测试数字并获取转换后的数字。

# CONVERTER: DEC / BIN / HEX


def dec2bin(d):
# dec -> bin
b = bin(d)
return b


def dec2hex(d):
# dec -> hex
h = hex(d)
return h


def bin2dec(b):
# bin -> dec
bin_numb="{0:b}".format(b)
d = eval(bin_numb)
return d,bin_numb


def bin2hex(b):
# bin -> hex
h = hex(b)
return h


def hex2dec(h):
# hex -> dec
d = int(h)
return d


def hex2bin(h):
# hex -> bin
b = bin(h)
return b




## TESTING NUMBERS
numb_dec = 99
numb_bin = 0b0111
numb_hex = 0xFF




## CALCULATIONS
res_dec2bin = dec2bin(numb_dec)
res_dec2hex = dec2hex(numb_dec)


res_bin2dec,bin_numb = bin2dec(numb_bin)
res_bin2hex = bin2hex(numb_bin)


res_hex2dec = hex2dec(numb_hex)
res_hex2bin = hex2bin(numb_hex)






## PRINTING
print('------- DECIMAL to BIN / HEX -------\n')
print('decimal:',numb_dec,'\nbin:    ',res_dec2bin,'\nhex:    ',res_dec2hex,'\n')


print('------- BINARY to DEC / HEX -------\n')
print('binary: ',bin_numb,'\ndec:    ',numb_bin,'\nhex:    ',res_bin2hex,'\n')


print('----- HEXADECIMAL to BIN / HEX -----\n')
print('hexadec:',hex(numb_hex),'\nbin:    ',res_hex2bin,'\ndec:    ',res_hex2dec,'\n')

计算二进制数:

print("Binary is {0:>08b}".format(16))

计算一个数的十六进制小数

print("Hexa Decimal is {0:>0x}".format(15))

计算所有的二进制no直到16::

for i in range(17):
print("{0:>2}: binary is {0:>08b}".format(i))

计算十六进制小数到17

 for i in range(17):
print("{0:>2}: Hexa Decimal is {0:>0x}".format(i))
##as 2 digit is enogh for hexa decimal representation of a number

我发现了一种使用矩阵运算将十进制转换为二进制的方法。

import numpy as np
E_mat = np.tile(E,[1,M])
M_order = pow(2,(M-1-np.array(range(M)))).T
bindata = np.remainder(np.floor(E_mat /M_order).astype(np.int),2)

E是输入十进制数据,M是二进制顺序。bindata是输出二进制数据,其格式为1乘M二进制矩阵。

你可以这样做:

bin(10)[2:]

或:

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

这是针对python 3的,它保留了前导零!

print(format(0, '08b'))

在此处输入图片描述

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

对于我们这些需要将有符号整数(范围-2**(digits-1)到2**(digits-1)-1)转换为2的补码二进制字符串的人来说,这是有效的:

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'

这是我的答案,它工作得很好!

def binary(value) :
binary_value = ''
while value !=1  :
binary_value += str(value%2)
value = value//2
return '1'+binary_value[::-1]

numpy.binary_repr(num, width=None)

上面留档链接中的示例:

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

当输入数字为负数并指定宽度时,返回两个的补码:

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

我觉得Martijn Pieter的评论值得强调作为答案:

binary_string = format(value, '0{}b'.format(width))

对我来说,它既清晰又多才多艺。

由于前面的答案大多使用格式(), 这是一个f-string实现。

integer = 7
bit_count = 5
print(f'{integer:0{bit_count}b}')

输出:

00111

为了方便起见,这里是格式化字符串文字的python文档链接:https://docs.python.org/3/reference/lexical_analysis.html#f-strings

这是一个(调试过的)程序,它使用divmod来构造一个二进制列表:

方案

while True:
indecimal_str = input('Enter positive(decimal) integer: ')
if indecimal_str == '':
raise SystemExit
indecimal_save = int(indecimal_str)
if indecimal_save < 1:
print('Rejecting input, try again')
print()
continue
indecimal = int(indecimal_str)
exbin = []
print(indecimal, '<->', exbin)
while True:
if indecimal == 0:
print('Conversion:', indecimal_save, '=', "".join(exbin))
print()
break
indecimal, r = divmod(indecimal, 2)
if r == 0:
exbin.insert(0, '0')
else:
exbin.insert(0, '1')
print(indecimal, '<->', exbin)

产出

Enter positive(decimal) integer: 8
8 <-> []
4 <-> ['0']
2 <-> ['0', '0']
1 <-> ['0', '0', '0']
0 <-> ['1', '0', '0', '0']
Conversion: 8 = 1000


Enter positive(decimal) integer: 63
63 <-> []
31 <-> ['1']
15 <-> ['1', '1']
7 <-> ['1', '1', '1']
3 <-> ['1', '1', '1', '1']
1 <-> ['1', '1', '1', '1', '1']
0 <-> ['1', '1', '1', '1', '1', '1']
Conversion: 63 = 111111


Enter positive(decimal) integer: 409
409 <-> []
204 <-> ['1']
102 <-> ['0', '1']
51 <-> ['0', '0', '1']
25 <-> ['1', '0', '0', '1']
12 <-> ['1', '1', '0', '0', '1']
6 <-> ['0', '1', '1', '0', '0', '1']
3 <-> ['0', '0', '1', '1', '0', '0', '1']
1 <-> ['1', '0', '0', '1', '1', '0', '0', '1']
0 <-> ['1', '1', '0', '0', '1', '1', '0', '0', '1']
Conversion: 409 = 110011001

接受的答案没有解决负数,我将介绍。 除了上面的答案,您还可以使用bin十六进制函数。在相反的方向,使用二进制表示法:

>>> 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将Two的补码二进制值转换为python整数:

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

但是我不知道有什么简单的方法可以用内置函数做相反的事情。

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

我很惊讶没有提到使用Python 3.6及更高版本支持的格式化字符串来完成此操作的好方法。TLDR:

>>> number = 1
>>> f'0b{number:08b}'
'0b00000001'

更长的故事

这是Python 3.6提供的格式化字符串的功能:

>>> x, y, z = 1, 2, 3
>>> f'{x} {y} {2*z}'
'1 2 6'

您也可以请求二进制:

>>> f'{z:b}'
'11'

指定宽度:

>>> f'{z:8b}'
'      11'

请求零填充:

f'{z:08b}'
'00000011'

并添加公共前缀来表示二进制数:

>>> f'0b{z:08b}'
'0b00000011'

你也可以让Python为你添加前缀,但我不喜欢上面的版本,因为你必须考虑前缀的宽度:

>>> f'{z:#010b}'
'0b00000011'

更多信息请见格式化字符串文字格式规范小语言的官方留档。

Python 3.6添加了一种新的字符串格式化方法,称为格式化字符串文字或“f字符串”。 示例:

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

输出将是“你好,鲍勃,你的号码是00001010!”

关于这个问题的讨论可以在这里找到-这里