4

I have a program which reads in a binary file of single precision IBM floating points numbers. The goal is to convert these to IEEE754 floating points (in binary format). Currently I am reading in the binary IBM number, converting it to a float and then converting that into its IEEE754 format (single precision). For some reason I am not getting quite the output I want.

My input:

11000010011101101010000000000000

Output I want:

11000010111011010100000000000000

Output i am getting:

1100000001011101101010000000000000000000000000000000000000000000

Code:

import struct

getBin = lambda x: x > 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:]

def floatToBinary64(value):
    val = struct.unpack('Q', struct.pack('d', value))[0]
    return getBin(val)

with open("test.bin", "rb") as f:
    while True:
        ibm = f.read(32);
        if not ibm:
            break

        print(ibm)
        ibm = int(ibm, 2)

        sign = (ibm >> 31) & 0x01
        exponent = (ibm >> 24) & 0x7f
        mantissa = (ibm & 0x00ffffff) / pow(2, 24)

        decimal = (1 - 2 * sign) * mantissa * float(pow(16, exponent - 64))


        print(decimal)

        binary = floatToBinary64(decimal)

        print(binary)

How can I modify this code to get my desired output?

eZ_Harry
  • 816
  • 9
  • 25
  • `floatToBinary64` is defined near the start. It is dealing with a 'Q' record which is a long long (i.e. 64-bit/8-byte), but the desired output is clearly 32-bit/4-byte. – Alex Taylor Oct 02 '18 at 02:25
  • Oh okay, that makes sense. Do you know what I would need to change it to? – eZ_Harry Oct 02 '18 at 02:59
  • 1
    Possible duplicate of [python: unpack IBM 32-bit float point](https://stackoverflow.com/questions/7125890/python-unpack-ibm-32-bit-float-point) – ReAl Oct 02 '18 at 07:31
  • [Convert IBM 360 floating-point format to IEEE-754](https://stackoverflow.com/q/52574893/995714) – phuclv Oct 02 '18 at 11:48

1 Answers1

2

In floatToBinary64, val = struct.unpack('Q', struct.pack('d', value))[0] converts the C double representation of value to an unsigned long long. (Python types are not strictly specified; a Python implementation typically rely on a C implementation and inherits many of its properties.) In many common C implementations, double is the IEEE-754 basic 64-bit binary format, while float is the IEEE-754 basic 32-bit binary format.

To change this to 32 bit, change it to val = struct.unpack('I', struct.pack('f', value))[0]. To match that, rename the routine to floatToBinary32.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312