2010-06-17 20 views
5

¿Cómo puedo combinar 2 ints con un solo punto flotante IEEE de 32 bits? (cada una de las 2 entradas representa 16 bit) Y en la dirección opuesta: ¿Cómo puedo transformar un flotador de pitón en 2 entradas de 16 bits?Python: convierte 2 ints a 32 float

(necesito esto a causa de protocolo Modbus - donde 2x16 registros de bits son tratados como número 32 de punto flotante individual)

+0

Desconfíe de tratar las carrozas de Python como 32-bit IEEE - en realidad son de 64 bits. Entonces, si desempaqueta tus 32 bits en un flotador, realmente será de 64 bits, y no estoy seguro de las implicaciones de redondeo de eso. –

Respuesta

3

Este código toma los enteros de 16 bits i1 e i2 y los convierte al número de coma flotante 3.14, y viceversa.

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)) 
+1

Esto no siempre funciona. Por ejemplo, en mi máquina si intento 'i1 = i2 = 32895', creo' f' y luego vuelvo a descomprimir, obtengo 'i2' como 49279. En este caso, es porque el punto flotante generado fue' nan', que tiene algunas características especiales. –

+0

Si eso es un problema para el OP, se puede comprobar si f es nan: si math.isnan (f): i1 = i2 = 32895 otra cosa: i1, i2 = unpack ('> HH', paquete ('f', f)) O puede probar python-bitstring (http://code.google.com/p/python-bitstring/). ¿Es manejar este caso correctamente? – Alejandro

+0

No creo que sea una buena idea comprobar si hay nan (hay muchas combinaciones que fallan de la misma manera; solo di un ejemplo). El módulo de cadena de bits no va a ayudar con el problema fundamental de ir a través del tipo de flotación de Python (en cualquier caso, usa struct internamente). La solución es mantener los datos como bytes (para lo cual la cadena de bits podría ser útil), pero los detalles dependen de la naturaleza exacta del problema del PO. –

0

El módulo estándar struct se puede utilizar para hacer esto fácilmente. Solo tenga cuidado con la compatibilidad de su plataforma, pero, aparte de eso, debe ser una aplicación bastante directa de pack() y unpack().

+0

algo así como desempaquetar ('> f', paquete ('hh, int1, int2)) ?? – GabiMe

+0

Sí. Si no "solo funciona", probablemente se encuentre con un problema de endianess. La forma más fácil que he encontrado para descubrir qué es lo que está mal es usar un pequeño script de prueba con constantes hexadecimales que puede usar mientras juega con las opciones de paquete/desempaquetar hasta que obtenga los resultados que está buscando. – Rakis

+0

No creo que este método funcione de manera confiable. Vea mi comentario sobre la respuesta de Alejandro. –