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.