tags:

views:

98

answers:

2

How can I combine 2 ints to a single 32bit IEEE floating point ? (each of the 2 ints represent 16 bit) And in the opposite direction: How can I transform a python float into 2 16 bit ints?

(I need this because of modbus protocol - where 2x16 bit registers are treated as single 32 floating point number)

A: 

The standard struct module can be used to do this easily. Just be careful of your platform endianess but, other than that, it should be a pretty straight-forward application of pack() and unpack().

Rakis
something like unpack('>f', pack('hh, int1, int2)) ??
bugspy.net
Yep. If it doesn't "just work", you're probably running into an endianess issue. The easiest way I've found to figure out what's going wrong is to use a small test script with hexidecimal constants that you can use while you fiddle with the pack/unpack options till you get the results you're looking for.
Rakis
I don't think this method will work reliably - see my comment on Alejandro's answer.
Scott Griffiths
@Scott Bit manipulation of floating-point values is inherently tricky the `struct` module makes such manipulation possible but doesn't free you from the responsibility using it appropriately.
Rakis
+1  A: 

This code takes the 16 bits integers i1 and i2 and convert them to the floating point number 3.14, and vice versa.

from struct import *
# Two integers to a floating point
i1 = 0xC3F5
i2 = 0x4840
f = unpack('f',pack('>HH',i1,i2))[0]

# Floating point to two integers
i1, i2 = unpack('>HH',pack('f',3.14))
Alejandro
This doesn't always work. For example on my machine if I try `i1 = i2 = 32895`, create `f` and then unpack again I get `i2` back out as 49279. In this case it's because the floating point generated was `nan`, which has some special characteristics.
Scott Griffiths
If that's an issue for the OP, he can check if f is nan: if math.isnan(f): i1 = i2 = 32895 else: i1, i2 = unpack('>HH',pack('f',f))Or he can try python-bitstring (http://code.google.com/p/python-bitstring/). Does is it handle this case correctly?
Alejandro
I don't think it's a good idea to check for nan (there are many combinations that fail in the same way - I only gave one example). The bitstring module isn't going to help with the fundamental problem of going via the Python float type (it uses struct internally in any case). The solution is to keep the data as bytes (for which bitstring might be helpful), but the details depend on the exact nature of the OP's problem.
Scott Griffiths