파이썬에서 다음 16 진수를 float (단 정밀도 32 비트)로 변환하는 방법은 무엇입니까? 나는이 질문을 추측하고있어16 진수를 float으로 변환
"41973333" -> 1.88999996185302734375E1
"41995C29" -> 1.91700000762939453125E1
"470FC614" -> 3.6806078125E4
파이썬에서 다음 16 진수를 float (단 정밀도 32 비트)로 변환하는 방법은 무엇입니까? 나는이 질문을 추측하고있어16 진수를 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
업데이트를 보라 ... 파이썬 3에
는 this one에 관한 당신은 4 바이트가 아닌 8 자리의 16 진수로 노력하고 있습니다.
"\x41\x91\x33\x33"
오히려 실제 바이트보다, 당신은 다음과 같이 변환 할 struct.pack
를 사용할 수있는 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)
당신이 hexdigits의 문자열을 처리해야하는 경우처럼 보이는 경우에도 4 바이트 문자열입니다
>>> for hx in ["41973333","41995C29","470FC614"]:
... print(struct.unpack(">f",struct.pack(">i",int(hx,16)))[0])
...
18.8999996185
19.1700000763
36806.078125
기본적으로 낮은 수준의 데이터 유형으로 작업 할 수있는 the ctypes module을 사용하는 것이 좋습니다. 귀하의 경우에 당신은 당신이 본질적으로 얼마나 낮은 수준의 비트 캐스팅을 수행하는 요구하고 있기 때문에 나는 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
말할 수 있습니다. 귀하의 질문은 기본적으로 파이썬에게 어떤 데이터를 가져 와서 그 데이터를 해석하는 것과 정확히 똑같은 비트가 다른 데이터 유형 인 것처럼 어떻게 해석합니까?
C에서는 int를했고, 부동, 당신은 포인터를 복용 한 후 캐스팅하고 역 참조, 거의 같은 일을 원하는만큼의 비트를 해석하기를 원한다면 :
int i = 0x41973333;
float f = *((float*)&i);
을하고는 정확히 필자의 예에서는 ctypes
라이브러리를 사용하는 파이썬 코드가 무엇을하는지 알 수 있습니다.
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
Gentelmen을이 작업을 수행하는 방법에 대한 의견을 참조하십시오
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
죄송합니다. 작은 ".value"at t 그는 끝 ...
이 코드는 거의 2 년 동안 내 프로그램의 수업으로 사용되었습니다.
(조금 편집하면 쉽게 기능에 넣을 수 있습니다.)
DaniWeb에서 코드에 대한 PyTony의 신용.
비 동적 컴퓨팅 달리,
코드 고정 플로트 크기로 고정 배선 아니고,
과 모든 바이트 크기로 작동한다.
비록 우리는 아직 해결할 몇 가지 버그가 있다고 생각합니다.XDD
는
내가 그것으로 3D 게임 모델을 변환하는 문제가 있었다 havn't는 ...
모두가 지금 생각에 대한 생각 좋다 (나는 (업데이트 포함) 내가 할 수있는 경우 나중에이 코드를 편집 할 수 있습니다). :)
코드가 통과 할 수 없습니다 ... – SamB
16 진수 문자열에 선행 0이 있으면 ctypes 방식이 작동하지 않습니다. 사용하지 마십시오.
python3에서는 '41973333'대신'bytes.fromhex ('41973333')'를 사용해야합니다 .decode ('hex')' –