Konwertuj ciąg liczby binarnej base-2 na liczbę int

306

Chciałbym po prostu przekonwertować ciąg liczby binarnej base-2 na liczbę całkowitą, mniej więcej tak:

>>> '11111111'.fromBinaryToInt()
255

Czy jest na to sposób w Pythonie?

Naftuli Kay
źródło
3
Chociaż tak naprawdę to nie ma znaczenia, ciąg binarny zwykle oznacza ciąg zawierający rzeczywiste dane binarne (bajt zawiera dwie cyfry szesnastkowe, tzn. „\ X00” to bajt zerowy).
trevorKirkby

Odpowiedzi:

563

Korzystasz z wbudowanej intfunkcji i przekazujesz jej podstawę liczby wejściowej, tj. 2Liczby binarnej:

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

Oto dokumentacja dla python2 i python3 .

rozwijać
źródło
61
W przypadku, gdy ktoś szuka czegoś przeciwnego: bin(255)-> '0b11111111'. Zobacz tę odpowiedź, aby uzyskać dodatkowe informacje.
Akseli Palén
7
Należy zauważyć, że działa to tylko w przypadku binarnych liczb całkowitych bez znaku. W przypadku liczb całkowitych ze znakiem opcje konwersji są bałaganem.
Fałszywe imię
2
Jak to zrobić w Pythonie 3?
Saras Arya
2
@SarasArya Jest bardzo podobny! :) Zaktualizowałem, patrz wyżej.
odpręż się
1
I pamiętaj, że w interaktywnej sesji REPL (zgodnie z sugestią >>>) nie musisz jej wcale używać print. Hipotetyczny przykład OP nie. Więc tak naprawdę powinno być identycznie w Pythonie 2 i 3.
John Y
37

Po prostu wpisz 0b11111111 w interaktywnym interfejsie Pythona:

>>> 0b11111111
    255
lengxuehx
źródło
28

Innym sposobem na to jest użycie bitstringmodułu:

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

Zauważ, że liczba całkowita bez znaku różni się od liczby całkowitej ze znakiem:

>>> b.int
-1

bitstringModuł nie jest wymogiem, ale ma wiele wydajnych metod odwracając wejście do iz bitów w innych formach, a także manipulowania nimi.

Alex Reynolds
źródło
8

Używanie int z bazą jest właściwą drogą. Robiłem to, zanim odkryłem, że int bierze również bazę. Zasadniczo jest to redukcja zastosowana do zrozumienia listy pierwotnego sposobu konwersji binarnej na dziesiętną (np. 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))])
Saurabh Hirani
źródło
4
Zamiast definiować add = lambda x, y: x + y, int.__add__można podać redukcję. Egreduce(int.__add__, ...)
Jordan Jambazov
4

Jeśli chcesz wiedzieć, co dzieje się za sceną, to proszę bardzo.

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')
Mohammad Mahjoub
źródło
3

Rekurencyjna implementacja Pythona:

def int2bin(n):
    return int2bin(n >> 1) + [n & 1] if n > 1 else [1] 
Ludovic Trottier
źródło
1

Jeśli używasz Python3.6 lub nowszego, możesz użyć ciągu f do wykonania konwersji:

Binarny na dziesiętny:

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

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

binarny na ósemkowy hexa itp.

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

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

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

Zwróć uwagę na 2 informacje oddzielone dwukropkiem.

W ten sposób możesz konwertować między {binarny, ósemkowy, szesnastkowy, dziesiętny} na {binarny, ósemkowy, szesnastkowy, dziesiętny}, zmieniając prawą stronę dwukropka [:]

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

Spróbuj zmienić lewą stronę jelita grubego na ósemkową / szesnastkową / dziesiętną.

Robert Ranjan
źródło
0

W przypadku dużej matrycy (10 ** 5 rzędów i więcej) lepiej jest użyć wektoryzowanego matmulta. Podaj we wszystkich rzędach i kolkach jednym strzałem. To jest bardzo szybkie. W Pythonie nie ma pętli. Pierwotnie zaprojektowałem go do konwertowania wielu kolumn binarnych, takich jak 0/1, na 10 kolumn gatunku w MovieLens na jedną liczbę całkowitą dla każdego przykładowego wiersza.

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
Geoffrey Anderson
źródło