Assume I have guarantees that float is IEEE 754 binary32. Given a bit pattern that corresponds to a valid float, stored in std::uint32_t, how does one reinterpret it as a float in a most efficient standard compliant way?
float reinterpret_as_float(std::uint32_t ui) {
   return /* apply sorcery to ui */;
}
I've got a few ways that I know/suspect/assume have some issues:
- Via - reinterpret_cast,- float reinterpret_as_float(std::uint32_t ui) { return reinterpret_cast<float&>(ui); }- or equivalently - float reinterpret_as_float(std::uint32_t ui) { return *reinterpret_cast<float*>(&ui); }- which suffers from aliasing issues. 
- Via - union,- float reinterpret_as_float(std::uint32_t ui) { union { std::uint32_t ui; float f; } u = {ui}; return u.f; }- which is not actually legal, as it is only allowed to read from most recently written to member. Yet, it seems some compilers (gcc) allow this. 
- Via - std::memcpy,- float reinterpret_as_float(std::uint32_t ui) { float f; std::memcpy(&f, &ui, 4); return f; }- which AFAIK is legal, but a function call to copy single word seems wasteful, though it might get optimized away. 
- Via - reinterpret_casting to- char*and copying,- float reinterpret_as_float(std::uint32_t ui) { char* uip = reinterpret_cast<char*>(&ui); float f; char* fp = reinterpret_cast<char*>(&f); for (int i = 0; i < 4; ++i) { fp[i] = uip[i]; } return f; }- which AFAIK is also legal, as - charpointers are exempt from aliasing issues and manual byte copying loop saves a possible function call. The loop will most definitely be unrolled, yet 4 possibly separate one-byte loads/stores are worrisome, I have no idea whether this is optimizable to single four byte load/store.
The 4 is the best I've been able to come up with.
Am I correct so far? Is there a better way to do this, particulary one that will guarantee single load/store?
 
     
     
     
     
    