Python – How to convert IEEE Python float to Microsoft Basic float

How to convert IEEE Python float to Microsoft Basic float… here is a solution to the problem.

How to convert IEEE Python float to Microsoft Basic float

I

got a Python floating-point value that I need to convert to Microsoft Basic Float (MBF) format.
Fortunately, some code that does the opposite is obtained from the Internet.

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 the process, but it hasn’t worked out yet. Please provide any assistance.

Solution

If you are performing these conversions while running under Windows, it may be faster to download and install mbf2ieee.exe and call the generated CVS functions provided by MBF2ieee.dll (e.g. via [ctypes][2]).

If you’re keen on doing this in pure Python, I think (but I can’t test, I don’t have an MBF number on hand) the following might work (I just took it from.) C code here Porting to 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]

If this is problematic, can you give some examples of input values and expected results?

EDIT: If it’s the inverse 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

Related Problems and Solutions