-3

I have been trying to figure this out for some time now and i get nowhere. I have two unsigned integers. This means four bytes.

3A BC 00 00

These represent a float value. I want to convert them to float using python. I can do this with python using struct.unpack.

Specifically:

values = [0x3A, 0xBC, 0x00, 0x00]
struct.unpack('>f', bytes(values))

Can someone explain this particular unpack command?

I know that the > part reverses the bits (big endian implementation). So they will be 00 00 BC 3A. What does f does? According to the docs it means float... What does this mean? I tried omitting it but i got struct.error: unpack requires a buffer of 0 bytes

Finally, why the casting to bytes happen?

user1584421
  • 3,499
  • 11
  • 46
  • 86
  • Specifying endianness changes the order of bytes, not individual bits. – sj95126 Sep 01 '22 at 23:20
  • 1
    *"I have two unsigned integers. This means four bytes."* - well not really, depends on the size of one integer... *"the > part reverses the bits"* - the bytes actually, but no, it keeps them as is, with `3a` as most significant byte. *Little endian* would instead reverse them, using `00` as most significant byte. *"What does f does"* I'd suggest to read [the documentation](https://docs.python.org/3/library/struct.html). *"why the casting to bytes happen"* - because `struct.unpack` wants a bytes-like object, i.e. `bytes` or `bytearray`. – Marco Bonelli Sep 01 '22 at 23:21
  • @sj95126 You are corrected, i edited the question. – user1584421 Sep 01 '22 at 23:24
  • @MarcoBonelli Thanks! I have read teh documentation, but do not understand the `f` part... – user1584421 Sep 01 '22 at 23:25
  • The `f` says to treat the 4 bytes as a floating-point number, rather than an integer, or an ASCII string, or one of the other possibilities. – chepner Sep 01 '22 at 23:44

1 Answers1

2

The struct module deals with conversion between python objects and a contiguous sequence of bytes. [0x3A, 0xBC, 0x00, 0x00] is a list of python integers (that is, references to int objects), not a contiguous sequence of bytes. A bytes object is a contiguous sequence of bytes and can be initialized with an iterable of integers between 0 and 255, so that's the first step.

Now, how should python interpret these bytes? Are they an integer, a bunch of floats, a bunch of characters? That's what the format string is for. "f" means "grab me a 4 byte float". The ">" is big-endian as you note, but its a bit more subtle. Python will grab 4 bytes, then deal with the endianness, and finally do the float conversion. Suppose the input was [0x3A, 0xBC, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44]? The format ">ff" would return 2 floats.

Finally, that's not "two integers". Its a sign bit, 8 bit exponent and 23 bit mantissa which is a standard format for single precision floats.

tdelaney
  • 73,364
  • 6
  • 83
  • 116