Bug when parsing the value of math.mininteger

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug when parsing the value of math.mininteger

Lux Lang
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.

Best regards.
Reply | Threaded
Open this post in threaded view
|

Re: Bug when parsing the value of math.mininteger

Lux Lang
I just tested with the hexadecimal representation of the same number, which is 0x8000000000000000, and Lua correctly parses it as an integer.
So, it appears that only Lua's decimal parser is bugged.

On Fri, Feb 12, 2021 at 7: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.

Best regards.
Reply | Threaded
Open this post in threaded view
|

Re: Bug when parsing the value of math.mininteger

Jonathan Goble
In reply to this post by Lux Lang
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.
Reply | Threaded
Open this post in threaded view
|

Re: Bug when parsing the value of math.mininteger

Lux Lang
Is this within the realm of what is possible to fix in Lua?

On Fri, Feb 12, 2021 at 8:33 PM Jonathan Goble <[hidden email]> wrote:
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.
Reply | Threaded
Open this post in threaded view
|

Re: Bug when parsing the value of math.mininteger

Jonathan Goble
On Fri, Feb 12, 2021 at 7:38 PM Lux Lang <[hidden email]> wrote:
>
> Is this within the realm of what is possible to fix in Lua?

Most likely not, unless the lexer learns to read a unary minus
followed by a number as a single token rather than two tokens.

P.S. You appear to be new to mailing lists (apologies if I've guessed
that incorrectly), so here's a quick friendly tip about mailing list
etiquette: It's considered proper to post your reply below the quote
rather than above it, as I am doing here. In Gmail's web interface,
you'll need to click the little three-dot icon above the Send button
to expand the quote and then scroll to the bottom. It's also proper to
trim the quote down to what you are specifically responding to (making
sure you keep any necessary context as well).