Search code examples
pythonfloating-pointpackunpackmodbus

Python : Convert 2 ints to float


I have been trying to convert a set of 2 16 bit integers into a single 32 bit floating point number. This is for my work on MODBUS communication protocol. My query is the same as mentioned here

However, when I follow the pack/unpack approach provided there, I do not get similar results.

Here is my test program:

from struct import *

tup=(16256, 0)

print hex(tup[0])
print hex(tup[1])

mypack = pack('>HH',tup[0],tup[1])
print mypack

f = unpack('f', mypack)[0]
print f

And the Output is as below:

0x3f80
0x0
?
4.60060298822e-41

I expect the final output to be actually just '1.0' as the floating point interpretation of '0x3F800000' is just that!

I am running this code on a Beagle Bone Black board, powered by Debian OS.

Where am I going wrong?


Solution

  • You need to specify the endianness in your unpack call.

    from struct import *
    
    tup=(16256, 0)
    
    print hex(tup[0])
    print hex(tup[1])
    
    mypack = pack('>HH',tup[0],tup[1])
    print `mypack`
    
    f = unpack('>f', mypack)
    print f
    

    output

    0x3f80
    0x0
    '?\x80\x00\x00'
    (1.0,)
    

    But please bear in mind the warnings / caveats mentioned in the question you linked to, especially those in regard to NaN.

    Also note that it's generally considered bad practice to do from modulename import * because it dumps the names from modulename into your scripts namespace. This is messy, and it can lead to bugs. So it's better to do

    import struct
    
    #...
    
    mypack = struct.pack('>HH',tup[0],tup[1])
    f = struct.unpack('>f', mypack)
    

    Sure, it's a little bit more to type, but it makes your code a lot easier to read and maintain.