Wie konvertiert man die folgende hexadezimale Zeichenfolge in Float (einzelne Genauigkeit 32-Bit) in Python?Konvertieren von hex in float
"41973333" -> 1.88999996185302734375E1
"41995C29" -> 1.91700000762939453125E1
"470FC614" -> 3.6806078125E4
Wie konvertiert man die folgende hexadezimale Zeichenfolge in Float (einzelne Genauigkeit 32-Bit) in Python?Konvertieren von hex in float
"41973333" -> 1.88999996185302734375E1
"41995C29" -> 1.91700000762939453125E1
"470FC614" -> 3.6806078125E4
>>> import struct
>>> struct.unpack('!f', '41973333'.decode('hex'))[0]
18.899999618530273
>>> struct.unpack('!f', '41995C29'.decode('hex'))[0]
19.170000076293945
>>> struct.unpack('!f', '470FC614'.decode('hex'))[0]
36806.078125
Update: siehe Kommentar auf, wie die 3.
ich diese Frage bin zu raten, bezieht sich auf this one und Sie arbeiten mit 4 Bytes statt 8 hexadezimalen Ziffern.
"\x41\x91\x33\x33"
ist ein 4-Byte-String, obwohl es wie 16
>>> len("\x41\x91\x33\x33")
4
>>> import struct
>>> struct.unpack(">fff","\x41\x97\x33\x33\x41\x99\x5C\x29\x47\x0F\xC6\x14")
(18.899999618530273, 19.170000076293945, 36806.078125)
Wenn Sie mit der Zeichenfolge von hexdigits beschäftigen müssen sieht, anstatt der tatsächliche Bytes, Sie struct.pack
verwenden können, um es zu konvertieren, wie dies
>>> for hx in ["41973333","41995C29","470FC614"]:
... print(struct.unpack(">f",struct.pack(">i",int(hx,16)))[0])
...
18.8999996185
19.1700000763
36806.078125
ich empfehle the ctypes module verwendet, die im Grunde können Sie mit geringen Datentypen arbeiten. In Ihrem Fall könnten Sie
from ctypes import *
def convert(s):
i = int(s, 16) # convert from hex to a Python int
cp = pointer(c_int(i)) # make this into a c integer
fp = cast(cp, POINTER(c_float)) # cast the int pointer to a float pointer
return fp.contents.value # dereference the pointer, get the float
print convert("41973333") # returns 1.88999996185302734375E1
print convert("41995C29") # returns 1.91700000762939453125E1
print convert("470FC614") # returns 3.6806078125E4
sagen, dass ich glaube, dass der ctypes
Modul Sinn hier macht, weil Sie im Wesentlichen ist zu fragen, wie Low-Level-Bit-Casting durchzuführen. Ihre Frage ist im Grunde, wie sage ich Python, um einige Daten zu nehmen und diese Daten so zu interpretieren, als wären diese genau dieselben Bits ein anderer Datentyp?
In C, wenn Sie einen int haben und wollten seine Bits als Schwimmer zu interpretieren, Sie ungefähr das gleiche tun würden, um einen Zeiger zu nehmen und dann Gießen und dereferencing es:
int i = 0x41973333;
float f = *((float*)&i);
und das ist genau was der Python-Code mit der ctypes
-Bibliothek in meinem Beispiel macht.
Die hexadezimalen Strings in 2-character Chunks (Bytes) zerlegen, jeden Chunk in das richtige Byte mit int-Formatierung bringen, struct.unpack, wenn das erledigt ist. Dh:
import struct
testcases = {
"41973333": 1.88999996185302734375E1,
"41995C29": 1.91700000762939453125E1,
"470FC614": 3.6806078125E4,
}
def hex2float(s):
bins = ''.join(chr(int(s[x:x+2], 16)) for x in range(0, len(s), 2))
return struct.unpack('>f', bins)[0]
for s in testcases:
print hex2float(s), testcases[s]
emittieren, je nach Wunsch:
18.8999996185 18.8999996185
19.1700000763 19.1700000763
36806.078125 36806.078125
Gentelmen in Python zu tun ... Siehe:
class fl:
def __init__(this, value=0, byte_size=4):
this.value = value
if this.value: # speedy check (before performing any calculations)
Fe=((byte_size*8)-1)//(byte_size+1)+(byte_size>2)*byte_size//2+(byte_size==3)
Fm,Fb,Fie=(((byte_size*8)-(1+Fe)), ~(~0<<Fe-1), (1<<Fe)-1)
FS,FE,FM=((this.value>>((byte_size*8)-1))&1,(this.value>>Fm)&Fie,this.value&~(~0 << Fm))
if FE == Fie: this.value=(float('NaN') if FM!=0 else (float('+inf') if FS else float('-inf')))
else: this.value=((pow(-1,FS)*(2**(FE-Fb-Fm)*((1<<Fm)+FM))) if FE else pow(-1,FS)*(2**(1-Fb-Fm)*FM))
del Fe; del Fm; del Fb; del Fie; del FS; del FE; del FM
else: this.value = 0.0
print fl(0x41973333).value # >>> 18.899999618530273
print fl(0x41995C29).value # >>> 19.170000076293945
print fl(0x470FC614).value # >>> 36806.078125
print fl(0x00800000).value # >>> 1.1754943508222875e-38 (minimum float value)
print fl(0x7F7FFFFF).value # >>> 340282346638528859811704183484516925440L (maximum float value)
# looks like I've found a small bug o.o
# the code still works though (the numbers are properly formatted)
# the result SHOULD be: 3.4028234663852886e+38 (rounded)
print fl(0x3f80000000, 5).value # >>> 1.0
Entschuldigung für das kleine ".value" bei t Er endet ...
Dieser Code wurde seit fast 2 Jahren als Klasse in meinem Programm verwendet.
(mit ein wenig Bearbeitung, können Sie es leicht zu einer Funktion machen)
Kredit an PyTony über bei DaniWeb für den Code.
Im Gegensatz zu nicht-dynamischem computing,
der Code auf eine feste Größe Schwimmers nicht fest verdrahtet ist,
und arbeitet mit jeder Byte-Größe.
obwohl ich denke, wir haben noch ein paar Bugs zu erarbeiten.XDD
(später werde ich diesen Code bearbeiten (wenn ich kann) mit dem Update)
alles gut ist aber für jetzt aber ...
ich havn't damit ein Problem Umwandlung 3D-Spiel Modelle hatte. :)
Wow, dass Code undurchdringlich ist ... – SamB
Der Ctypes-Ansatz funktioniert nicht, wenn die Hexadezimalzahl führende Nullen enthält. Benutze es nicht.
In Python3 müssen Sie 'bytes.fromhex ('41973333')' anstelle von ''41973333'.decode (' hex ')' –