lua-users home
lua-l archive

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


It appears that in Lua 5.3 usual call to tonumber() is not enough
to correctly parse numbers entered by user from file or keyboard.
For example,
local googol = tonumber("1"..("0"):rep(100))
gives zero (instead of 1e+100 as in previous Lua versions).

Lua 5.3 is hardly suitable for DSL by the similar reason.
For example, when writing the following line in a settings file
my_parameter = 10000000000000000000
most users are expecting to receive a value close to 10^19 instead of
a negative value returned by Lua 5.3.

The behavior currently implemented in Lua 5.3 is very counter-intuitive:
Lua silently gives incorrect result.
To avoid this pitfall, users are forced to always remember the difference
between floats and integers.  It is very inconvenient for typical Lua user.
I doubt that such people exist who really need integer overflow to be
interpreted as useful feature when parsing decimal numbers entered by user.

IMO, both Lua parser and tonumber() function should return correct
float values in case of integer overflow.
This can be done safely as it does not break the main feature of integers:
integers will stay integers after tonumber(tostring(x)) conversion cycle.

Test cases:
assert(tonumber("1"..("0"):rep(18))  == 1000000000000000000)
assert(tonumber("1"..("0"):rep(100)) == 1e+100)
assert(load("return 1"..("0"):rep(18))() == 1000000000000000000)
assert(load("return 1"..("0"):rep(19))() == 1e+19)
assert(math.tointeger("1000000000000000000")  == 1000000000000000000)
assert(math.tointeger("10000000000000000000") == nil)

One more minor suggestion:
Usual L-suffixed syntax for integers may be useful in Lua:
1000000000000000000     would return integer 1000000000000000000
1000000000000000000L    would return integer 1000000000000000000

10000000000000000000    would return float 1e+19
10000000000000000000L   would generate compilation error
10000000000000000000UL  would return integer -8446744073709551616

100000000000000000000   would return float 1e+20
100000000000000000000L  would generate compilation error
100000000000000000000UL would generate compilation error

One more syntax-related wish:
Please let us use single quote as separator in float and integer literals:
local million = 1'000'000
local micro   = 0.000'001
local mask32  = 0xFFFF'FFFF

-- Egor