Reputation: 19
I am reading a binary file from the mainframe and I would like to convert the single precession floating point numbers which are currently represented in HEX to be converted to its decimal equivalent in python. For example
X'42808000' ==> should be converted to 128.50 in decimal.. X'C2808000' ==> should be converted to -128.50 in decimal
Are they any built in functions in python that does this. It looks like the internal floating representations are not in IEEE format but the old "S370 mainframe hexadecimal format". Kindly let me know your thoughts on how to convert the same. Thanks
Upvotes: 1
Views: 313
Reputation: 123473
It's unclear from your question where you say the numbers are currently represented in HEX, for the format of the S370 hexadecimal floating-point numbers, whether you meat that they're binary integer or string values, so I wrote a function that will accept either one.
try:
basestring
except NameError: # Python 3
basestring = str
def hextofp(hexadecimal):
""" Convert S370 hexadecimal floating-point number to Python
binary floating point value (IEEE 754).
"""
v = int(hexadecimal, 16) if isinstance(hexadecimal, basestring) else hexadecimal
if v: # not special case of "True 0"
sign = -1 if v & 0x80000000 else 1
exponent = ((v & 0x7f000000) >> 24) - 64 # remove bias
fraction = float(v & 0x00ffffff) / 16777216 # divide by 2**24
return sign * (fraction * 16**exponent)
return 0.0
print('{:.2f}'.format(hextofp('42808000'))) # -> 128.50
print('{:.2f}'.format(hextofp(0x42808000))) # -> 128.50
print('{:.2f}'.format(hextofp('C2808000'))) # -> -128.50
print('{:.3f}'.format(hextofp('40600000'))) # -> 0.375
# True 0
print('{:.1f}'.format(hextofp('00000000'))) # -> 0.0
# largest representable number
print('{:.8g}'.format(hextofp('7fffffff'))) # -> 7.2370051e+75
# smallest positive (normalized) number
print('{:.8g}'.format(hextofp('00100000'))) # -> 5.3976053e-79
# misc examples
print('{:.2f}'.format(hextofp('42500000'))) # -> 80.00
print('{:.2f}'.format(hextofp('41100000'))) # -> 1.00
print('{:.3f}'.format(hextofp('C276A000'))) # -> -118.625
print('{:.2f}'.format(hextofp('427b3333'))) # -> 123.20
print('{:.2f}'.format(hextofp('427b7333'))) # -> 123.45
Upvotes: 1