int.bit_length()

Bit width of the magnitude. The sign is ignored, so n and -n always give the same answer, and 0 gives 0 rather than 1.

Int methodPython 3.1+Live demo
Common call
n.bit_length()
Returns
int — the position of the highest set bit, counting from 1
Replaces
len(bin(abs(n))) - 2 and math.floor(math.log2(n)) + 1
Watch out
(0).bit_length() is 0, not 1 — there is no set bit to point at
int.bit_length()
→ int

Demo

Live evaluation
Try:
Inputs
nintinteger to measure
Output
(0).bit_length()
0

bit_length answers "how wide is this number in binary?". It counts from the highest set bit down to bit 0, so 255 (11111111) is 8 and 256 (100000000) is 9. The sign is discarded first, which is why -255 also gives 8. Zero is the special case: it has no set bit at all, so the answer is 0 rather than 1.

Common patterns

Bytes needed to store a value
Round the bit width up to whole bytes — the usual companion to to_bytes.
n_bytes = (n.bit_length() + 7) // 8
Integer log2 without floats
Exact for every int, unlike math.log2, which loses precision on very large values.
floor_log2 = n.bit_length() - 1   # for n > 0
Check if a value fits in a field
Cheaper and clearer than comparing against 2 ** width.
if value.bit_length() <= 16:
    pack_as_uint16(value)

Examples

1. Zero is 0
(0).bit_length()
Returns
0
2. One bit
(1).bit_length()
Returns
1
3. Full byte
(255).bit_length()
Returns
8
4. Just over a byte
(256).bit_length()
Returns
9
5. Sign is ignored
(-255).bit_length()
Returns
8
6. Huge ints are fine
(2 ** 1000).bit_length()
Returns
1001

Pitfalls

1. (0).bit_length() is 0, not 1
It counts set bits positions, not printed characters. Zero has no set bit, so the width is 0. Code that divides by the result, or assumes at least one byte, breaks on zero.
Zero bytes for zero
n = 0
n_bytes = (n.bit_length() + 7) // 8
n.to_bytes(n_bytes, "big")
b'' # empty, probably not what you wanted
Floor at one byte
n_bytes = max(1, (n.bit_length() + 7) // 8)
b'\x00'
2. It measures the magnitude, not the two-complement width
Negative numbers return the width of their absolute value. That is NOT the number of bits a signed representation needs — signed storage needs one more bit for the sign.
Too narrow for signed
(-128).bit_length()
8 # but signed -128 needs 8, and -129 needs 9
Add the sign bit
width = n.bit_length() + (1 if n < 0 else 0)
room for the sign
3. Not the same as len(bin(n))
bin() prefixes with "0b", and adds "-" for negatives, so the string length is 2 or 3 characters longer. Reaching for len(bin(n)) and forgetting to subtract is a classic off-by-two.
Off by two
len(bin(255))
10 # "0b11111111"
Use the method
(255).bit_length()
8

When to use

Use it
  • Sizing a buffer before calling to_bytes
  • Exact integer log2 on values too big for float precision
  • Checking a value fits a fixed-width field
  • Bit-twiddling where the position of the top set bit matters
Reach for something else
  • Counting how many bits are SET → bit_count
  • Wanting the two-complement width of a negative → add the sign bit yourself
  • Formatting for display → bin, hex or format

Notes

Complexity
O(1) for machine-word ints; O(1) on the top digit for big ints
Return
A non-negative int; 0 only for the input 0
CPython impl
Objects/longobject.c :: long_bit_length
Memory
No allocation — reads the most significant digit
Thread-safe
Yes — ints are immutable

FAQ

Because bit_length reports the position of the highest set bit, and zero has none. Every other value n satisfies 2 ** (n.bit_length() - 1) <= abs(n) < 2 ** n.bit_length(); zero cannot, so it is defined as 0.

(0).bit_length()
# 0

History

3.1
int.bit_length added (also backported to Python 2.7).