I got Python float value and I need to convert it in to Microsoft Basic Float (MBF) format. Luckily, Got some code from internet that does the reverse.
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]
Now I need to reverse this process, but no success yet. Any help please.
If you're going to perform these conversions while running under Windows, faster might be to download and install mbf2ieee.exe and call the CVS
function offered by the resulting Mbf2ieee.dll
(e.g. via [ctypes][2]).
If you're keen to do it in pure Python, I think (but I can't test, having no MBF numbers at hand) that the following might work (I just ported it to Python from 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]
If this has problems, can you give some examples of input values and expected results?
Edit: if it's the reverse function you want, it should be:
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
Well, I tried float2mbf4byte()
and made 2 modifications:
- converting negative values is now working,
- for Python 2, ieee should be list of int's, not string
The snippet:
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))
来源:https://stackoverflow.com/questions/2268191/how-to-convert-from-ieee-python-float-to-microsoft-basic-float