我有Python浮点值,我需要将其转换为Microsoft Basic Float(MBF)格式。 幸运的是,从互联网上得到了一些相反的代码。
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]
现在我需要扭转这个过程,但还没有成功。请帮忙。
答案 0 :(得分:4)
如果您要在Windows下运行时执行这些转换,则可以更快地下载并安装mbf2ieee.exe并调用生成的CVS
提供的Mbf2ieee.dll
功能(例如,通过[ctypes的] [2])。
如果你热衷于使用纯Python,我认为(但我无法测试,手头没有MBF编号),以下内容可能会起作用(我只是从C code here将其移植到Python ):
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
答案 1 :(得分:0)
好吧,我尝试了float2mbf4byte()
并做了两次修改:
摘录:
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))
答案 2 :(得分:0)
mbf2ieee无法正确转换,请尝试以下操作:
import struct
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
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', bytearray(ieee))[0]
print(mbf2ieee(bytearray(float2mbf4byte(52400126))))
...,您将得到:
builtins.ValueError:字节必须在范围(0,256)中
因为正确的答案是[0,E4,47,9A]
,但是
float2mbf4byte给出[0, 228, 19527, 76]
。
第三个元素不是字节大小值