I am wondering how to convert the result returned by float.hex()
to binary, for example, from 0x1.a000000000000p+2
to 110.1
.
Can anyone please help? Thanks.
def float_to_binary(num):
exponent=0
shifted_num=num
while shifted_num != int(shifted_num):
shifted_num*=2
exponent+=1
if exponent==0:
return '{0:0b}'.format(int(shifted_num))
binary='{0:0{1}b}'.format(int(shifted_num),exponent+1)
integer_part=binary[:-exponent]
fractional_part=binary[-exponent:].rstrip('0')
return '{0}.{1}'.format(integer_part,fractional_part)
def floathex_to_binary(floathex):
num = float.fromhex(floathex)
return float_to_binary(num)
print(floathex_to_binary('0x1.a000000000000p+2'))
# 110.1
print(floathex_to_binary('0x1.b5c2000000000p+1'))
# 11.01101011100001
Explanation:
float.fromhex
returns a float num
. We'd like its binary representation.
{0:b}.format(...)
returns binary representations of integers, but not floats.
But if we multiply the float by enough powers of 2, that is, shift the binary representation to the left enough places, we end up with an integer, shifted_num
.
Once we have that integer, we are home free, because now we can use {0:b}.format(...)
.
We can re-insert the decimal point (err, binary point?) by using a bit of string slicing based on the number of places we had shifted to the left (exponent
).
Technical point: The number of digits in the binary representation of shifted_num
may be smaller than exponent
. In that case, we need to pad the binary representation with more 0's on the left, so binary slicing with binary[:-exponent]
won't be empty. We manage that with '{0:0{1}b}'.format(...)
. The 0{1}
in the format string sets the width of the formated string to {1}
, padded on the left with zeros. (The {1}
gets replaced by the number exponent
.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With