lua-users home
lua-l archive

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




Le ven. 10 mai 2019 à 16:08, Sean Conner <sean@conman.org> a écrit :
It was thus said that the Great Egor Skriptunoff once stated:
> On Thu, May 9, 2019 at 11:49 PM Sean Conner wrote:
>
> > It was thus said that the Great Egor Skriptunoff once stated:
> > >
> > > BTW, math.abs(1<<63) in both Lua 5.3 and 5.4 returns negative value.
> > > That's a bug.
> >
> >   That's also a bug in most CPUs (those that are 2's complement), although
> > a
> > number will set the overflow flag [1] to signal the condision [2].
> >
> >
> CPUs are making all arithmetic modulo their word (2^32), this is how the
> CPU operations are declared in CPU architecture manual.
> So, it's not a bug in CPU.
>
> Integer operators in Lua are explicitly declared modulo 2^64 (Lua manual
> section 3.4.1 - Arithmetic operators), so the following is OK:
> assert(-INT_MIN==INT_MIN)

  Actually, GCC disagrees:

        #include <limits.h>
        #include <assert.h>

        int main(void)
        {
          assert(-INT_MIN == INT_MIN);
          return 0;
        }

        [spc]lucy:/tmp>gcc x.c
        x.c: In function `Main':
        x.c:7: warning: integer overflow in _expression_
        [spc]lucy:/tmp>

  Which is fine, because that's undefined behavior in C.  From the C99
standard, 7.20.6.1.2:

        The abs, labs, and llabs functions compute the absolute value of an
        integer j.  If the result cannot be represented, the behavior is
        undefined.[265]

        [265] The absolute value of the most negative number cannot be
        represented in two's complement.

(Okay, so the code actually compiles, and the programs run without aborting,
but technically speaking, the program above is invoking undefined behavior.)

  Now, quoting section 3.4.1 of the Lua manual:

        With the exception of exponentiation and float division, the
        arithmetic operators work as follows: If both operands are integers,
        the operation is performed over integers and the result is an
        integer. ...

        In case of overflows in integer arithmetic, all operations wrap
        around, according to the usual rules of two-complement arithmetic.
        (In other words, they return the unique representable integer that
        is equal modulo 264 to the mathematical result.)

This statement in the doc CANNOT be true, otherwise we are unable to MULTIPLY arbitrary pairs of integers : in case of integer overflow, a floatting point value MUST be returned, because there's a single Lua "number" datatype for both integers and non-integers. Subtypes of numbers, are just internal optimisation hints, but such exceptions have to be handled to change the internal subtype.

And taking the opposite of an integer is simply a multiplication of that integer by integer -1 (and it should be).

I think this is a severe bug of the Lua doc ! So I also agree that assert(-INT_MIN==INT_MIN) should really cause an error, even if it does not (in which case this is an implementation bug, fogetting to check that case)