Created
May 27, 2024 00:34
-
-
Save mal1kc/7ccc01d5220b4a29509af3c03454f4fa to your computer and use it in GitHub Desktop.
ieee_754 implementation in python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def float_to_binary_32(f): | |
""" | |
Converts a 32-bit floating-point number to its binary representation. | |
Args: | |
f (float): The floating-point number to encode. | |
Returns: | |
str: The binary representation of the floating-point number. | |
""" | |
# For 32-bit float, we manually handle the sign, exponent, and mantissa | |
# by extracting integer and decimal parts and computing the binary representation. | |
# Then, we adjust the exponent and mantissa to fit the IEEE 754 format. | |
# Finally, we concatenate the sign, exponent, and mantissa to get the binary string. | |
if f == 0.0: | |
return '0' * 32 | |
sign = '1' if f < 0 else '0' | |
f = abs(f) | |
integer_part = int(f) | |
decimal_part = f - integer_part | |
integer_binary = bin(integer_part)[2:] | |
decimal_binary = '' | |
while decimal_part != 0: | |
decimal_part *= 2 | |
if decimal_part >= 1: | |
decimal_binary += '1' | |
decimal_part -= 1 | |
else: | |
decimal_binary += '0' | |
binary_representation = integer_binary + '.' + decimal_binary | |
exponent = 0 | |
if '.' in binary_representation: | |
exponent = binary_representation.index('.') - 1 | |
binary_representation = binary_representation.replace('.', '') | |
else: | |
binary_representation = binary_representation.rstrip('0') | |
exponent_binary = bin(127 + exponent)[2:].zfill(8) | |
mantissa = binary_representation[1:].ljust(23, '0') | |
return sign + exponent_binary + mantissa | |
def binary_to_float_32(binary): | |
""" | |
Converts a binary representation to a 32-bit floating-point number. | |
Args: | |
binary (str): The binary representation of the floating-point number. | |
Returns: | |
float: The decoded floating-point number. | |
""" | |
# For 32-bit float, we extract the sign, exponent, and mantissa from the binary string. | |
# Then, we compute the floating-point number by applying the formula based on IEEE 754 format. | |
sign = int(binary[0]) | |
exponent = int(binary[1:9], 2) - 127 | |
mantissa = 1 + sum(int(binary[i]) * 2**(-i+8) for i in range(9, 32)) | |
if exponent == -127: | |
if mantissa == 0: | |
return 0.0 | |
else: | |
return (-1) ** sign * mantissa * 2**(-126) | |
if exponent == 128: | |
if mantissa == 0: | |
return float('inf') if sign == 0 else float('-inf') | |
else: | |
return float('nan') | |
return (-1) ** sign * mantissa * 2**exponent | |
def float_to_binary_64(f): | |
""" | |
Converts a 64-bit floating-point number to its binary representation. | |
Args: | |
f (float): The floating-point number to encode. | |
Returns: | |
str: The binary representation of the floating-point number. | |
""" | |
# For 64-bit float, the process is similar to 32-bit float but with a larger mantissa. | |
# We manually handle the sign, exponent, and mantissa, | |
# adjust them to fit the IEEE 754 format, and concatenate to get the binary string. | |
if f == 0.0: | |
return '0' * 64 | |
sign = '1' if f < 0 else '0' | |
f = abs(f) | |
integer_part = int(f) | |
decimal_part = f - integer_part | |
integer_binary = bin(integer_part)[2:] | |
decimal_binary = '' | |
while decimal_part != 0: | |
decimal_part *= 2 | |
if decimal_part >= 1: | |
decimal_binary += '1' | |
decimal_part -= 1 | |
else: | |
decimal_binary += '0' | |
binary_representation = integer_binary + '.' + decimal_binary | |
exponent = 0 | |
if '.' in binary_representation: | |
exponent = binary_representation.index('.') - 1 | |
binary_representation = binary_representation.replace('.', '') | |
else: | |
binary_representation = binary_representation.rstrip('0') | |
exponent_binary = bin(1023 + exponent)[2:].zfill(11) | |
mantissa = binary_representation[1:].ljust(52, '0') | |
return sign + exponent_binary + mantissa | |
def binary_to_float_64(binary): | |
""" | |
Converts a binary representation to a 64-bit floating-point number. | |
Args: | |
binary (str): The binary representation of the floating-point number. | |
Returns: | |
float: The decoded floating-point number. | |
""" | |
# For 64-bit float, we extract the sign, exponent, and mantissa from the binary string. | |
# Then, we compute the floating-point number using the formula based on IEEE 754 format. | |
sign = int(binary[0]) | |
exponent = int(binary[1:12], 2) - 1023 | |
mantissa = 1 + sum(int(binary[i]) * 2**(-i+11) for i in range(12, 64)) | |
if exponent == -1023: | |
if mantissa == 0: | |
return 0.0 | |
else: | |
return (-1) ** sign * mantissa * 2**(-1022) | |
if exponent == 1024: | |
if mantissa == 0: | |
return float('inf') if sign == 0 else float('-inf') | |
else: | |
return float('nan') | |
return (-1) ** sign * mantissa * 2**exponent | |
def main(): | |
examples = [3.14, 123.456, -0.001] | |
for example in examples: | |
binary_encoded_32 = float_to_binary_32(example) | |
decoded_32 = binary_to_float_32(binary_encoded_32) | |
binary_encoded_64 = float_to_binary_64(example) | |
decoded_64 = binary_to_float_64(binary_encoded_64) | |
print(f"Original: {example}") | |
print(f"32-bit Encoded: {binary_encoded_32}, Decoded: {decoded_32}") | |
print(f"64-bit Encoded: {binary_encoded_64}, Decoded: {decoded_64}") | |
print() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment