How to convert binary representation with IEEE byte (small number)

I am decrypting a binary that has decimal numbers represented by four bytes, a little endian. For example, 94 53 F0 40represents 7.510202. Unfortunately, Python gives me 7.51020240784.

When I try to analyze this data with unpack("<f",sampledata)[0], I do not get the exact representations of the original due to the way Python stores the values ​​(for more information see http://bugs.python.org/issue4114 ).

Unfortunately, I need to get the same idea - regardless of the discussion about the inaccuracy of floats, because I need to write these values ​​to a text file with the same number of decimal places, since they were originally written to a binary file with.

I would rather stick with Python if possible, but I am happy to implement the solution in C if necessary. The reason why I cannot just trim the return of the decompression function is because I cannot guarantee how many decimal places the original float has, for example it 0C 02 0F 41represents 8.938 according to my hex editor from the source binary, which has only 3 decimal places .

To be clear, I need to take four hexadecimal bytes as my input and output either text / ASCII or a numeric representation of the 32-bit IEEE floating point number, which has the same number of decimal places as the creator of the file provided. I will use the result to create the CSV source file of binary data, and not to perform 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])
+4
source share
2 answers

IEEE 4 7 . , , - unpack 7 . Python float .

def magnitude(x):
    return 0 if x==0 else int(math.floor(math.log10(abs(x)))) + 1

def round_total_digits(x, digits=7):
    return round(x, digits - magnitude(x))

>>> round_total_digits(struct.unpack('<f', '\x94\x53\xF0\x40')[0])
7.510202
>>> round_total_digits(struct.unpack('<f', '\x0C\x02\x0F\x41')[0])
8.938
>>> x = struct.unpack('<f', struct.pack('<f', 12345.67))[0]
>>> x
12345.669921875
>>> round_total_digits(x)
12345.67

, , , . .

+4
  uint32_t b = 0x40F05394 + printf("");

  printf("%.11f\n", *(float *) &b);

() :

7.51020240784

f. python . ​​

:

print "%.11f" % (unpack("<f",hexbytes)[0])

, .

C :

      int p = 11;
      printf("%.*f\n", p, *(float *) &b);  // 11 here can be a variable

Python:

     p = 11
     print "%.*f" % (p, (unpack("<f",hexbytes)[0]))  # 11 can be a variable

, 0x40F05394 0x9453F040, .

+1

Source: https://habr.com/ru/post/1547951/


All Articles