[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Lua 5.3: wrong coercion?
- From: Tim Hill <drtimhill@...>
- Date: Fri, 16 Jan 2015 13:35:35 -0800
> On Jan 16, 2015, at 12:49 PM, Roberto Ierusalimschy <firstname.lastname@example.org> wrote:
>> According to sect 3.4.3 in the refman:
>> "The conversion from strings to numbers goes as follows: First, the
>> string is converted to an integer or a float, following its syntax
>> and the rules of the Lua lexer. (The string may have also leading
>> and trailing spaces and a sign.) Then, the resulting number is
>> converted to the required type (float or integer) according to the
>> previous rules."
>> Thus if I have a string which is "42" it should be coerced to an
>> integer, since 42 is parsed as an integer constant by the lexer,
>> whereas I get:
>> print( 43, "42" + 1 ) --> 43 43.0
>> where it seems that the addition is a float addition, signaling that
>> one of the operands is float. Is this a bug, an error in the refman
>> or maybe something on my side (Windows 7-64, using 32bit executables
>> compiled with TDM-GCC 4.9.2 32 bit)? Am I missing something?
> You are missing the last sentence that you quoted! "Then, the resulting
> number is converted to the required type (float or integer) according
> to the previous rules." The "required type" in this case is a float, as
> explained in the rule for addition (Section 3.4.1):
> [...] the arithmetic operators work as follows: If both operands are
> integers, the operation is performed over integers and the result is an
> integer. Otherwise, if both operands are numbers or strings that can be
> converted to numbers (see §3.4.3), then they are converted to floats,
> -- Roberto
I’m scratching my head on this one…
(1) 3.4.3 "First, the string is converted to an integer or a float, following its syntax and the rules of the Lua lexer...”
—> So, “42” should convert to the integer 42. So we now have 42 + 1 as the print() expression.
(2) 3.4.3 “...Then, the resulting number is converted to the required type (float or integer) according to the previous rules.”
—> If by “previous rules” the manual means “...All other arithmetic operations applied to mixed numbers (integers and floats) convert the integer operand to a float; this is called the usual rule.”, then this doesn’t seem to apply here, since both operands are integers. So we still have 42 + 1.
(3) 3.4.1 "If both operands are integers, the operation is performed over integers and the result is an integer. Otherwise, if both operands are numbers or strings that can be converted to numbers (see §3.4.3), then they are converted to floats"
—> Yes, they are both numbers or strings. So we convert them to float and get 42.0 + 1.0
But why? Given that the parser has determined “42” is an integer, why does the arithmetic operator then somehow keep track of the origins of the integer as a string and coerce it to a float? I have to confess I find the following surprising:
print(“42” + 1)
print(tonumber(“42”) + 1)
Is this behavior (the first print()) for backward compatibility? That makes sense to me, but otherwise I’m trying to understand the rationale.