Convert float to hex string

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Convert float to hex string

Post by blmorris » Mon Jan 19, 2015 10:13 pm

I have a nice graphical demonstration of orientation sensing using the micropython navigation pyskin but sadly, there is no micropython involved yet. My next goal is to program the pyboard to replace the arduino as the link to the host.
Richard Bartlett from richards-tech (who wrote the RTIMULib software used for that demo) helped me to figure out the data format used in the serial link; the arduino transmits the 4-byte hex representation of the floating point data.
I can use CPython to convert the data back into a float, confirming that the data I extract is a sane floating point number.

Now I need to generate that hex data from a float on the pyboard.
The following code (from Stack Overflow) can do the trick:

Code: Select all

def float_to_hex(f):
    return hex(struct.unpack('<I', struct.pack('<f', f))[0])

float_to_hex(17.5)    # Output: '0x418c0000'
But I don't think we have these functions available yet in micropython. Any ideas?

-Bryan

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Convert float to hex string

Post by blmorris » Mon Jan 19, 2015 11:09 pm

BTW, converting directly to a little-endian bytes object will work just as well.

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: Convert float to hex string

Post by Damien » Tue Jan 20, 2015 12:59 am

Try:

Code: Select all

import array
bytes(array.array('f', [17.5]))
hex(struct.unpack('<I',bytes(array.array('f', [17.5]))))

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Convert float to hex string

Post by blmorris » Tue Jan 20, 2015 4:08 am

Great, that works. And if I study really hard I might someday even understand why…
In fact, the second line

Code: Select all

bytes(array.array('f', [17.5]))
is exactly what I need to transmit the data; this is the little-endian bytes representation, so the bytes are in the right order. The last line is helpful for pretty-printing and debugging.

One thing- testing on the pyboard and on CPython 3.4, I get slightly different representations in the LSB's:

pyboard:

Code: Select all

>>> bytes(array.array('f', [-0.0029576942324638367]))
b'\xe4\xd5A\xbb'
CPython:

Code: Select all

>>> bytes(array.array('f', [-0.0029576942324638367]))
b'\xe0\xd5A\xbb'
The difference of '0xe4' to '0xe0' is small, and probably won't matter in practice, but is this an issue of the implementation of the floating point hardware or something in our software? The example here is from my data collection, so it isn't contrived. I saw it for a few other instances as well - I should note that CPython returns the same hex representation that I originally extracted from the Arduino data stream.

-Bryan

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Convert float to hex string

Post by dhylands » Tue Jan 20, 2015 7:29 am

@blmorris - The difference is that in CPython floats are stored as a long double (96-bit) (or double (64-bit)), but in MicroPython the floats are 32-bit.

A 32-bit float can only store about 6 significant digits (23-bit mantissa). The difference happens in the conversion from the base-10 representation into the base-2 representation.

In a 32-bit float, bytes(array.array('f', [-0.002957694231])), bytes(array.array('f', [-0.002957694239])), and bytes(array.array('f', [-0.0029576942324638367])) all have the same binary representation.

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: Convert float to hex string

Post by Damien » Tue Jan 20, 2015 9:02 am

blmorris wrote:Great, that works. And if I study really hard I might someday even understand why…
The struct packing of floats in uPy should work, but for some reason is not fully implemented even though all the code is there (as you can see by the fact that the array packing works!). So your original piece of code was right.

Post Reply