Byte Operations
I24 and U24 provide extensive support for working with binary data and byte representations.
Byte Order (Endianness)
All byte operations support three byte orders:
'little': Little-endian (least significant byte first)'big': Big-endian (most significant byte first)'native': Native byte order (platform-dependent)
Converting to Bytes
Basic Conversion
from i24 import I24, U24
value = I24(0x123456)
# Little-endian (LSB first)
le_bytes = value.to_bytes(byteorder='little')
print(le_bytes) # [86, 52, 18] (0x56, 0x34, 0x12)
# Big-endian (MSB first)
be_bytes = value.to_bytes(byteorder='big')
print(be_bytes) # [18, 52, 86] (0x12, 0x34, 0x56)
# Native byte order (platform-dependent)
native_bytes = value.to_bytes(byteorder='native')
Signed vs Unsigned
from i24 import I24, U24
# Negative signed value
negative = I24(-1000)
bytes_neg = negative.to_bytes(byteorder='little')
print(bytes_neg) # [24, 252, 255] (two's complement)
# Same bit pattern as unsigned
unsigned = U24(16776216) # Equivalent bit pattern
bytes_pos = unsigned.to_bytes(byteorder='little')
print(bytes_pos) # [24, 252, 255]
Creating from Bytes
Basic Creation
from i24 import I24, U24
# From little-endian bytes
bytes_le = bytes([0x12, 0x34, 0x56])
value = I24.from_bytes(bytes_le, byteorder='little')
print(hex(value.to_int())) # 0x563412
# From big-endian bytes
bytes_be = bytes([0x12, 0x34, 0x56])
value = I24.from_bytes(bytes_be, byteorder='big')
print(hex(value.to_int())) # 0x123456
# Default is native byte order
value = I24.from_bytes(bytes([0x01, 0x02, 0x03]))
Validation
The from_bytes method validates input:
from i24 import I24
# Wrong number of bytes
try:
value = I24.from_bytes(bytes([0x01, 0x02]), byteorder='little')
except ValueError as e:
print(f"Error: {e}") # bytes must be exactly 3 bytes long
# Invalid byte order
try:
value = I24.from_bytes(bytes([0x01, 0x02, 0x03]), byteorder='middle')
except ValueError as e:
print(f"Error: {e}") # byteorder must be 'little', 'big', or 'native'
Bitwise Operations
I24 and U24 support all standard bitwise operations:
AND, OR, XOR
from i24 import I24, U24
a = I24(0b111100001111)
b = I24(0b110011001100)
# Bitwise AND
result = a & b
print(bin(result.to_int())) # 0b110000001100
# Bitwise OR
result = a | b
print(bin(result.to_int())) # 0b111111001111
# Bitwise XOR
result = a ^ b
print(bin(result.to_int())) # 0b001111000011
Bitwise NOT
from i24 import I24, U24
value = I24(0b111100001111)
inverted = ~value
print(bin(inverted.to_int() & 0xFFFFFF)) # Inverted bits
Left and Right Shift
from i24 import I24, U24
value = I24(0b1111)
# Left shift
shifted = value << 4
print(bin(shifted.to_int())) # 0b11110000
# Right shift
shifted = value >> 2
print(bin(shifted.to_int())) # 0b11
# Shift with overflow detection
large = I24(0x100000)
try:
result = large << 8 # Would exceed 24 bits
except OverflowError as e:
print(f"Shift overflow: {e}")
Bit Manipulation Methods
Counting Bits
from i24 import I24, U24
value = U24(0b11110000111100001111)
# Count one bits
ones = value.count_ones()
print(ones) # 12
# Count zero bits
zeros = value.count_zeros()
print(zeros) # 20
# Leading zeros
leading = value.leading_zeros()
print(leading) # Number of leading zero bits
# Trailing zeros
trailing = value.trailing_zeros()
print(trailing) # Number of trailing zero bits
Bit Length
from i24 import I24, U24
value = U24(255) # 0b11111111
# Number of bits needed to represent the value
bits_needed = value.bit_length()
print(bits_needed) # 8
# Bit count (number of 1 bits)
bit_count = value.bit_count()
print(bit_count) # 8