lua-users home
lua-l archive

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


Hi all,

I think this has been raised before in IRC a year or two ago, 
but I don't think there was ever a consensus on exactly what 
the result should be. 

Lua seems to have trouble parsing both -0 and 0 while reading 
a file. Individually, it works fine, however when both are 
present in the same file, the compiler seems to fold -0 and 0 
into the same constant. Reference the following:

mpdelbuono@li23-154 ~ $ luac -l -
a = -0.0

main <stdin:0,0> (3 instructions, 12 bytes at 0x805fb30)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0 
functions
        1       [1]     LOADK           0 -2    ; -0
        2       [1]     SETGLOBAL       0 -1    ; a
        3       [1]     RETURN          0 1

This wouldn't be an issue if -0 and 0 operated the same in all 
situations (primarily because Lua follows that -0 == 0). 
However, we encounter an issue in the situation where there is 
an actual distinction between -0 and 0, like the following:

mpdelbuono@li23-154 ~ $ lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> return 1 / -0
-inf
> return 1 / 0
inf

Surely we all agree that -inf ~= inf, and as such 1/-0 ~= 1/0. 
However, we get the following:

> return 1 / -0 == 1 / 0
true

Why does this happen? Because of the same problem:

mpdelbuono@li23-154 ~ $ luac -l -
return 1 / -0 == 1 /0

main <stdin:0,0> (8 instructions, 32 bytes at 0x805fb30)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0 
functions
        1       [1]     DIV             0 -2 -1 ; 1 -0
        2       [1]     DIV             1 -2 -1 ; 1 -0
        3       [1]     EQ              1 0 1
        4       [1]     JMP             1       ; to 6
        5       [1]     LOADBOOL        0 0 1
        6       [1]     LOADBOOL        0 1 0
        7       [1]     RETURN          0 2
        8       [1]     RETURN          0 1

Again, notice the statement of 2 constants instead of the 
expected 3. The flaw here is that it is being turned into "1 
/0 == 1 / 0" instead of what was entered.

It seems Lua always chooses the first zero. Simply reversing 
the sides of the expression will yield a different, but 
equally incorrect, result:

mpdelbuono@li23-154 ~ $ luac -l -
return 1 / 0 == 1 / -0

main <stdin:0,0> (8 instructions, 32 bytes at 0x805fb30)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0 
functions
        1       [1]     DIV             0 -2 -1 ; 1 0
        2       [1]     DIV             1 -2 -1 ; 1 0
        3       [1]     EQ              1 0 1
        4       [1]     JMP             1       ; to 6
        5       [1]     LOADBOOL        0 0 1
        6       [1]     LOADBOOL        0 1 0
        7       [1]     RETURN          0 2
        8       [1]     RETURN          0 1


If I had to venture a guess, Lua is making a naive check to 
see if a constant is already present in the constants list by 
checking equality directly, rather than actually checking if 
they are truly the same constant.

Personally, I think this is a bug, but it is an extremely 
borderline case. However, as shown above, it does in fact 
cause incorrect bytecode to be generated in a very specific 
use case.

Regards,
-- Matthew P. Del Buono
Embry-Riddle Aeronautical University