846

How do I convert an integer into a binary string in Python?

37   →   '100101'
Mateen Ulhaq's user avatar
Mateen Ulhaq
27.9k21 gold badges121 silver badges155 bronze badges
askedMar 31, 2009 at 3:04
Nate's user avatar
1
  • For the opposite take, for a pure string processing algorithm, seethis.CommentedMar 15, 2020 at 17:05

36 Answers36

1111

Python's string format method can take a format spec.

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

Format spec docs for Python 2

Format spec docs for Python 3

OrenIshShalom's user avatar
OrenIshShalom
7,3109 gold badges54 silver badges141 bronze badges
answeredMar 31, 2009 at 3:17
Tung Nguyen's user avatar
Sign up to request clarification or add additional context in comments.

6 Comments

str.format() just to format one value is overkill. Go straight to theformat() function:format(n, 'b'). There is no need to parse out the placeholder and match it to an argument, go straight for the value formatting operation itself. Only usestr.format() if you need to place the formatted result in a longer string (e.g. use it as a template).
@mike: Or use the formatting specification. Add the number of digits with a leading0 to the formatting string:format(10, '016b') formats to 16 digits with leading zeros.
typically one would use 4/8/... bit representation:"{:08b}".format(37)
f"{37:b}" in Python3.7 or later.
There is an issue here with negative numbers. @nate didn't clearly specify what the desired output was in that case, but purely in binary numbers, negative signs don't exist. So the most significant bit is generally used for the negative sign. Assuming we use 8bit integers, -37 would be0b10100101. But with an unsigned integer, that value would be 165. So it is not this simple. The answer should reflect this.
|
671

If you're looking forbin() as an equivalent tohex(), it was added in python 2.6.

Example:

>>> bin(10)'0b1010'
Akseli Palén's user avatar
Akseli Palén
28.2k10 gold badges69 silver badges76 bronze badges
answeredMar 31, 2009 at 3:17
John Fouhy's user avatar

5 Comments

Note also that it's faster to dostr(bin(i))[2:] (0.369s for 1000000ops) than"{0:b}".format(i) (0.721s for 1000000ops)
@mVChr if someone's converting numbers into an ASCII binary representation, I really hope speed doesn't matter.
@mVChr:str.format() is the wrong tool anyway, you would useformat(i, 'b') instead. Take into account that that also gives you padding and alignment options though;format(i, '016b') to format to a 16-bit zero-padded binary number. To do the same withbin() you'd have to add astr.zfill() call:bin(i)[2:].zfill(16) (no need to callstr()!).format()'s readability and flexibility (dynamic formatting is much harder withbin()) are great tradeoffs, don't optimise for performance unless you have to, until then optimise for maintainability.
What does [2:] mean?
Of course, with python 3.6+ you can now usef"{37:b}".
75

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 onFormatted string literals andFormat Specification Mini-Language.

answeredAug 19, 2020 at 10:37
Roman Pavelka's user avatar

4 Comments

To add underscores:f'0b{z:09_b}' =>'0b0000_0011'
what about endianness? can one change it?
This is out of scope of this question. The most significant first is the canonical way how to write number in positional system regardless of system endianness which is just an implementation detail. You can dof'{z:08b}'[::-1] to achieve the least significant byte first ordering, however this will IMHO in most cases cause just confusion...
f strings also appear to be faster than format().timeit.timeit( 'f"{2:08b}"', number=10000000 ) => 1.1823169720000806 versustimeit.timeit( 'format(2,"08b")', number=10000000 ) => 1.3507722609992925
72

Python actuallydoes 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) for42, or101010.


For a more general philosophy, no language or library will give its user baseeverything 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 themost 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).
answeredMar 31, 2009 at 3:25
paxdiablo's user avatar

6 Comments

