Python: 将十六进制解包为双精度浮点数
这是值
value = ['\x7f', '\x15', '\xb7', '\xdb', '5', '\x03', '\xc0', '@']
我尝试了。
unpack('d', value)
但他需要一个字符串进行解包。现在它是一个列表。但当我将其更改为字符串时,长度将从8变为58。但双精度浮点数需要一个长度为8的值。
使用''.join
函数将列表转换为字符串:
>>> value = ['\x7f', '\x15', '\xb7', '\xdb', '5', '\x03', '\xc0', '@']
>>> ''.join(value)
'\x7f\x15\xb7\xdb5\x03\xc0@'
>>> from struct import unpack
>>> unpack('d', ''.join(value))
(8198.4207676749193,)
>>> from struct import unpack
>>> value = ['\x7f', '\x15', '\xb7', '\xdb', '5', '\x03', '\xc0', '@']
>>> unpack('<d', ''.join(value))[0]
8198.42076767492
>>> unpack('>d', ''.join(value))[0]
1.4893584640656973e+304
仅为娱乐 - 这里是显式解码的方法
>>> value = ['\x7f', '\x15', '\xb7', '\xdb', '5', '\x03', '\xc0', '@']
>>> bytes = map(ord,reversed(value))
>>> sign = (1,-1)[bytes[0]>>7]
>>> exp = ((0x7f&bytes[0])<<4) + (bytes[1]>>4) - 1023
>>> mantissa = reduce(lambda x,y: (x<<8) + y, bytes[2:], bytes[1]&0xf)
>>> sign*2**exp*(1+mantissa*2**-52)
8198.4207676749193
>>> import struct
>>> def double_to_hex(f):
return hex(struct.unpack('<Q', struct.pack('<d', f))[0])
>>> def hex_to_double(f):
return struct.unpack('!d', bytes.fromhex(f))[0]
>>> data = 12.982947
>>> hex_value = double_to_hex(data)
>>> print(hex_value)
0x4029f744d4456712
>>> double_value = hex_to_double(hex_value[2:])
>>> print(double_value)
12.982947
您还可以使用 ctypes
库进行此转换。
from ctypes import pointer, cast, POINTER, c_double, c_longlong
def convert_longlong_to_double(s):
try:
i = int(s, 10) # convert from hex to a Python int
except Exception:
i = s
cp = pointer(c_longlong(i)) # make this into a c long long
fp = cast(cp, POINTER(c_double)) # cast the long long pointer to a double pointer
return fp.contents.value # dereference the pointer, get the double
使用示例:
r1 = 0
r2 = 0
r3 = 16473
r4 = 0
longlong = (r1 << 16) | (r2 << 0) | (r3 << 48) | (r4 << 32)
print(convert_longlong_to_double(longlong))