2009-10-20 7 views
27

파이썬에서 다음 16 진수를 float (단 정밀도 32 비트)로 변환하는 방법은 무엇입니까? 나는이 질문을 추측하고있어16 진수를 float으로 변환

"41973333" -> 1.88999996185302734375E1 

"41995C29" -> 1.91700000762939453125E1 

"470FC614" -> 3.6806078125E4 

답변

47
>>> 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에

+12

python3에서는 '41973333'대신'bytes.fromhex ('41973333')'를 사용해야합니다 .decode ('hex')' –

5

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 
12

기본적으로 낮은 수준의 데이터 유형으로 작업 할 수있는 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 라이브러리를 사용하는 파이썬 코드가 무엇을하는지 알 수 있습니다.

4

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 
0

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는 ...

모두가 지금 생각에 대한 생각 좋다 (나는 (업데이트 포함) 내가 할 수있는 경우 나중에이 코드를 편집 할 수 있습니다). :)

+0

코드가 통과 할 수 없습니다 ... – SamB

-1

16 진수 문자열에 선행 0이 있으면 ctypes 방식이 작동하지 않습니다. 사용하지 마십시오.

관련 문제