Some good advise in this answer. Only too bad that the code is needlessly slow. You propose an O(N^2) algo where an O(N) would do. The problematic part is in thes = "1" + s ands = "0" + s lines. Each makes an unnecessary copy of s. You should reverse the string just before you return it instead.
@Andreas, what Iproposed was to use'{0:b}'.format(42), the slow method was simply an example of how to do it generically, which may or may not be O(n^2) depending on the actual language used. It only looks like Python since Python is an ideal pseudo-code language so I'll change that to make it clear.
Actually it would be a pretty esoteric language wheres = "1" + s wasn't O(N) whens is a string type. Maybe a language where all strings are stored backwards or each char is a node in a linked list? For any typical language a string is basically an array of chars. In that case prefixing a string requires that a copy is made, how else are you going to put the character before the other characters?
I can easily envisage a string type that consists of a block of memory where the string is right-justified within that block, and an offset to its starting character. To prefix a character, you would then simply reduce the offset and store the character there. Yes, thatwould be esoteric but it makes little sense to me to argue about possible real-world issues with a bit of pseudo-code,especially since you're not likely to have more than a few dozen bits/iterations. Even the much maligned bubble sort is adequate if your data size is small :-) In any case, I'll add a note about efficiency.
Sure, if efficiency is important you'd probably not choose python to begin with. Still In my experience it happens quite often that code that was written naïvely using an O(N²) algo and tested with a small data set quickly gets used with a much larger data set because "it seems to work". Then all of a sudden you have code that takes hours to run that when fixed may take only seconds. O(N²) algos are insidious because they seem to work for a while but when your data scales they don't and by then the guy who wrote them has quit and no one knows why things take forever.
|
65

If you want a textual representation without the 0b-prefix, you could use this:

get_bin = lambda x: format(x, 'b')print(get_bin(3))>>> '11'print(get_bin(-3))>>> '-11'

When you want a n-bit representation:

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

Alternatively, if you prefer having a function:

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)
answeredFeb 12, 2014 at 15:33
Martin Thoma's user avatar

9 Comments

Or just useformat(integer, 'b').bin() is a debugging tool, specifically aimed at producing thePython binary integer literal syntax,format() is meant to produce specific formats.
@MartijnPieters Thank you very much for mentioning it. I've adjusted my solutution. How do you know thatbin() is a debugging tool aimed at producing the Python binary integer literal syntax? I couldn't find that in the documentation.
From the documentation:The result is a valid Python expression. It's aim is to produce a Python expression, not to produce end-user representations. The same applies tooct() andhex().
More alternatives: If you are going to make the width dynamic, instead ofstr.zfill() you could usestr.format() orformat() with a dynamic second argument:'{0:0{1}b}'.format(x, n) orformat(b, '0{}b'.format(n)).
@MartijnPieters Wow, thank you very much for this input! I didn't know that this was possible with format. However, I think my current answer withzfill is easier to read and understand than the dynamic second argument, so I'll keep that.
|
44

As a reference:

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

This function can convert a positive integer as large as18446744073709551615, represented as string'1111111111111111111111111111111111111111111111111111111111111111'.

It can be modified to serve a much larger integer, though it may not be as handy as"{0:b}".format() orbin().

answeredDec 17, 2013 at 19:39
kctong529's user avatar

2 Comments

@GarethDavidson which version is this? Having this stated explicitly might be of greater future use when googling it.
It was version 2.7 I think. I doubt it'd work in 3.x
39

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

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

enter image description here

answeredNov 13, 2018 at 7:04
grepit's user avatar

3 Comments

I appreciate the simple answer.
Thank you so much. It's a shame this answer is so far down.
Excellent! This is what I'm looking for.
30

A simple way to do that is to use string format, see thispage.

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

And if you want to have a fixed length of the binary string, you can use this:

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

If two's complement is required, then the following line can be used:

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

where n is the width of the binary string.

answeredJan 19, 2016 at 21:29
Xiang's user avatar

Comments

17

one-liner withlambda:

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

test:

>>> binary(5)'101'



EDIT:

