Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 224 additions & 0 deletions conversions/binary_to_gray_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
"""
Convert between Binary and Gray Code representations.

Gray Code (also known as reflected binary code) is a binary numeral system where
two successive values differ in only one bit. This property makes it useful in
error correction, digital communications, and position encoders.

Wikipedia: https://en.wikipedia.org/wiki/Gray_code
"""


def binary_to_gray(binary_number: int) -> int:
"""
Convert a binary number to its Gray Code equivalent.

The algorithm works by XORing the binary number with itself right-shifted by 1.
Formula: gray = binary XOR (binary >> 1)

Args:
binary_number: A positive integer representing a binary number

Returns:
The Gray Code equivalent as an integer

Examples:
>>> binary_to_gray(0)
0
>>> binary_to_gray(1)
1
>>> binary_to_gray(2)
3
>>> binary_to_gray(3)
2
>>> binary_to_gray(4)
6
>>> binary_to_gray(7)
4
>>> binary_to_gray(10)
15
>>> binary_to_gray(15)
8
>>> binary_to_gray(255)
128
>>> binary_to_gray(-1)
Traceback (most recent call last):
...
ValueError: Input must be a non-negative integer
>>> binary_to_gray(3.5)
Traceback (most recent call last):
...
TypeError: Input must be an integer
"""
if not isinstance(binary_number, int):
raise TypeError("Input must be an integer")
if binary_number < 0:
raise ValueError("Input must be a non-negative integer")

return binary_number ^ (binary_number >> 1)


def gray_to_binary(gray_number: int) -> int:
"""
Convert a Gray Code number to its binary equivalent.

The algorithm works by repeatedly XORing the gray code with itself right-shifted,
until the right-shifted value becomes 0.

Args:
gray_number: A positive integer representing a Gray Code number

Returns:
The binary equivalent as an integer

Examples:
>>> gray_to_binary(0)
0
>>> gray_to_binary(1)
1
>>> gray_to_binary(3)
2
>>> gray_to_binary(2)
3
>>> gray_to_binary(6)
4
>>> gray_to_binary(4)
7
>>> gray_to_binary(15)
10
>>> gray_to_binary(8)
15
>>> gray_to_binary(128)
255
>>> gray_to_binary(-1)
Traceback (most recent call last):
...
ValueError: Input must be a non-negative integer
>>> gray_to_binary(5.5)
Traceback (most recent call last):
...
TypeError: Input must be an integer
"""
if not isinstance(gray_number, int):
raise TypeError("Input must be an integer")
if gray_number < 0:
raise ValueError("Input must be a non-negative integer")

binary_number = gray_number
gray_number >>= 1

while gray_number:
binary_number ^= gray_number
gray_number >>= 1

return binary_number


def decimal_to_gray(decimal_number: int) -> str:
"""
Convert a decimal number to its Gray Code representation as a binary string.

Args:
decimal_number: A positive integer in decimal

Returns:
Gray Code representation as a binary string

Examples:
>>> decimal_to_gray(0)
'0'
>>> decimal_to_gray(1)
'1'
>>> decimal_to_gray(2)
'11'
>>> decimal_to_gray(3)
'10'
>>> decimal_to_gray(4)
'110'
>>> decimal_to_gray(10)
'1111'
>>> decimal_to_gray(15)
'1000'
>>> decimal_to_gray(-1)
Traceback (most recent call last):
...
ValueError: Input must be a non-negative integer
"""
if not isinstance(decimal_number, int):
raise TypeError("Input must be an integer")
if decimal_number < 0:
raise ValueError("Input must be a non-negative integer")

gray_code = binary_to_gray(decimal_number)
return bin(gray_code)[2:] # Remove '0b' prefix


def gray_to_decimal(gray_string: str) -> int:
"""
Convert a Gray Code binary string to its decimal equivalent.

Args:
gray_string: A string of 0s and 1s representing Gray Code

Returns:
The decimal equivalent as an integer

Examples:
>>> gray_to_decimal('0')
0
>>> gray_to_decimal('1')
1
>>> gray_to_decimal('11')
2
>>> gray_to_decimal('10')
3
>>> gray_to_decimal('110')
4
>>> gray_to_decimal('1111')
10
>>> gray_to_decimal('1000')
15
>>> gray_to_decimal('invalid')
Traceback (most recent call last):
...
ValueError: Invalid binary string
>>> gray_to_decimal('')
Traceback (most recent call last):
...
ValueError: Input string cannot be empty
"""
if not gray_string:
raise ValueError("Input string cannot be empty")

# Validate binary string
if not all(bit in "01" for bit in gray_string):
raise ValueError("Invalid binary string")

gray_number = int(gray_string, 2)
return gray_to_binary(gray_number)


if __name__ == "__main__":
import doctest

doctest.testmod()

# Interactive demonstration
print("=== Binary to Gray Code Converter ===\n")

# Demonstrate conversions for 0-15
print("Decimal | Binary | Gray Code")
print("--------|----------|----------")
for i in range(16):
binary = bin(i)[2:].zfill(4)
gray = decimal_to_gray(i).zfill(4)
print(f"{i:7} | {binary:8} | {gray:9}")

print("\n=== Verification: Gray to Binary ===\n")
print("Gray Code | Binary | Decimal")
print("----------|----------|--------")
for i in range(16):
gray = decimal_to_gray(i).zfill(4)
decimal = gray_to_decimal(gray)
binary = bin(decimal)[2:].zfill(4)
print(f"{gray:9} | {binary:8} | {decimal:7}")