On Fri, Feb 12, 2021 at 6:59 PM Lux Lang <

[hidden email]> wrote:

>

> Hello, everyone.

>

> I have found a bug in Lua 5.4.2.

>

> The value of math.mininteger is the integer -9223372036854775808.

> If you were to write the number itself, instead of accessing it through the math.mininteger constant, the Lua parser would instead produce the float -9.2233720368548e+18

>

> This occurs both on the REPL, as well as when loading a Lua file.

>

> Funny enough the value just next to math.mininteger, which is to say -9223372036854775807, correctly parses into an integer instead of a float. So it seems only math.mininteger suffers this bug. The value of math.maxinteger also correctly parses into an integer.

>

> I can work around this bug, but I hope it's chosen to be fixed.

This is a caused by the fact that the lexer, as is the case in many

other languages, does not actually recognize negative numbers. So

-9223372036854775808 is not lexed as a single token, but as two

tokens: a minus operator followed by a *positive* integer. The parser

and compiler then turn that token sequence into a load of the positive

number followed by a unary minus operation.

The catch is that in a two's complement representation (used by

virtually every modern architecture out there these days), the

absolute value of the most negative number that can be represented by

a given number of bits is always one greater than the largest positive

integer that can be represented by the same number of bits. So

9223372036854775807 fits in a 64-bit signed integer, but

9223372036854775808 does not, even though -9223372036854775808 does.

Since 9223372036854775808 is too large to be represented as a 64-bit

signed integer, Lua coerces it to a float (technically, a

double-precision floating point number) at parse time.

When you access math.mininteger, Lua actually uses a system C header

macro to give you the proper minimum integer as defined by your system

C library, which is guaranteed to parse correctly in C code and

therefore be correctly represented in the memory bits.

Your second email about 0x8000000000000000 parsing correctly is

because there is no unary minus operation involved. Lua always parses

hexadecimal constants always as a positive integer, overflowing if

necessary. So 0x8000000000000000 parses as positive

9223372036854775808, which overflows to -9223372036854775808.