lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hello David,

Saturday, September 3, 2005, 7:10:20 AM, you wrote:

> Beats me. How  does the following from luaconf.h work? 

> union luai_Cast { double l_d; long l_l; };
> #define lua_number2int(i,d) \
>   { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }

The large number is 2^52 + 2^51.  A double on IX86 architecture has 53
bits precision, stored in a 52-bit mantissa.  The mantissa is layed
out in little endian order, starting at the first byte of the double.
So bytes 0-3 in a double represent bits 0-31 of the mantissa.

If a double d is integral and in the long range, then 2^52 + 2^51 + d
is always a 53 bit number (i.e. bit 52 is 1) of which the least
significant 4 bytes exactly represent the number d as a long, even if
d is negative.  The union simply addresses these lowest 4 bytes.

I wonder if the same trick works for big endian IEEE 754 based
architectures if we adjust it like so:

    union luai_Cast { double l_d; long l_l[2]; };
    #define lua_number2int(i,d) \
     { volatile union luai_Cast u; \
       u.l_d = (d) + 6755399441055744.0; \
       (i) = u.l_l[1]; }

Did anyone check?

--
Wim