将hex转换为float

jac*_*ack 35 python floating-point binary hex decimal

如何在Python中将以下十六进制字符串转换为float(单精度32位)?

"41973333" -> 1.88999996185302734375E1

"41995C29" -> 1.91700000762939453125E1

"470FC614" -> 3.6806078125E4
Run Code Online (Sandbox Code Playgroud)

Den*_*ach 56

>>> 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
Run Code Online (Sandbox Code Playgroud)

更新:请参阅有关如何在Python 3中执行此操作的注释.

  • 在python3中你必须使用`bytes.fromhex('41973333')`而不是''41973333'.decode('hex')` (15认同)

Eli*_*ght 13

我建议使用ctypes模块,它基本上允许您使用低级数据类型.在你的情况下你可以说

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
Run Code Online (Sandbox Code Playgroud)

我相信这个ctypes模块在这里很有意义,因为你实际上是在询问如何执行低级位转换.您的问题基本上是,我如何告诉Python获取一些数据并解释该数据,就好像那些完全相同的位是不同的数据类型一样?

在C中,如果你有一个int并且希望将它的位解释为float,你会做大致相同的事情,拿一个指针然后转换并解除引用它:

int i = 0x41973333;
float f = *((float*)&i);
Run Code Online (Sandbox Code Playgroud)

这正是ctypes我的示例中使用库的Python代码所做的事情.


Joh*_*ooy 5

我猜这个问题涉及到这一块,你用4个字节,而不是8个十六进制数字的工作.

"\x41\x91\x33\x33" 是一个4字节的字符串,即使它看起来像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)
Run Code Online (Sandbox Code Playgroud)

如果你确实需要处理十六进制数字而不是实际字节,你可以使用struct.pack它来转换它,就像这样

>>> for hx in ["41973333","41995C29","470FC614"]:
...     print(struct.unpack(">f",struct.pack(">i",int(hx,16)))[0])
... 
18.8999996185
19.1700000763
36806.078125
Run Code Online (Sandbox Code Playgroud)