web-dev-qa-db-fra.com

Comment convertir un float en hex

En Python, j'ai besoin de convertir un tas de flotteurs en hexadécimal. Il doit être rempli à zéro (par exemple, 0x00000010 au lieu de 0x10). Tout comme http://gregstoll.dyndns.org/~gregstoll/floattohex/ does. (Malheureusement, je ne peux pas utiliser de bibliothèque externe sur ma plateforme, donc je ne peux pas utiliser celle fournie sur ce site)

Quel est le moyen le plus efficace de le faire?

14
user2339945

C'est un peu délicat en python, car on ne cherche pas à convertir le valeur à virgule flottante en un entier (hexadécimal). Au lieu de cela, vous essayez de interpréter la représentation IEEE 754 binaire de la valeur à virgule flottante sous forme hexadécimale.

Nous utiliserons les fonctions pack et unpack de la bibliothèque struct intégrée.

Une float est 32 bits. Nous allons d'abord pack dans un binaire1 string, puis unpack comme int.

def float_to_hex(f):
    return hex(struct.unpack('<I', struct.pack('<f', f))[0])

float_to_hex(17.5)    # Output: '0x418c0000'

Nous pouvons faire la même chose pour double, sachant qu'il s'agit de 64 bits:

def double_to_hex(f):
    return hex(struct.unpack('<Q', struct.pack('<d', f))[0])

double_to_hex(17.5)   # Output: '0x4031800000000000L'

1 - Signification d'une chaîne d'octets bruts; not une chaîne de uns et de zéros.

31

En Python, float est toujours à double précision.

Si vous souhaitez que votre réponse apparaisse sous la forme d'un entier hexadécimal, vous avez déjà répondu à la question:

import struct

# define double_to_hex as in the other answer

double_to_hex(17.5)   # Output: '0x4031800000000000'
double_to_hex(-17.5)  # Output: '0xc031800000000000'

Cependant, vous pourriez plutôt envisager d'utiliser la fonction intégrée:

(17.5).hex()    # Output: '0x1.1800000000000p+4'
(-17.5).hex()   # Output: '-0x1.1800000000000p+4'

# 0x1.18p+4 == (1 + 1./0x10 + 8./0x100) * 2**4 == 1.09375 * 16 == 17.5

C'est la même réponse que précédemment, mais dans un format plus structuré et lisible par l'homme.

Les 52 bits inférieurs sont la mantisse. Les 12 bits supérieurs consistent en un bit de signe et un exposant de 11 bits; le biais de l'exposant est 1023 == 0x3FF, 0x403 signifie donc '4'. Voir Article Wikipedia sur la virgule flottante IEEE .

12
ghostarbeiter

Suite à Jonathon Reinhart très utile réponse . J'avais besoin de cela pour envoyer un nombre à virgule flottante sous forme d'octets sur UDP

import struct

# define double_to_hex (or float_to_hex)
def double_to_hex(f):
    return hex(struct.unpack('<Q', struct.pack('<d', f))[0])

# On the UDP transmission side
doubleAsHex = double_to_hex(17.5)
doubleAsBytes = bytearray.fromhex(doubleAsHex.lstrip('0x').rstrip('L'))

# On the UDP receiving side
doubleFromBytes = struct.unpack('>d', doubleAsBytes)[0] # or '>f' for float_to_hex
2
Ken

si vous êtes sur micropython (ce qui n’est pas dit dans la question, mais j’ai eu du mal à trouver), vous pouvez utiliser ceci

import binascii
def float_to_hex(f):
    binascii.hexlify(struct.pack('<f', f))

float_to_hex(17.5) #Answer: 0x418c0000
0
Kevin Cando