Chuyển đổi chuỗi số nhị phân cơ sở-2 thành int


306

Tôi chỉ đơn giản muốn chuyển đổi một chuỗi số nhị phân cơ sở 2 thành một int, đại loại như thế này:

>>> '11111111'.fromBinaryToInt()
255

Có cách nào để làm điều này trong Python không?


3
Mặc dù nó không thực sự quan trọng, một chuỗi nhị phân thường có nghĩa là một chuỗi chứa dữ liệu nhị phân thực tế (một byte chứa hai chữ số thập lục phân, tức là "\ x00" là một byte rỗng).
trevorKirkby

Câu trả lời:


563

Bạn sử dụng hàm dựng sẵn intvà truyền cho nó cơ sở của số đầu vào, tức là 2cho số nhị phân:

>>> int('11111111', 2)
255

Đây là tài liệu cho python2 và cho python3 .


61
Trong trường hợp ai đó đang tìm kiếm điều ngược lại: bin(255)-> '0b11111111'. Xem câu trả lời này để biết thêm chi tiết.
Akseli Palén

7
Cần lưu ý rằng điều này chỉ hoạt động cho số nguyên nhị phân không dấu. Đối với số nguyên đã ký, các tùy chọn chuyển đổi là một mớ hỗn độn.
Tên giả

2
Làm thế nào để làm điều này trong python 3?
Saras Arya

2
@SaraArya Nó rất giống nhau! :) Tôi cập nhật, xem ở trên.
thư giãn

1
Và lưu ý rằng trong phiên REPL tương tác (như được gợi ý bởi >>>lời nhắc), bạn hoàn toàn không cần sử dụng print. Ví dụ giả thuyết của OP là không. Vì vậy, nó thực sự phải giống hệt nhau trong Python 2 và 3.
John Y

37

Chỉ cần gõ 0b11111111 trong giao diện tương tác python:

>>> 0b11111111
    255

28

Một cách khác để làm điều này là bằng cách sử dụng bitstringmô-đun:

>>> from bitstring import BitArray
>>> b = BitArray(bin='11111111')
>>> b.uint
255

Lưu ý rằng số nguyên không dấu khác với số nguyên đã ký:

>>> b.int
-1

Các bitstringmô-đun không phải là một yêu cầu, nhưng nó có rất nhiều phương pháp performant cho biến đầu vào và từ bit thành các dạng khác, cũng như thao tác chúng.


8

Sử dụng int với cơ sở là cách đúng đắn để đi. Tôi đã từng làm điều này trước khi tôi tìm thấy int mất cơ sở. Về cơ bản, đây là một mức giảm áp dụng cho việc hiểu danh sách về cách nguyên thủy chuyển đổi nhị phân thành thập phân (ví dụ 110 = 2 ** 0 * 0 + 2 ** 1 * 1 + 2 ** 2 * 1)

add = lambda x,y : x + y
reduce(add, [int(x) * 2 ** y for x, y in zip(list(binstr), range(len(binstr) - 1, -1, -1))])

4
Thay vì xác định add = lambda x, y: x + y, int.__add__có thể được cung cấp để giảm. Ví dụ:reduce(int.__add__, ...)
Jordan Jambazov

4

Nếu bạn muốn biết những gì đang xảy ra đằng sau hậu trường, thì ở đây bạn đi.

class Binary():
def __init__(self, binNumber):
    self._binNumber = binNumber
    self._binNumber = self._binNumber[::-1]
    self._binNumber = list(self._binNumber)
    self._x = [1]
    self._count = 1
    self._change = 2
    self._amount = 0
    print(self._ToNumber(self._binNumber))
def _ToNumber(self, number):
    self._number = number
    for i in range (1, len (self._number)):
        self._total = self._count * self._change
        self._count = self._total
        self._x.append(self._count)
    self._deep = zip(self._number, self._x)
    for self._k, self._v in self._deep:
        if self._k == '1':
            self._amount += self._v
    return self._amount
mo = Binary('101111110')

3

Một triển khai Python đệ quy:

def int2bin(n):
    return int2bin(n >> 1) + [n & 1] if n > 1 else [1] 

1

Nếu bạn đang sử dụng python3.6 trở lên, bạn có thể sử dụng chuỗi f để thực hiện chuyển đổi:

Nhị phân đến thập phân:

>>> print(f'{0b1011010:#0}')
90

>>> bin_2_decimal = int(f'{0b1011010:#0}')
>>> bin_2_decimal
90

nhị phân để bát phân hexa và vv

>>> f'{0b1011010:#o}'
'0o132'  # octal

>>> f'{0b1011010:#x}'
'0x5a'   # hexadecimal

>>> f'{0b1011010:#0}'
'90'     # decimal

Hãy chú ý đến 2 mẩu thông tin được phân tách bằng dấu hai chấm.

Theo cách này, bạn có thể chuyển đổi giữa {binary, bát phân, thập lục phân, thập phân} thành {nhị phân, bát phân, thập lục phân, thập phân} bằng cách thay đổi bên phải của dấu hai chấm [:]

:#b -> converts to binary
:#o -> converts to octal
:#x -> converts to hexadecimal 
:#0 -> converts to decimal as above example

Hãy thử thay đổi bên trái của dấu hai chấm để có số bát phân / thập lục phân / thập phân.


0

Đối với ma trận lớn (10 ** 5 hàng trở lên), tốt hơn là sử dụng matmult được vector hóa. Vượt qua tất cả các hàng và cols trong một shot. Nó cực kỳ nhanh. Không có vòng lặp trong python ở đây. Ban đầu tôi đã thiết kế nó để chuyển đổi nhiều cột nhị phân như 0/1 cho 10 cột thể loại khác nhau trong MovieLens thành một số nguyên duy nhất cho mỗi hàng mẫu.

def BitsToIntAFast(bits):
  m,n = bits.shape
  a = 2**np.arange(n)[::-1]  # -1 reverses array of powers of 2 of same length as bits
  return bits @ a
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.