Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting float.hex() value to binary in Python

Tags:

python

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.

like image 450
Qiang Li Avatar asked Oct 05 '11 19:10

Qiang Li


1 Answers

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.)

like image 161
unutbu Avatar answered Oct 08 '22 16:10

unutbu