but then :(

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

in compare to

t1 = time()for i in range(1000000):    '{0:b}'.format(i)t2 = time()print(t2 - t1)# 0.68017411232
answeredJun 15, 2015 at 2:12
Aziz Alto's user avatar

2 Comments

that returns '' for 0 though. Wouldn't the normal representation for 0 be '0'?
if you wanna see that 0 :), you can replace'' with'0', but it will add a leading 0 for any number.
17

As the preceding answers mostly used format(),here is an f-string implementation.

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

Output:

00111

For convenience here is the python docs link for formatted string literals:https://docs.python.org/3/reference/lexical_analysis.html#f-strings.

answeredJun 7, 2019 at 20:41
John Forbes's user avatar

Comments

12

Summary of alternatives:

n=42assert  "-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.

Contributors includeJohn Fouhy,Tung Nguyen,mVChr,Martin Thoma. and Martijn Pieters.

1 Comment

str.format() just to format one value is overkill. Go straight to theformat() function:format(n, 'b'). No need to parse out the placeholder and match it to an argument that way.
11
>>> format(123, 'b')'1111011'
answeredDec 7, 2018 at 15:17
Sandu Ursu's user avatar

Comments

10

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'
Daniel's user avatar
Daniel
3,6271 gold badge18 silver badges40 bronze badges
answeredDec 18, 2018 at 19:32
DeanM's user avatar

Comments

8

you can do like that :

bin(10)[2:]

or :

f = str(bin(10))c = []c.append("".join(map(int, f[2:])))print c
answeredJun 21, 2018 at 22:19
Skiller Dz's user avatar

1 Comment

bin(n).replace("0b", "")
7

Using numpy pack/unpackbits, they are your best friends.

