"""
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:]
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")
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()
print("=== Binary to Gray Code Converter ===\n")
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}")