lua-users home
lua-l archive

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


As well, if you add 1 to the MAX_INT value in Lua should not wrap around.

It's a fact that Lua implementations tried to optimize the operations on its "number" type to avoid using floatting points as much as possible, so that it could use the integer arithmeric of C or C++. But the number type is larger in range and precision than that. In some cases, Lua integers cannot fit the native integers in C and will still become floatting points (possibly with loss of precision and rounding for the lowest bits of large absolute values).

Optimization of operations on Lua numbers is then tricky, and implementations should care about it (and should raise overflows only in case of overflows of floatting points with a too large exponent, or at least returning signed "infinite" values which are also valid Lua number values).

If Lua code wants to wrap around, I really think that Lua should provide a scoping declaration or annotation for that (we've already spoken about weak references with "*toclose" which now requires such annotation). It's high time for Lua to think about generalizing a syntax for annotations (not just for declarations of "*toclose" variables, but also for expressions) and it's another argument for changing "*toclose" into "@toclose".

I still propose the syntax "@ANNOTATION_ID" or "@{ ANNOTATION_ID, parameters...}" for these annotations, to be used before a declared name or before a subexpression in parentheses, rather than "*ANNOTATION_ID" just before a declared name.


Le ven. 10 mai 2019 à 19:56, Philippe Verdy <verdy_p@wanadoo.fr> a écrit :


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)