Python Hex to Float Conversion

3.5/5 - (2 votes)

Problem Formulation

πŸ’¬ Question: Given a hexadecimal string. How to convert it to a float?

Examples

Here are a few example conversions where each hex string represents four bytes, i.e., two hex characters per byte.

Hex StringFloat
'0f0f0f0f'7.053344520075142e-30
'4282cbf1'65.39832305908203
'43322ffb'178.1874237060547
'534f11ab'889354649600.0

Solution – Convert Hex to Float

The expression struct.unpack('!f', bytes.fromhex('12ff01ca'))[0] converts a hexadecimal string '12ff01ca' to a bytes object and then to a float using the specifier '!f' of the struct.unpack() function.

import struct
print(struct.unpack('!f', bytes.fromhex('12ff01ca'))[0])
# 7.053344520075142e-30

Let’s deconstruct this expression.

First, create a bytes object from the hex string:

>>> bytes.fromhex('12ff01ca')
b'\x12\xff\x01\xca'

Second, pass it in the struct.unpack() function:

>>> struct.unpack('!f', b'\x12\xff\x01\xca')
(1.6093203504465906e-27,)

Third, get the first tuple value (the output of the struct.unpack() function is always a tuple even if only one tuple value exists):

>>> (1.6093203504465906e-27,)[0]
1.6093203504465906e-27

You can learn more about the specifications of the struct library calls here:

πŸ‘‰ This module performs conversions between Python values and C structs represented as Python bytes objects.

Generally, the most important functions in the library are:

  • pack(),
  • unpack(),
  • calcsize(),
  • pack_into() and
  • unpack_from().

You provide the format of the data using specifiers like these:

?: boolean
h: short
l: long
i: int
f: float
q: long long int

In our case, you only need the 'f' format specifier with the '!' prefix. The format specifier '!' represents the network byte order (big endian).

Convert Hex List to Float List

If you want to convert multiple hex strings in a list to a float list, you can use a simple for loop like so:

import struct

lst = []
for i in ['4282cbf1', '43322ffb', '534f11ab', '0f0f0f0f']:
    lst.append(struct.unpack('!f', bytes.fromhex(i))[0])
print(lst)
# [65.39832305908203, 178.1874237060547, 889354649600.0, 7.053344520075142e-30]