Examples-------->>> a = np.array([[2], [7], [23]], dtype=np.uint8)>>> aarray([[ 2],       [ 7],       [23]], dtype=uint8)>>> b = np.unpackbits(a, axis=1)>>> barray([[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)
answeredAug 27, 2015 at 3:39
pitfall's user avatar

2 Comments

The question is about astring representation. Still, this happened to be just what I was looking for without going via string first! :)
Thedoco says: Unpacks elements of auint8 array into a binary-valued output array. So good for values up to 255.
7

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

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

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 issign-magnitude notation, where the first bit represents the negative sign, and the rest is the actual value. In that case, -37 would be0b1100101 and 37 would be0b0100101. This looks like what python produces, but just add a 0 or 1 in front for positive / negative numbers.

More common isTwo'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 be0b11011011 and 37 would be0b00100101.

Python has no easy way to produce these binary representations. You can usenumpy 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. Thebitstring package can help though.

>>> from bitstring import BitArray>>> arr = BitArray(int=-37, length=8)>>> arr.uint219>>> arr.int-37>>> arr.bin'11011011'>>> BitArray(bin='11011011').int-37>>> BitArray(bin='11011011').uint219
answeredJun 26, 2020 at 2:49
Dolf Andringa's user avatar

Comments

6

Python 3.6 added a new string formatting approach called formatted string literals or “f-strings”.Example:

name = 'Bob'number = 42f"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

answeredOct 27, 2020 at 13:47
Tim  Uzlov's user avatar

Comments

5

Yet another solution with another algorithm, by using bitwise operators.

def int2bin(val):    res=''    while val>0:        res += str(val&1)        val=val>>1     # val=val/2     return res[::-1]   # reverse the string

A faster version without reversing the string.

def int2bin(val):   res=''   while val>0:       res = chr((val&1) + 0x30) + res       val=val>>1       return res
answeredOct 18, 2014 at 22:45
Reza Abtin's user avatar

1 Comment

The second version is definitely not faster as you end up with something like an O(N^2) algorithm instead of a O(N). I've seen things like this kill an application (performance-wise) because the developer thought doing an extra pass at the end was slower than doing some extra stuff in the first loop. Once fixed brought the running time down from days to seconds.
5

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'
answeredApr 30, 2019 at 9:28
Tom Hale's user avatar

Comments

4
n=input()print(bin(n).replace("0b", ""))
Mihai Maruseac's user avatar
Mihai Maruseac
21.5k7 gold badges61 silver badges110 bronze badges
answeredNov 29, 2014 at 12:45
dblaze's user avatar

Comments

4
def binary(decimal) :    otherBase = ""    while decimal != 0 :        otherBase  =  str(decimal % 2) + otherBase        decimal    //=  2    return otherBaseprint binary(10)

output:

1010

Martin Tournoij's user avatar
Martin Tournoij
28k24 gold badges110 silver badges158 bronze badges
answeredOct 4, 2014 at 2:07
mukundan's user avatar

Comments

3

Here is the code I've just implemented. This is not amethod but you can use it as aready-to-use function!

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
answeredMar 15, 2014 at 13:18
quents's user avatar

Comments

3

Calculator with all neccessary functions for DEC,BIN,HEX:(made and tested with Python 3.5)

You can change the input test numbers and get the converted ones.

# CONVERTER: DEC / BIN / HEXdef dec2bin(d):    # dec -> bin    b = bin(d)    return bdef dec2hex(d):    # dec -> hex    h = hex(d)    return hdef bin2dec(b):    # bin -> dec    bin_numb="{0:b}".format(b)    d = eval(bin_numb)    return d,bin_numbdef bin2hex(b):    # bin -> hex    h = hex(b)    return hdef hex2dec(h):    # hex -> dec    d = int(h)    return ddef hex2bin(h):    # hex -> bin    b = bin(h)    return b## TESTING NUMBERSnumb_dec = 99numb_bin = 0b0111 numb_hex = 0xFF## CALCULATIONSres_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)## PRINTINGprint('------- 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')
answeredAug 29, 2017 at 8:11
HKC72's user avatar

Comments

3

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

Sebastián Palma's user avatar
Sebastián Palma
33.6k6 gold badges45 silver badges65 bronze badges
answeredMar 31, 2009 at 3:08
Van Gale's user avatar

2 Comments

python def binary_int32(x): return ''.join(["{:0>8b}".format(b) for b in struct.pack('>i', x)])
2

Somewhat similar solution

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
answeredApr 26, 2014 at 12:42
Chandler's user avatar

Comments

2

here is simple solution using the divmod() fucntion which returns the reminder and the result of a division without the fraction.

def dectobin(number):    bin = ''    while (number >= 1):        number, rem = divmod(number, 2)        bin = bin + str(rem)    return bin
answeredJul 18, 2014 at 14:35
user210021's user avatar

1 Comment

Needs debugging. Callingdectobin(10) resulted in '0101'
2

Here's yet another way using regular math, no loops, only recursion. (Trivial case 0 returns nothing).

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']
answeredOct 23, 2015 at 12:53
ergonaut's user avatar

1 Comment

It's weird that0 returns'', it should be'0'...
2

To calculate binary of numbers:

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

To calculate the Hexa decimal of a number:

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

To Calculate all the binary no till 16::

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

To calculate Hexa decimal no till 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
answeredApr 3, 2018 at 16:16
Rajesh Kumar Sahoo's user avatar

Comments

1
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")
Tom Wyllie's user avatar
Tom Wyllie
2,08215 silver badges16 bronze badges
answeredApr 27, 2017 at 8:53
Advay168's user avatar

1 Comment

Might want to add some explanation to what you did there.
1

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

import numpy as npE_mat = np.tile(E,[1,M])M_order = pow(2,(M-1-np.array(range(M)))).Tbindata = 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.

answeredMay 29, 2018 at 20:22
Galle He's user avatar

Comments

Protected question. To answer this question, you need to have at least 10 reputation on this site (not counting theassociation bonus). The reputation requirement helps protect this question from spam and non-answer activity.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.