4

Original Message:

I need to multiply two 64 bit numbers, but Lua is losing precision with big numbers. (for example 99999999999999999 is shown as 100000000000000000) After multiplying I need a 64 bit solution, so I need a way to limit the solution to 64 bits. (I know, if the solution would be precise, I could just use % 0x10000000000000000, so that would work too)

EDIT: With Lua 5.3 and the new 64 bit integer support, this problem doesn't exist anymore. Neat.

Masterjun
  • 43
  • 5
  • My suggestion is to modify the source code and get your own type in the interpreter. Most cases you will embed the customized interpreter anyway – SwiftMango Oct 30 '12 at 17:30
  • 1
    @texasbruce: There's no need to *modify the interpreter*; that's way overkill. You can add types without directly modifying the interpreter at all. Just create a module that you expose to Lua. – Nicol Bolas Oct 30 '12 at 17:36
  • Note also that you need 128 bits to represent the product of two 64-bit numbers. – lhf Oct 31 '12 at 11:53
  • Not if you want a 64 bit result anyways. – Cubic Nov 05 '12 at 19:52

2 Answers2

3

Lua uses double-precision floating points for all math, including integer arithmetic (see http://lua-users.org/wiki/FloatingPoint). This gives you about 53 bits of precision, which (as you've noticed) is less than you need.

There are a couple of different ways to get better precision in Lua. Your best bet is to find the most active such effort and piggy-back off it. In that case, your question has already been answered; check out What is the standard (or best supported) big number (arbitrary precision) library for Lua?

If your Lua distribution has packages for it, the easy answer is lmapm.

Community
  • 1
  • 1
Graeme
  • 1,445
  • 1
  • 10
  • 4
  • 1
    If the OP only needs to handle integers, then using [lbc](http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lbc) instead of lmapm would be easier because lbc is self-contained. – lhf Oct 30 '12 at 19:27
1

If you use LuaJIT in place of Lua, you get access to all C99 built-in types, including long long which is usually 64 bits.

local ffi = require 'ffi'

-- Needed to parse constants that do not fit in a double:
ffi.cdef 'long long strtoll(const char *restrict str, char **restrict endptr, int base);'

local a = ffi.C.strtoll("99999999999999999", nil, 10)
print(a)
print(a * a)

=> 3803012203950112769LL (assuming the result is truncated to 64 bits)

finnw
  • 47,861
  • 24
  • 143
  • 221