102

I have a binary file that I have to parse and I'm using Python. Is there a way to take 4 bytes and convert it to a single precision floating point number?

4 Answers 4

134
>>> import struct
>>> struct.pack('f', 3.141592654)
b'\xdb\x0fI@'
>>> struct.unpack('f', b'\xdb\x0fI@')
(3.1415927410125732,)
>>> struct.pack('4f', 1.0, 2.0, 3.0, 4.0)
'\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@'
Sign up to request clarification or add additional context in comments.

6 Comments

This only works for 4 or 8 byte floats. What about 10-byte floats?
I agree with @dplass, what about other floats. And, why is there a comma at the end of this string?
@startec The question was about 4-byte floats. Which string ends with a comma? Only the tuple from struct.unpack has a comma.
@PetrKrampl accuracy of C float (single, 4 bytes) and C double (double, 8 bytes). Python float is really C double. Whatever the accuracy of storing 3.141592654 as a C double, it's lost when it's converted to a C float (by struct.pack) and then back to C double (Python extracts the 4-bytes as a C float and then converts the result back to a C double/Python float). This applies to all implementations of Python that use IEEE754 floating point numbers (CPython does; anyway, I don't know of any non-IEEE754-conformant Python implementation on any system).
Note: to view the individual bytes of the bytearray (indicated by b'), use list(). Ex: list(struct.pack('f', 3.141592654)) returns a list of the individual bytes as [219, 15, 73, 64]. This is very handy.
|
23

Just a little addition, if you want a float number as output from the unpack method instead of a tuple just write

>>> import struct
>>> [x] = struct.unpack('f', b'\xdb\x0fI@')
>>> x
3.1415927410125732

If you have more floats then just write

>>> import struct
>>> [x,y] = struct.unpack('ff', b'\xdb\x0fI@\x0b\x01I4')
>>> x
3.1415927410125732
>>> y
1.8719963179592014e-07
>>> 

1 Comment

Alternately you can reference the list position on the RHS x = struct.unpack('f', b'\xdb\x0fI@')[0]
5

I would add a comment but I don't have enough reputation.

Just to add some info. If you have a byte buffer containing X amount of floats, the syntax for unpacking would be:

struct.unpack('Xf', ...)

If the values are doubles the unpacking would be:

struct.unpack('Xd', ...)

Comments

1

Comment: let's say you are receiving a float variable via MODBUS communication protocol (2 registers, 1 int each), you can convert the message with:

floatvar = struct.unpack('f',int1.to_bytes(2,'big')+int2.to_bytes(2,'big')).

*note MODBUS is big Endian

1 Comment

pack and unpack by default use the machine’s native format and byte order, but if you need big Endian you can use '>f' format string. See docs.python.org/3/library/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.