Re: A bug of plus in 64bit

  • From: Coda Highland <chighland@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Wed, 23 Mar 2016 06:41:31 -0700

On Wed, Mar 23, 2016 at 1:49 AM, Shawn Tsao <t.s.c@xxxxxxxxxxx> wrote:

Hi All,
  Thanks for your answers.

  I tried below codes. It seems the value will be always converted to double
even if I define them using ffi.cast("uint64_t"...). How can I make the
answer correct?

lua site:
function test(ull_num)
  local n = ffi.cast("uint64_t", ull_num)
  local d = ffi.cast("uint64_t", ull_num)
  local high = n / d
  local low = n % d
  return tonumber(high), tonumber(low)
end

c/c++ site:
......
lua_getglobal(L, "test");
lua_pushnumber(L, 0x1234567890ABCDEF");
lua_pcall(L, 1, 2, 0);
long long high = (long long)lua_tonumber(L, -2);
long long low = (long long)lua_tonumber(L, -1);
NSLog(@"%0.16llX, %0.16llX", high, low);
....

result:
0000000012345678, 0000000090ABCE00

Regards
Shawn

Both of these functions are still working with doubles. That means
you've already had the precision loss, and casting to ULL isn't going
to get those lost bits back.

Short version: Don't use any functions that have "number" in it
because that means "double" in Lua-speak.

Another issue: LuaJIT has exactly zero interoperability between the
FFI and the C API. There is no way to pass a 64-bit int (which is an
FFI type) into LuaJIT using the C API. You have to go the other way,
defining a C function that returns the value and call it from within
LuaJIT using the FFI.

As an aside, / and % are math operations. When possible, you should
really do this using bit operations:

C:
high = num >> 32;
low = num & 0xFFFFFFFF;

LuaJIT 2.1 (git):
local bit = require("bit")
num = 0x0123456789abcdefULL
high = bit.rshift(num, 32)
low = bit.band(num, 0xFFFFFFFF)

Of course, LuaJIT 2.0 doesn't have 64-bit bitop support, so you'll
have to use / and % there.

/s/ Adam

Other related posts: