[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Integers-related trap in Lua 5.3
- From: Egor Skriptunoff <egor.skriptunoff@...>
- Date: Mon, 16 May 2016 12:20:30 +0300
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.
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.
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