Search code examples
luainteger64-bitadditionzerobrane

Lua addition error


It seems like Lua addition is not working when dealing with large numbers (64bit values). I have tried to compute the following:

71776119061217280 + 281474976710655

or in hexa

  0x00FFFFFFFFFFFF‬
+ 0x‭FF000000000000

Lua 5.1, 5.2, and 5.3 all return

72057594037927936 (= 0x‭100000000000000)

No need to take out your calculator to see that this is wrong. An even number added to an odd number is not an even number. As a matter of fact, it seems to be off by 1 (the right result is 72057594037927935). In hexa the problem is even more obvious since the result should be 0xFFFFFFFFFFFFFF. Anyone knows what's happening, or what I would be doing wrong here?

Update:

For info, I am seeing this with ZeroBrane Studio on Windows 10.


Solution

  • These are the results that I get using Lua interpreters included with ZeroBrane Studio for this script:

    print(("%.17g"):format(71776119061217280 + 281474976710655))
    print(71776119061217280 + 281474976710655)
    

    Lua 5.1 (it's actually LuaJIT interpreter):

    72057594037927936
    7.2057594037928e+016
    

    Lua 5.2:

    72057594037927936
    7.2057594037928e+016
    

    Lua 5.3

    72057594037927936
    72057594037927935
    

    If you run this in the Local console in the IDE, then you'll see 72057594037927936, as it's using %.17g format during serialization of the results.

    The local console always uses the interpreter the IDE is executed with, which is Lua 5.1 (actually LuaJIT) on all platforms, so this is maybe where the confusion about the results is coming from. Setting the interpreter only changes what's used for Running and Debugging scripts, but not the Local console (at least in the current version, as there are tickets that may change that). This should not affect the tooltip and stack/watch windows, as they use %.16g format, which can be changed using debugger.numformat setting; the console is the only place where %.17g format is used as it's the one recommended to avoid losing precision.