On Wed, May 18, 2016 at 8:28 PM, Roberto Ierusalimschy
<roberto@inf.puc-rio.br <mailto:roberto@inf.puc-rio.br>> wrote:
> > One problem with all proposed solutions is math.mininteger. The
> > lexer reads numbers without signal. (Several languages do the
> > same, e.g. C). This means that -9223372036854775808 is read as
> > -(9223372036854775808) (a unary minus applied over a positive
> > constant). But 9223372036854775808 is not a valid integer, so
it would
> > result in a float (or nil, or inf, or error). Whatever the
choice, the
> > final value of -9223372036854775808 would not be an integer,
despite
> > it being a valid integer.
The lexer cannot distinguish between a "-9223372036854775808" in
"x = -9223372036854775808" and in "x = x-9223372036854775808". It
handles both the same way
It seems to be an interesting algorithmical problem.
For historical reason people consider positive numbers as "main" numbers
and negative numbers as derived numbers.
But in computer we have more negative integers than positive.
Let's change our attitude toward numbers: let negative numbers be the
main.
To solve the "mininteger" problem, we need a lexer that acts in favor of
negative numbers.
Suggestion:
Lexer must replace "minus followed by a number" with "plus followed by
negative number" before starting to calculate the number value.
Example: source code is "X = X - 357" (with a space between "-" and "357")
Lexer splits this code in the following lexems: "X", "=", "X", "+", "-357"
Please note that "-" is sticked to the number due to new behavior of
lexer.
Calculations of the number value:
result = 0;
sign_of_number := (-1);
for every digit in { 3, 5, 7 } do
result = (result * 10) + (next_digit * sign_of_number);
end
It is obvious that for any string representing an integer from (-2^63)
to (2^63-1) it is guaranteed that no integer overflow will happen
during all steps of the calculation.
So, if integer overflow occurs, then we are discarding integer result
and switching to calculation of float result.
It is possible that it may be more convenient to avoid checking of
integer overflow flag on every step of calculations.
We can simply calculate the value of the number two times:
as integer and as float.
When we calculating integer value, we ignore integer overflows.
When we calculating float value, the result saturates at infinity.
After that we compare both results.
delta = abs(float_value - integer_value)
if delta is greater than 10^9, then float is the correct answer,
otherwise integer value is preferred.