Python int to binary string?

Viewed 1058426

Are there any canned Python methods to convert an Integer (or Long) into a binary string in Python?

There are a myriad of dec2bin() functions out on Google... But I was hoping I could use a built-in function / library.

36 Answers

If you're looking for bin() as an equivalent to hex(), it was added in python 2.6.

Example:

>>> bin(10)
'0b1010'

Python actually does have something already built in for this, the ability to do operations such as '{0:b}'.format(42), which will give you the bit pattern (in a string) for 42, or 101010.


For a more general philosophy, no language or library will give its user base everything that they desire. If you're working in an environment that doesn't provide exactly what you need, you should be collecting snippets of code as you develop to ensure you never have to write the same thing twice. Such as, for example, the pseudo-code:

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

which will construct your binary string based on the decimal value. Just keep in mind that's a generic bit of pseudo-code which may not be the most efficient way of doing it though, with the iterations you seem to be proposing, it won't make much difference. It's really just meant as a guideline on how it could be done.

The general idea is to use code from (in order of preference):

  • the language or built-in libraries.
  • third-party libraries with suitable licenses.
  • your own collection.
  • something new you need to write (and save in your own collection for later).

I am surprised there is no mention of a nice way to accomplish this using formatting strings that are supported in Python 3.6 and higher. TLDR:

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

Longer story

This is functionality of formatting strings available from Python 3.6:

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

You can request binary as well:

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

Specify the width:

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

Request zero padding:

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

And add common prefix to signify binary number:

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

You can also let Python add the prefix for you but I do not like it so much as the version above because you have to take the prefix into width consideration:

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

More info is available in official documentation on Formatted string literals and Format Specification Mini-Language.

This is for python 3 and it keeps the leading zeros !

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

enter image description here

For those of us who need to convert signed integers (range -2**(digits-1) to 2**(digits-1)-1) to 2's complement binary strings, this works:

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

This produces:

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

you can do like that :

bin(10)[2:]

or :

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

The accepted answer didn't address negative numbers, which I'll cover. In addition to the answers above, you can also just use the bin and hex functions. And in the opposite direction, use binary notation:

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

But with negative numbers, things get a bit more complicated. The question doesn't specify how you want to handle negative numbers.

Python just adds a negative sign so the result for -37 would be this:

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

In computer/hardware binary data, negative signs don't exist. All we have is 1's and 0's. So if you're reading or producing binary streams of data to be processed by other software/hardware, you need to first know the notation being used.

One notation is sign-magnitude notation, where the first bit represents the negative sign, and the rest is the actual value. In that case, -37 would be 0b1100101 and 37 would be 0b0100101. This looks like what python produces, but just add a 0 or 1 in front for positive / negative numbers.

More common is Two's complement notation, which seems more complicated and the result is very different from python's string formatting. You can read the details in the link, but with an 8bit signed integer -37 would be 0b11011011 and 37 would be 0b00100101.

Python has no easy way to produce these binary representations. You can use numpy to turn Two's complement binary values into python integers:

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

But I don't know an easy way to do the opposite with builtin functions. The bitstring package can help though.

>>> 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 added a new string formatting approach called formatted string literals or “f-strings”. Example:

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

Output will be 'Hello, Bob, your number is 00001010!'

A discussion of this question can be found here - Here

Unless I'm misunderstanding what you mean by binary string I think the module you are looking for is struct

numpy.binary_repr(num, width=None)

Examples from the documentation link above:

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

I found a method using matrix operation to convert decimal to binary.

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)

Eis input decimal data,M is the binary orders. bindata is output binary data, which is in a format of 1 by M binary matrix.

I feel Martijn Pieter's comment deserves to be highlighted as an answer:

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

To me is is both clear and versatile.

This is my answer it works well..!

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

Here is a (debugged) program that uses divmod to construct a binary list:

Program

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)

Output

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
Related