Portable serialisation of IEEE754 floating-point values

c, endianness, floating-point, ieee-754, portability

Solution

Much simpler, and depending on the same assumption as yours (which is that float and integer types have the same byte order, and is almost universally valid -- realistically you'll never encounter a system where it isn't true):

#include <string.h>

float htonf(float val) {
    uint32_t rep;
    memcpy(&rep, &val, sizeof rep);
    rep = htonl(rep);
    memcpy(&val, &rep, sizeof rep);
    return val;
}

Any reasonably good compiler will optimize away the two `memcpy` calls; they are present to defeat over-eager strict aliasing optimizations, so this ends up being as efficient as `htonl` plus the overhead of a single function call.

Problem

I've recently been working on a system that needs to store and load large quantities of data, including single-precision floating-point values. I decided to standardise on network byte order for integers, and also decided to store floating point values in big-endian format, i.e.: ``` |-- Byte 0 --| |-- Byte 1 -| Byte 2 Byte 3 # ####### # ####### ######## ######## Sign Exponent Mantissa 1b 8b, MSB first 23b, MSB first ``` Ideally, I want to provide functions like `htonl()` and `ntohl()`, since I have already been using these for swabbing integers, and I also want to implement this in a way that has as much platform-independence as possible (while assuming that the `float` type corresponds to IEEE754 32-bit floating point values). Is there some way, possibly using `ieee754.h`, to do this? I have one answer that seems to work, and I will post it below, but it seems pretty slow and inefficient and I would appreciate any suggestions about how to make it faster and/or more reliable.

Original source

Related problems