492

I'd simply like to convert a base-2 binary number string into an int, something like this:

>>> '11111111'.fromBinaryToInt()
255

Is there a way to do this in Python?

wtanaka.com
  • 419
  • 4
  • 11
Naftuli Kay
  • 87,710
  • 93
  • 269
  • 411
  • 5
    While it doesn't really matter, a binary string typically means a string containing actual binary data (a byte contains two hexadecimal digits, ie "\x00" is a null byte). – trevorKirkby May 03 '14 at 18:25
  • Just to mention it: the other way around it goes like '{0:08b}'.format(65) (or f'{65:08b}'). – TNT Oct 10 '20 at 12:58
  • 2
    it is uint rather than int. Please change the title – Gideon Kogan Dec 25 '22 at 21:09

10 Answers10

918

You use the built-in int() function, and pass it the base of the input number, i.e. 2 for a binary number:

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

Here is documentation for Python 2, and for Python 3.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 93
    In case someone is looking for the opposite: `bin(255)` -> `'0b11111111'`. See [this answer](http://stackoverflow.com/a/699892/638546) for additional details. – Akseli Palén Mar 13 '13 at 23:29
  • 9
    It should be noted that this only works for unsigned binary integers. For signed integers, the conversion options are a mess. – Fake Name Nov 01 '14 at 13:30
  • 5
    How to do this in python 3? – Saras Arya Feb 27 '15 at 05:45
  • 1
    And note that in an interactive REPL session (as suggested by the `>>>` prompt), you don't need to use `print` at all. The OP's hypothetical example didn't. So it really should be identical in Python 2 and 3. – John Y Jul 12 '16 at 22:36
  • 1
    To add to @AkseliPalén comment: `bin (255)[2:]` – Timo Sep 20 '20 at 20:10
51

Just type 0b11111111 in python interactive interface:

>>> 0b11111111
    255
lengxuehx
  • 1,500
  • 1
  • 18
  • 25
36

Another way to do this is by using the bitstring module:

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

Note that the unsigned integer (uint) is different from the signed integer (int):

>>> b.int
-1

Your question is really asking for the unsigned integer representation; this is an important distinction.

The bitstring module isn't a requirement, but it has lots of performant methods for turning input into and from bits into other forms, as well as manipulating them.

Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
10

Using int with base is the right way to go. I used to do this before I found int takes base also. It is basically a reduce applied on a list comprehension of the primitive way of converting binary to decimal ( e.g. 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
  • 1,198
  • 14
  • 21
5

If you wanna know what is happening behind the scene, then here you go.

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')
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Mohammad Mahjoub
  • 417
  • 4
  • 12
5

For large matrix (10**5 rows and up) it is better to use a vectorized matmult. Pass in all rows and cols in one shot. It is extremely fast. There is no looping in python here. I originally designed it for converting many binary columns like 0/1 for like 10 different genre columns in MovieLens into a single integer for each example row.

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
  • 1,534
  • 17
  • 25
5

Here's another concise way to do it not mentioned in any of the above answers:

>>> eval('0b' + '11111111')
255

Admittedly, it's probably not very fast, and it's a very very bad idea if the string is coming from something you don't have control over that could be malicious (such as user input), but for completeness' sake, it does work.

The Zach Man
  • 738
  • 5
  • 15
  • This might be fine for hard-coded constants, but there are multiple reasons why using `eval` is considered bad practice, especially when you would try to parse user input. See this post, for example: https://stackoverflow.com/questions/1832940/why-is-using-eval-a-bad-practice – larsschwegmann Dec 03 '21 at 08:47
  • I love this answer, really creative – collinsmarra Dec 17 '21 at 04:09
4

A recursive Python implementation:

def int2bin(n):
    return int2bin(n >> 1) + [n & 1] if n > 1 else [1] 
Pang
  • 9,564
  • 146
  • 81
  • 122
4

If you are using python3.6 or later you can use f-string to do the conversion:

Binary to decimal:

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

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

binary to octal hexa and etc.

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

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

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

Pay attention to 2 piece of information separated by colon.

In this way, you can convert between {binary, octal, hexadecimal, decimal} to {binary, octal, hexadecimal, decimal} by changing right side of colon[:]

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

Try changing left side of colon to have octal/hexadecimal/decimal.

Robert Ranjan
  • 1,538
  • 3
  • 19
  • 17
4

For the record to go back and forth in basic python3:

a = 10
bin(a)
# '0b1010'

int(bin(a), 2)
# 10
eval(bin(a))
# 10
ClementWalter
  • 4,814
  • 1
  • 32
  • 54