Python bin() Function: Convert Integers to Binary

Need the bits behind a number? The Python bin() function takes an integer and gives back its binary form as a string that starts with 0b. Negative numbers get a minus sign in front, and floats raise a TypeError:

bin(10)      # '0b1010'
bin(-10)     # '-0b1010'
f"{10:08b}"  # '00001010' (no prefix, padded)

Every output below comes from Command Prompt runs on Python 3.12.5, copied as printed.

In this tutorial, we’ll look at what bin() returns, how to drop the prefix and pad the result, how negatives behave, and which inputs fail.

What does the Python bin() function return?

bin(x) always returns a str. The input can be any integer, including hex or octal literals and True, since a bool is a subclass of int:

for n in [10, 255, 0, -10, True]:
    print(f"bin({n!r:>5}) -> {bin(n)}")

print(type(bin(10)))
print(bin(0x1F), bin(0o17))      # hex and octal literals are just ints

Output:

bin(   10) -> 0b1010
bin(  255) -> 0b11111111
bin(    0) -> 0b0
bin(  -10) -> -0b1010
bin( True) -> 0b1
<class 'str'>
0b11111 0b1111
Command Prompt output of Python bin() on 10, 255, 0, -10 and True, plus hex and octal literals
Each integer comes back as a 0b string, -10 keeps its minus sign, and True prints as 0b1.

Because the result is text, you can slice it, count its 1 characters, or print it. Going the other direction, from a number you typed to its bits, is covered step by step in converting decimal numbers to binary in Python.

Remove the 0b prefix and pad bin() output

The 0b prefix is handy for reading but gets in the way when you need fixed-width bits. Here are the usual fixes side by side:

n = 10
print(bin(n)[2:])                 # slice off 0b
print(bin(n).removeprefix("0b"))  # clearer, Python 3.9+
print(format(n, "b"))             # no prefix at all
print(f"{n:08b}")                 # 8 digits, zero-padded
print(f"{n:#010b}")               # keep 0b, 10 chars total
print(bin(n)[2:].zfill(8))

print(bin(-10)[2:])               # slicing breaks on negatives
print(format(-10, "08b"))

Output:

1010
1010
1010
00001010
0b00001010
00001010
b1010
-0001010
Command Prompt output removing the 0b prefix from Python bin() with slicing, removeprefix, format and f-string padding
Slicing, removeprefix() and format() give 1010; the :08b and zfill() versions pad it to 00001010.

I use f"{n:08b}" almost every time because it pads and drops the prefix in one step. On negatives, slicing bin(-10) leaves a stray b, while format() handles the sign. More padding options are in padding numbers with leading zeros in Python.

How does Python bin() handle negative numbers?

Python ints have no fixed width, so bin() doesn’t show two’s complement. It prints a minus sign plus the bits of the absolute value. To get the bit pattern a C program or a hardware register would hold, mask the number to a width first:

n = -10
print("bin(-10):        ", bin(n))
print("8-bit two's comp:", format(n & 0xFF, "08b"))
print("16-bit:          ", format(n & 0xFFFF, "016b"))

print(int("0b1010", 2), int("1010", 2), int("0b1010", 0))
print("bit_length(255):", (255).bit_length())
print("bit_count(255): ", (255).bit_count())   # Python 3.10+

Output:

bin(-10):         -0b1010
8-bit two's comp: 11110110
16-bit:           1111111111110110
10 10 10
bit_length(255): 8
bit_count(255):  8
Command Prompt output of Python bin(-10), its 8-bit and 16-bit two's complement, int() parsing and bit_length
Masking -10 with 0xFF gives 11110110, and int() turns the 0b1010 text back into 10 three different ways.

int(text, 2) reverses bin(), and base 0 reads the prefix for you. See converting a binary string to int in Python for input checks, and checking if a string is binary before parsing user input.

Why does bin() raise a TypeError for floats and strings?

bin() only accepts integers, or objects that define __index__() to say which integer they stand for. A float or a string of digits fails:

for value in [3.5, "10"]:
    try:
        bin(value)
    except TypeError as e:
        print(f"bin({value!r}): TypeError: {e}")

class Seat:
    def __init__(self, row):
        self.row = row
    def __index__(self):
        return self.row

print("bin(Seat(12)):", bin(Seat(12)))
print("bin(int(3.5)):", bin(int(3.5)))

Output:

bin(3.5): TypeError: 'float' object cannot be interpreted as an integer
bin('10'): TypeError: 'str' object cannot be interpreted as an integer
bin(Seat(12)): 0b1100
bin(int(3.5)): 0b11
Command Prompt output of Python bin() raising TypeError for 3.5 and the string 10, and working on a class with __index__
Both 3.5 and the string ’10’ raise a TypeError saying they can’t be read as an integer; the Seat object works through __index__().

Convert first: int(3.5) truncates to 3, and int("10") parses text. If you’re adding bit strings together rather than numbers, adding two binary numbers in Python shows the pattern.

Want to keep going with number formats? Try these next:

Frequently asked questions

How do I convert an integer to binary without 0b in Python?

Use format(n, "b") or f"{n:b}". Add a width like 08b to pad with zeros.

Why does bin(-10) return -0b1010?

Python ints have unlimited size, so bin() shows a sign plus magnitude. Use n & 0xFF to see the 8-bit two’s complement.

How do I convert a binary string back to an integer?

Call int("1010", 2), or int("0b1010", 0) to let Python read the prefix.

Can bin() take a float?

No. It raises a TypeError. Convert with int() first, which drops the fractional part.

How do I count the 1 bits in a number?

Use n.bit_count() on Python 3.10+, or bin(n).count("1") on older versions.

Where is bin() documented?

See bin() in the Python docs.