Does Lua make use of 64-bit integers? How do I use it?
3 Answers
Compile it yourself. Lua uses double-precision floating point numbers by default. However, this can be changed in the source (luaconf.h
, look for LUA_NUMBER
).

- 344,408
- 85
- 689
- 683
-
8To clarify, Lua has a single numerical data type. By default this is a `double`, but can be changed in the header files to another type, such as `int64_t`. – Yann Ramin Jun 23 '10 at 19:18
-
2If you change the number type in `luaconf.h`, don't forget to change the related macros accordingly. – lhf Jun 23 '10 at 21:44
-
@lhf: It's documented right above the macro, though, so I thought it'd be pretty discoverable. – Joey Jun 23 '10 at 22:17
-
3Note that this will have some sweeping side effects, since this is the only type numbers will have. For example, `math.sin` is not necessarily sensible with an integral type for LUA_NUMBER. There is a patch to the Lua sources, known as the LNUM patch, which can mitigate this by supporting an integral type alongside a floating point type. See http://stackoverflow.com/questions/945731/what-is-the-maximum-value-of-a-number-in-lua/947763#947763 – RBerteig Jun 24 '10 at 00:15
-
I am making an apps to use at the pge lua game engine on the psp. I was thinking to define the type of the variable, just as in VB.NET or C#. – Aaron de Windt Jun 24 '10 at 00:34
-
2@Aaron: There is only a single numerical type and even with the LNUM patch RBerteig mentioned that doesn't change from the programmer's point of view – you just suddenly have 64-bit integers alongside with doubles and as far as I understood it choosing the correct type will be done automatically. You don't declare types in Lua as you do in VB or C# – those languages use a completely different typing discipline. – Joey Jun 24 '10 at 07:23
require "bit"
-- Lua unsigned 64bit emulated bitwises
-- Slow. But it works.
function i64(v)
local o = {}; o.l = v; o.h = 0; return o;
end -- constructor +assign 32-bit value
function i64_ax(h,l)
local o = {}; o.l = l; o.h = h; return o;
end -- +assign 64-bit v.as 2 regs
function i64u(x)
return ( ( (bit.rshift(x,1) * 2) + bit.band(x,1) ) % (0xFFFFFFFF+1));
end -- keeps [1+0..0xFFFFFFFFF]
function i64_clone(x)
local o = {}; o.l = x.l; o.h = x.h; return o;
end -- +assign regs
-- Type conversions
function i64_toInt(a)
return (a.l + (a.h * (0xFFFFFFFF+1)));
end -- value=2^53 or even less, so better use a.l value
function i64_toString(a)
local s1=string.format("%x",a.l);
local s2=string.format("%x",a.h);
local s3="0000000000000000";
s3=string.sub(s3,1,16-string.len(s1))..s1;
s3=string.sub(s3,1,8-string.len(s2))..s2..string.sub(s3,9);
return "0x"..string.upper(s3);
end
-- Bitwise operators (the main functionality)
function i64_and(a,b)
local o = {}; o.l = i64u( bit.band(a.l, b.l) ); o.h = i64u( bit.band(a.h, b.h) ); return o;
end
function i64_or(a,b)
local o = {}; o.l = i64u( bit.bor(a.l, b.l) ); o.h = i64u( bit.bor(a.h, b.h) ); return o;
end
function i64_xor(a,b)
local o = {}; o.l = i64u( bit.bxor(a.l, b.l) ); o.h = i64u( bit.bxor(a.h, b.h) ); return o;
end
function i64_not(a)
local o = {}; o.l = i64u( bit.bnot(a.l) ); o.h = i64u( bit.bnot(a.h) ); return o;
end
function i64_neg(a)
return i64_add( i64_not(a), i64(1) );
end -- negative is inverted and incremented by +1
-- Simple Math-functions
-- just to add, not rounded for overflows
function i64_add(a,b)
local o = {};
o.l = a.l + b.l;
local r = o.l - 0xFFFFFFFF;
o.h = a.h + b.h;
if( r>0 ) then
o.h = o.h + 1;
o.l = r-1;
end
return o;
end
-- verify a>=b before usage
function i64_sub(a,b)
local o = {}
o.l = a.l - b.l;
o.h = a.h - b.h;
if( o.l<0 ) then
o.h = o.h - 1;
o.l = o.l + 0xFFFFFFFF+1;
end
return o;
end
-- x n-times
function i64_by(a,n)
local o = {};
o.l = a.l;
o.h = a.h;
for i=2, n, 1 do
o = i64_add(o,a);
end
return o;
end
-- no divisions
-- Bit-shifting
function i64_lshift(a,n)
local o = {};
if(n==0) then
o.l=a.l; o.h=a.h;
else
if(n<32) then
o.l= i64u( bit.lshift( a.l, n) ); o.h=i64u( bit.lshift( a.h, n) )+ bit.rshift(a.l, (32-n));
else
o.l=0; o.h=i64u( bit.lshift( a.l, (n-32)));
end
end
return o;
end
function i64_rshift(a,n)
local o = {};
if(n==0) then
o.l=a.l; o.h=a.h;
else
if(n<32) then
o.l= bit.rshift(a.l, n)+i64u( bit.lshift(a.h, (32-n))); o.h=bit.rshift(a.h, n);
else
o.l=bit.rshift(a.h, (n-32)); o.h=0;
end
end
return o;
end
-- Comparisons
function i64_eq(a,b)
return ((a.h == b.h) and (a.l == b.l));
end
function i64_ne(a,b)
return ((a.h ~= b.h) or (a.l ~= b.l));
end
function i64_gt(a,b)
return ((a.h > b.h) or ((a.h == b.h) and (a.l > b.l)));
end
function i64_ge(a,b)
return ((a.h > b.h) or ((a.h == b.h) and (a.l >= b.l)));
end
function i64_lt(a,b)
return ((a.h < b.h) or ((a.h == b.h) and (a.l < b.l)));
end
function i64_le(a,b)
return ((a.h < b.h) or ((a.h == b.h) and (a.l <= b.l)));
end
-- samples
a = i64(1); -- 1
b = i64_ax(0x1,0); -- 4294967296 = 2^32
a = i64_lshift(a,32); -- now i64_eq(a,b)==true
print( i64_toInt(b)+1 ); -- 4294967297
X = i64_ax(0x00FFF0FF, 0xFFF0FFFF);
Y = i64_ax(0x00000FF0, 0xFF0000FF);
-- swap algorithm
X = i64_xor(X,Y);
Y = i64_xor(X,Y);
X = i64_xor(X,Y);
print( "X="..i64_toString(X) ); -- 0x00000FF0FF0000FF
print( "Y="..i64_toString(Y) ); -- 0x00FFF0FFFFF0FFFF

