Pythonで次の16進数文字列を浮動小数点(単精度32ビット)に変換するにはどうすればよいですか?
"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
更新:これを行う方法についてのコメントはPython 3。
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
あなたは基本的に低レベルのビットキャストを実行する方法を尋ねているので、ctypes
モジュールはここで理にかなっていると思います。あなたの質問は、基本的に、いくつかのデータを取得してそのデータをまったく同じビットが異なるデータ型であるかのように解釈するためにPython
Cでintがあり、そのビットをfloatとして解釈したい場合は、おおよそ同じことを行い、ポインターを取得し、それをキャストして間接参照します。
int i = 0x41973333;
float f = *((float*)&i);
それはまさに、私の例でctypes
ライブラリを使用するPythonコードが実行していることです。
この質問は this one に関連していて、8桁の16進数ではなく4バイトで作業していると思います。
"\x41\x91\x33\x33"
は16バイトのように見えても4バイトの文字列です
>>> 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)
実際のバイトではなく16進数の文字列を処理する必要がある場合は、次のように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
16進文字列を2文字のチャンク(バイト)にスライスし、各チャンクをint形式で適切なバイトにし、完了したらstruct.unpackを実行します。つまり:
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]
必要に応じて発光:
18.8999996185 18.8999996185
19.1700000763 19.1700000763
36806.078125 36806.078125