I am decoding a binary file, which has decimal numbers represented by four bytes, little endian. For example, 94 53 F0 40
represents 7.510202. Unfortunately, Python is giving me 7.51020240784.
When I try to parse this data using unpack("<f",sampledata)[0]
I don't get exact representations of the original, due to the way Python stores values (for more information, see http://bugs.python.org/issue4114).
Unfortunately, I do need to get the exact same representation- regardless of discussions about the inaccuray of floats, because I need to write these values to a text file, with the same number of decimal places as they were initially written to the binary file with.
I'd rather stick to Python if possible, but am happy to implement a solution in C if necessary. The reason I cannot simply truncate the return of the unpack function, is that I cannot guarantee how many decimal places the original float had, for example 0C 02 0F 41
represents 8.938 according to my hex editor, from the original binary file, which only has 3 decimal places.
To be clear, I need to take four hex bytes as my input, and output either a text/ASCII or number representation of the IEEE 32-bit floating point number, that has the same number of decimal places as was intended by the creator of the file. The output I will use to create a CSV of the original binary data file, not for actually performing any calculations.
Any suggestions?
Example:
from __future__ import print_function
from struct import *
print("Should print 7.510202")
hexbytes = b"\x94\x53\xF0\x40"
# 01101001 11001000 11110001 01000000
# should print 7.510202
print(unpack("<f",hexbytes)[0])
94 53 F0 40
does not represent7.510202
; that value isn't exactly representable in either single- or double-precision IEEE 754 binary floating-point. It represents the number7.5102024078369140625
(exactly). If you need more information from the original text file (like the number of decimal places originally used to describe the number), you're going to have to track that information separately. By the time you pass to just a single-precision float, that information is gone. – Mark Dickinson"%.7g" % x
. – Mark Dickinsonround
function but it only works if you already know how many decimals to the right are required, and for arbitrary input that can change drastically. – Mark Ransom