How to interpret 4 bytes as a 32-bit float using Python

28,933

Solution 1

For detail see Python Struct. For your specific question:

import struct

# if input is string, per @robyschek will fail on python 3
data=b'\x64\xd8\x64\x3f'  
print struct.unpack('<f', data)   #little endian
print struct.unpack('>f', data)   # big endian

#your input  
list1=[0x64, 0xD8, 0x6E, 0x3F]
# aa=str(bytearray(list1))  # edit: this conversion wasn't needed
aa= bytearray(list1) 
print struct.unpack('<f', aa)
​

output:

(0.8939268589019775,)
(3.193376169798871e+22,)
(0.9329893589019775,)

Solution 2

If you're willing to use a big library that's really for handling (large) arrays of numbers efficiently:

import numpy as np
data_bytes = np.array([0x64, 0xD8, 0x6E, 0x3F], dtype=np.uint8)
data_as_float = data_bytes.view(dtype=np.float32)
print(data_as_float)

This will also work on big byte arrays; then you get an array of floats.

Share:
28,933
programmar
Author by

programmar

Updated on July 09, 2022

Comments

  • programmar
    programmar almost 2 years

    I am sort of a novice to the Python language and am having a hard time doing something I could very easily do with C++ or Java but for some reason seems so convoluted to do in Python. I have the following four bytes in an array (in big endian order):

    [0x64, 0xD8, 0x6E, 0x3F]
    

    I already know beforehand what these bytes represent. They specify the following 32-bit floating-point number: 0.932989

    What are the steps I need to perform using Python (preferably v3.2.1 and without using extra imports) to interpret those 4 bytes as that float and store that number in a variable which I can manipulate as a 32-bit floating-point value? I.e. so i can use it just as the following variable myVar = 0.932989

    I've tried:

    x = [0x64, 0xd8, 0x6e, 0x3f]
    y = int.from_bytes(x, byteorder='little', signed=False) #interpret bytes as an unsigned little-endian integer (so far so good)
    z = float(y) #attempt to cast as float reinterprets integer value rather than its byte values
    

    y has the right expected integer interpretation of those bytes, which is 1064228964, the problem comes when casting that to a 32-bit float. Instead of casting the raw bytes of y as a float, it casts the integer representation of those bytes, so z contains 1064228964.0 instead of the desired value of 0.932989. Is there maybe something equivalent to int.from_bytes that I can use to perform this simple task? Perhaps something like float.from_bytes?

  • robyschek
    robyschek about 8 years
    unpack works on bytearrays, so no need to cast to str, and even more, on py3 unpack does not accept str and will fail
  • roadrunner66
    roadrunner66 about 8 years
    @robyschek : Ty, wanted to give string answer, since that's common. Ty for pointer on py3.
  • programmar
    programmar about 8 years
    For some reason I get aa="bytearray(b'd\\xd8n?')". is there a way to fix this?
  • programmar
    programmar about 8 years
    Yes. I type list1=[0x64, 0xD8, 0x6E, 0x3F] and then aa=str(bytearray(list1)), then I type aa to see its contents, and the answer from python is "bytearray(b'd\\xd8n?')".
  • roadrunner66
    roadrunner66 about 8 years
    Please see my edit. You don't need the aa=str(...) portion, just passing the bytelist is OK, your error happens in Python3, which is why I didn't notice it (Python 2.7 here).