Date: Fri, 26 Jul 2013 14:48:45 -0400
On Jul 26, 2013, at 2:35 PM, Jeffrey Yasskin <jyasskin_at_[hidden]> wrote:
> Howard, if Gaby's right that new(&memory) int; leaves the object with
> indeterminate value even if 'memory' started with a defined value (and
> I think he is), then that's the rule you're breaking when you
> explicitly change the active member of your union and then read the
> new member.
Ok, what if I change the active member this way:
float InverseSquareRoot4(float x)
{
union U
{
float as_float;
int32_t as_int;
};
U u = {x};
// current member is as_float
size_t active_member = 0;
// temporary buffer
alignas(U) char tmp[sizeof(U)];
float xhalf = 0.5f*x;
// Prepare to read from as_int
if (active_member != 1)
{
std::memcpy(tmp, &u.as_float, sizeof(U));
std::memcpy(&u.as_int, tmp, sizeof(U));
active_member = 1;
}
// current member is as_int
u.as_int = 0x5f3759df - (u.as_int>>1);
// Prepare to read from as_float
if (active_member != 0)
{
std::memcpy(tmp, &u.as_int, sizeof(U));
std::memcpy(&u.as_float, tmp, sizeof(U));
active_member = 0;
}
// current member is as_float
u.as_float = u.as_float*(1.5f - xhalf*u.as_float*u.as_float);
return u.as_float;
}
Howard
> Howard, if Gaby's right that new(&memory) int; leaves the object with
> indeterminate value even if 'memory' started with a defined value (and
> I think he is), then that's the rule you're breaking when you
> explicitly change the active member of your union and then read the
> new member.
Ok, what if I change the active member this way:
float InverseSquareRoot4(float x)
{
union U
{
float as_float;
int32_t as_int;
};
U u = {x};
// current member is as_float
size_t active_member = 0;
// temporary buffer
alignas(U) char tmp[sizeof(U)];
float xhalf = 0.5f*x;
// Prepare to read from as_int
if (active_member != 1)
{
std::memcpy(tmp, &u.as_float, sizeof(U));
std::memcpy(&u.as_int, tmp, sizeof(U));
active_member = 1;
}
// current member is as_int
u.as_int = 0x5f3759df - (u.as_int>>1);
// Prepare to read from as_float
if (active_member != 0)
{
std::memcpy(tmp, &u.as_int, sizeof(U));
std::memcpy(&u.as_float, tmp, sizeof(U));
active_member = 0;
}
// current member is as_float
u.as_float = u.as_float*(1.5f - xhalf*u.as_float*u.as_float);
return u.as_float;
}
Howard
Received on 2013-07-26 20:48:41