Forget casts. Use memcpy
.
float xhalf = 0.5f*x;
uint32_t i;
assert(sizeof(x) == sizeof(i));
std::memcpy(&i, &x, sizeof(i));
i = 0x5f375a86 - (i>>1);
std::memcpy(&x, &i, sizeof(i));
x = x*(1.5f - xhalf*x*x);
return x;
The original code tries to initialize the int32_t
by first accessing the float
object through an int32_t
pointer, which is where the rules are broken. The C-style cast is equivalent to a reinterpret_cast
, so changing it to reinterpret_cast
would not make much difference.
The important difference when using memcpy is that the bytes are copied from the float
into the int32_t
, but the float
object is never accessed through an int32_t
lvalue, because memcpy
takes pointers to void and its insides are “magical” and don’t break the aliasing rules.