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)