Skip to content

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

How to check whether a number's binary representation is a palindrome in Python using string slicing, bit manipulation, and fixed-width checks, with simple examples and practical tips.

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]


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

    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

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]


print(is_binary_palindrome(9))           # True

print(is_palindrome_fixed_width(9, 8))   # False

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


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:
            half_len = (bits + 1) // 2

            for i in range(1 << (half_len - 1), 1 << half_len):
                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)


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

    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

Method Time Complexity Space Complexity Best For
String slicing O(log n) O(log n) General use, readability
Bit manipulation O(log n) O(1) Memory-constrained, competitive programming
Fixed-width O(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.
Navigation