Convert a float to 4 uint8_t

You can do this illegal operation:

float f = someFloatValue;
uint8_t* i = reinterpret_cast<uint8_t*>(&f);

Although this works most of the time, it is not supported by c++ standard and compilers might generate code with undefined behaviour.

Another solution is using unions:

union{
    float f;
    uint8_t i[4];
}
f = someFloatValue;
// now i's contain the bit pattern of f

It's unclear if all compilers yield consistent results, but it seems safer than the first aproach.

You can also pack the value of f in a 32-bit integer. This, however can result in losing a bit of precision, but depending on how accurately you want to keep f, would be the best solution.


First you should note that the standard imposes no specific size restrictions on float. It's possible that a float wouldn't fit into four bytes on some imaginable architecture (although I'm not aware of any). You should at least (static_)assert that it will fit before attempting anything.

Then I think the simplest way is to assert that CHAR_BIT is 8, and use the legal aliasing to unsigned char* with reinterpret_cast:

static_assert(sizeof(float) == 4);
float f = 0; // whatever value
unsigned char* float_as_char = reinterpret_cast<unsigned char*>(&f);

This totally ignores the endian issue though, so maybe what you really want is to make a copy of the bytes so you can fix that up:

static_assert(sizeof(float) == 4);
float f = 0; // whatever value
uint8_t bytes[4];
std::memcpy(bytes, &f);
// Fix up the order of the bytes in "bytes" now.

You normally do this by casting the float to an array of uint8_t.

In C you can do it like this:

uint8_t *array;
array = (unit8_t*)(&f);

in C++ use the reinterpret_cast

uint8_t *array;
array = reinterpret_cast<uint8_t*>(&f);

Then array[0], ..., array[3] are your bytes.