lua-users home
lua-l archive

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


On 11/27/18, pocomane <pocomane_7a@pocomane.com> wrote:
> -- Min integer literal, BUG ???
> assert(tostring(-9223372036854775808) == '-9.2233720368548e+018')
> assert(math.type(-9223372036854775808) == 'float')

The issue appears to be that the lexer sees '-' separately from the
numeral itself. As such, when reading the number, it must fit in a
non-negative integer, and is then constant-folded to the actual
negative. Incidentally, it appears that this corner case has already
been noticed and is dealt with by the %q format:

lstrlib.c
961:        const char *format = (n == LUA_MININTEGER)  /* corner case? */
962-                           ? "0x%" LUA_INTEGER_FRMLEN "x"  /* use hexa */
963-                           : LUA_INTEGER_FMT;  /* else use default format */

It seems to me that making this particular case work would be rather
involved, and essentially require negative numbers to be first-class
citizens in the grammar, rather than cobbled together through unary
minus and constant folding. I also don't see a satisfying solution
for, e.g. "- 9223372036854775808", "- --[[]]9223372036854775808",
"-(9223372036854775808)", though arguably those are *explicitly* the
negation of positive 9223372036854775808, which doesn't fit, and
really should be an integer.

In any case, the main uses I can see for having that number as a
constant and an integer are qua -2^63 and qua minimum integer. Perhaps
some variation on "-2^63|0", "-1<<63", "~(~0>>1)", or
"-0x8000000000000000" might be suitable? (Though that last one only
happens to work because 0x8000000000000000 == -0x8000000000000000 (64
bits) in 2's complement, and the unchecked overflow from casting to
signed after reading a hex literal may be undefined behavior.)