2010-02-15 5 views
3

나는 Python float 값을 가지고 있으며, 이것을 Microsoft Basic Float (MBF) 형식으로 변환해야합니다. 운 좋게도 인터넷에서 코드를 가져와 역순으로 처리합니다.IEEE Python float을 (를) 마이크로 소프트 기본 float로 변환하는 방법

def fmsbin2ieee(self,bytes): 
    """Convert an array of 4 bytes containing Microsoft Binary floating point 
    number to IEEE floating point format (which is used by Python)""" 
    as_int = struct.unpack("i", bytes) 
    if not as_int: 
     return 0.0 
    man = long(struct.unpack('H', bytes[2:])[0]) 
    exp = (man & 0xff00) - 0x0200 
    if (exp & 0x8000 != man & 0x8000): 
     return 1.0 
     #raise ValueError('exponent overflow') 
    man = man & 0x7f | (man << 8) & 0x8000 
    man |= exp >> 1 
    bytes2 = bytes[:2] 
    bytes2 += chr(man & 255) 
    bytes2 += chr((man >> 8) & 255) 
    return struct.unpack("f", bytes2)[0] 

이제이 과정을 되돌려 야하지만 아직 성공하지 못했습니다. 제발 도와주세요. 당신이 Windows에서 실행하는 동안 이러한 변환을 수행 위하여려고하는 경우에

+0

당신이 8 바이트 파이썬 플로트와 4 바이트 MS 부동의 출력의 입력 여부를 확인하시기 바랍니다이 아닌 8 바이트 MS 플로트. –

답변

4

는 빠르게 제공하는 CVS 기능을 다운로드하고 mbf2ieee.exe를 설치하고 호출 할 수 있습니다 결과 Mbf2ieee.dll (예를 들어를 통해 [하는 ctypes] [2]).

순수 파이썬에서 열심히하고 싶다면 다음과 같이 작동 할 수도 있습니다. (단지 파이썬에 C code here에서 이식했습니다) :

def mbf2ieee(mbf_4bytestring): 
    msbin = struct.unpack('4B', mbf_4bytestring) 
    if msbin[3] == 0: return 0.0 

    ieee = [0] * 4 
    sign = msbin[2] & 0x80 
    ieee_exp = msbin[3] - 2 
    ieee[3] = sign | (ieee_exp >> 1) 
    ieee[2] = (ieee_exp << 7) | (msbin[2] & 0x7f) 
    ieee[:2] = msbin[:2] 

    return struct.unpack('f', ieee)[0] 

문제가있는 경우 입력 값과 예상되는 결과의 예를 제공 할 수 있습니까?

편집 : 당신이 원하는 역 함수의 경우, 그것이 있어야 :

def float2mbf4byte(f): 
    ieee = struct.pack('f', f) 
    msbin = [0] * 4 
    sign = ieee[3] & 0x80 

    msbin_exp = (ieee[3] << 1) | (ieee[2] >> 7) 
    # how do you want to treat too-large exponents...? 
    if msbin_exp == 0xfe: raise OverflowError 
    msbin_exp += 2 

    msbin[3] = msbin_exp 
    msbin[2] = sign | (ieee[2] & 0x7f) 
    msbin[:2] = ieee[:2] 
    return msbin 
+0

Ummmmmm ..... 이것은 bassackwards ... OP는 Python float (8 바이트 IEEE float)에서 MS Basic float로 이동하려고합니다. –

+0

@ 존, 그는 내가 게시 한 코드에 혼란스러워합니다. ieee에게 mbf가 있습니다 - 내 대답에 역기능을 추가하겠습니다. –

+0

@Alex : 4 바이트 IEEE를 통해 8 바이트 IEEE에서 4 바이트 MS로 이동하면 직접 이동하면 손실되는 것보다 더 많은 정밀도가 손실 될 수 있습니다. –

0

글쎄, 나는 float2mbf4byte()을 시도하고 2 수정했다 : 지금 노력하고 있습니다 음의 값을 변환

  1. 을,
  2. for Python 2, ieee는 문자열이 아닌 int의 목록이어야합니다.

코드 조각 :

def float2mbf4byte(f): 
    ieee = [ord(s) for s in struct.pack('f', f)] 
    msbin = [0] * 4 

    sign = ieee[3] & 0x80 
    ieee[3] &= 0x7f 

    msbin_exp = (ieee[3] << 1) | (ieee[2] >> 7) 
    # how do you want to treat too-large exponents...? 
    if msbin_exp == 0xfe: raise OverflowError 
    msbin_exp += 2 

    msbin[3] = msbin_exp 
    msbin[2] = sign | (ieee[2] & 0x7f) 
    msbin[:2] = ieee[:2] 
    return msbin 

def ieee2fmsbin(f): 
    return struct.pack('4B', *float2mbf4byte(f)) 
관련 문제