- 71
- 1
- 2
-
1Why don't you define a class with metatable fields to support the arithmeric operators ? And why no function for converting these numbers to decimal strings (you can also bind this function to the the '__string' metatable) ? Note: if Lua is compiled to support numbers with IEEE 64-bit doubles, it stores exactly all numbers with absolute value <= (2^53). – verdy_p Apr 19 '15 at 03:16
Lua 5.3 introduces the integer subtype, which uses 64-bit integer by default.
The type number uses two internal representations, one called integer and the other called float. Lua has explicit rules about when each representation is used, but it also converts between them automatically as needed (see §3.4.3). Therefore, the programmer may choose to mostly ignore the difference between integers and floats or to assume complete control over the representation of each number. Standard Lua uses 64-bit integers and double-precision (64-bit) floats, but you can also compile Lua so that it uses 32-bit integers and/or single-precision (32-bit) floats. The option with 32 bits for both integers and floats is particularly attractive for small machines and embedded systems. (See macro
LUA_32BITS
in fileluaconf.h
.)

- 119,891
- 44
- 235
- 294
-
Yes, this is much faster than emulations using arrays of 32-bit integers or strings for storing exact values. However Lua may be also easily ported to run in other host languages than C or C++ (e.g. in PHP, Java or Javascript), offering other native numeric datatypes, or numbers with higher precision (such as 80-bit long double in x86 architectures). With emulation, you can also support complex numbers or matrixes in Lua. – verdy_p Apr 19 '15 at 03:10