Skip to main content

How to Check if a Binary Representation is a Palindrome in Python

A binary palindrome is a number whose binary representation reads the same forwards and backwards. For example, 5 in binary is 101, and 9 is 1001, both are palindromes.

This guide covers multiple approaches, from simple string manipulation to efficient bit-level operations.

Using String Slicing

Python's string slicing [::-1] makes palindrome checking straightforward. Convert the number to binary, remove the 0b prefix, and compare with its reverse.

def is_binary_palindrome(n: int) -> bool:
"""Check if binary representation of n is a palindrome."""
binary_str = bin(n)[2:] # Remove '0b' prefix
return binary_str == binary_str[::-1]


# Test cases
print(is_binary_palindrome(5)) # True (101)
print(is_binary_palindrome(9)) # True (1001)
print(is_binary_palindrome(10)) # False (1010)
print(is_binary_palindrome(0)) # True (0)

Output:

True
True
False
True

Using f-strings

An alternative approach using formatted strings:

def is_binary_palindrome_fstring(n: int) -> bool:
"""Check palindrome using f-string formatting."""
binary_str = f"{n:b}"
return binary_str == binary_str[::-1]

Using Bit Manipulation

For competitive programming or memory-constrained environments, reverse the bits mathematically without allocating strings.

def is_binary_palindrome_bitwise(n: int) -> bool:
"""Check palindrome using bit manipulation (O(1) space)."""
if n < 0:
return False

if n == 0:
return True

# Reverse the bits
original = n
reversed_n = 0

while n > 0:
reversed_n = (reversed_n << 1) | (n & 1)
n >>= 1

return reversed_n == original


print(is_binary_palindrome_bitwise(9)) # True
print(is_binary_palindrome_bitwise(10)) # False
How It Works

For n = 9 (binary 1001):

  1. Extract last bit: 9 & 1 = 1, shift result left, add bit → reversed = 1
  2. Shift n right: 9 >> 1 = 4 (binary 100)
  3. Extract: 4 & 1 = 0, shift and add → reversed = 10
  4. Continue until n = 0 → reversed = 1001 = 9
  5. Compare: 9 == 9 → True

Fixed-Width Palindrome Check

Sometimes you need to check if a number is a palindrome within a specific bit width (e.g., 8-bit byte). In this case, leading zeros are significant.

def is_binary_palindrome(n: int) -> bool:
"""Check if binary representation of n is a palindrome."""
binary_str = bin(n)[2:] # Remove '0b' prefix
return binary_str == binary_str[::-1]

def is_palindrome_fixed_width(n: int, width: int = 8) -> bool:
"""Check if n is a palindrome in a fixed-width binary representation."""
if n < 0 or n >= (1 << width):
raise ValueError(f"Number must be between 0 and {(1 << width) - 1}")

binary_str = f"{n:0{width}b}"
return binary_str == binary_str[::-1]


# Without fixed width: 9 = '1001' is a palindrome
print(is_binary_palindrome(9)) # True

# With 8-bit fixed width: 9 = '00001001' is NOT a palindrome
print(is_palindrome_fixed_width(9, 8)) # False

# 129 = '10000001' IS a palindrome in 8 bits
print(is_palindrome_fixed_width(129, 8)) # True

Finding Binary Palindromes in a Range

Generate all binary palindromes within a given range:

def find_binary_palindromes(start: int, end: int) -> list:
"""Find all binary palindromes in the given range."""
palindromes = []

for n in range(start, end + 1):
binary = bin(n)[2:]
if binary == binary[::-1]:
palindromes.append((n, binary))

return palindromes


# Find palindromes from 1 to 50
results = find_binary_palindromes(1, 50)

for decimal, binary in results:
print(f"{decimal:3d} = {binary}")

Output:

  1 = 1
3 = 11
5 = 101
7 = 111
9 = 1001
15 = 1111
17 = 10001
21 = 10101
27 = 11011
31 = 11111
33 = 100001
45 = 101101

Generating Binary Palindromes

Efficiently generate palindromes rather than checking every number:

def generate_binary_palindromes(max_bits: int) -> list:
"""Generate all binary palindromes up to max_bits length."""
palindromes = []

for bits in range(1, max_bits + 1):
if bits == 1:
palindromes.append(1)
else:
# Generate palindromes of this bit length
half_len = (bits + 1) // 2

for i in range(1 << (half_len - 1), 1 << half_len):
# Build palindrome from first half
half = bin(i)[2:]

if bits % 2 == 0:
palindrome = half + half[::-1]
else:
palindrome = half + half[-2::-1]

palindromes.append(int(palindrome, 2))

return sorted(palindromes)


# Generate all palindromes up to 8 bits
palins = generate_binary_palindromes(8)
print(f"Found {len(palins)} palindromes")
print(palins[:15])

Output:

Found 30 palindromes
[1, 3, 5, 7, 9, 15, 17, 21, 27, 31, 33, 45, 51, 63, 65]

Performance Comparison

import time


def is_binary_palindrome(n: int) -> bool:
"""Check if binary representation of n is a palindrome."""
binary_str = bin(n)[2:] # Remove '0b' prefix
return binary_str == binary_str[::-1]


def is_binary_palindrome_bitwise(n: int) -> bool:
"""Check palindrome using bit manipulation (O(1) space)."""
if n < 0:
return False

if n == 0:
return True

# Reverse the bits
original = n
reversed_n = 0

while n > 0:
reversed_n = (reversed_n << 1) | (n & 1)
n >>= 1

return reversed_n == original


def benchmark(func, test_range, iterations=1000):
start = time.perf_counter()
for _ in range(iterations):
for n in test_range:
func(n)
return time.perf_counter() - start


test_numbers = range(1, 1000)

print(f"String method: {benchmark(is_binary_palindrome, test_numbers):.4f}s")
print(f"Bitwise method: {benchmark(is_binary_palindrome_bitwise, test_numbers):.4f}s")

Output:

String method:  0.2659s
Bitwise method: 1.1837s

Method Comparison

MethodTime ComplexitySpace ComplexityBest For
String slicingO(log n)O(log n)General use, readability
Bit manipulationO(log n)O(1)Memory-constrained, competitive programming
Fixed-widthO(width)O(width)Hardware-specific bit patterns

Summary

  • Use string slicing (bin(n)[2:][::-1]) for most applications. It's readable and Pythonic.
  • Use bit manipulation when memory is constrained or you need constant space.
  • Use fixed-width formatting when leading zeros are significant (e.g., byte-level operations).
  • Consider generating palindromes directly when you need many of them.