[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Strange lua 5.3 tonumber() behaviour
- From: Dirk Laurie <dirk.laurie@...>
- Date: Wed, 19 Aug 2015 07:58:43 +0200
2015-08-19 5:34 GMT+02:00 Daurnimator <quae@daurnimator.com>:
> Lua 5.3 doesn't seem to accept fractional components when passing a base
>
> $ lua5.1 -e 'print(tonumber("9.0", 10))'
> 9
> $ lua5.3 -e 'print(tonumber("9.0", 10))'
> nil
> $ lua5.3 -e 'print(tonumber("9.0"))'
> 9.0
This already is true for Lua 5.2.
> Lua 5.3 performs overflow/wraparound on large numbers... but only with
> limited precision.
>
> $ lua5.1 -e 'print(tonumber("99999999999999999999999999999999999999999999999999999999999999999999999999999999"))'
> 1e+80
> $ lua5.3 -e 'print(tonumber("99999999999999999999999999999999999999999999999999999999999999999999999999999999"))'
> -1
> $ lua5.1 -e 'print(tonumber("999999999999999999999999999"))'
> 1e+27
> $ lua -e 'print(tonumber("999999999999999999999999999"))'
> -6930898827444486145
>
> Are these behaviours intentional?
They are exactly what you would get if you used that string in Lua source.
> s=9999999999999999999999999999999999999999999999999999999999999999
> s
-1
> Should these changes from 5.1/5.2 be documented?
The first one (which is a change only from 5.1) is documented.
>From the 5.2/5.3 manual:
~~~
When called with base, then e must be a string to be interpreted as
an integer numeral in that base. ... If the string e is not a valid numeral
in the given base, the function returns nil.
~~~
The second one is not a tostring issue, but deals more generally with
numerals that are lexically integers but not representable in 64 bits.
The manual makes only the lexical distinction:
~~~
A numeric constant with a fractional dot or an exponent denotes
a float; otherwise it denotes an integer.
~~
You have a point here. But documenting it does not go far enough:
it should be changed in Lua 5.3.2. While not technically a bug,
this is an totally unnecessary gotcha.
It is one thing for overflows to occur as a result of arithmetic
operations: decades of teaching of computer basics prepare
one for that. But string-to-number conversion, whether in
tostring() or load(), can easily check that a lexical integer is
in range (whatever "range" means for the current luaconf.h)
and should give an error otherwise.