num2bit
manually converts the in-memory representation of a IEEE standard double
to 32-bit, fixed-point, two's complement signed format, using rounding to the nearest integer.
Converting through a union
is unsafe because it violates strict type aliasing rules. You're not allowed to write to one member of a union, then read from another. It would be more proper to do something like
static int32_t num2bit(double n)
{
int32_t o;
n += 6755399441055744.0; /* 2^52 + 2^51 */
memcpy( & o, & n, sizeof o ); /* OK with strict aliasing but must mind endianness. */
return o;
}
This function is probably intended as an optimization, but its value as such is dubious. You need to re-test on every new microprocessor and ensure it's only used on hardware where it's faster.
Note also that a plain C floating-integral conversion uses round-to-zero, or truncation. This function is perhaps not intended to handle fractional values at all.
num2u64
is a Windows-specific workaround (note the #ifdef
). When converting a double
value greater than 263 to an unsigned integer, "something bad" happens (perhaps saturation), so the author subtracts 264 to make it a negative number, then casts that to a signed, negative integer, then casts the result to an unsigned integer which will have a value greater than 263.
In any case, you can tell the intent is simply to convert a double
to a uint64_t
, since that's all it does on non-Windows platforms.