Lua uses one single number representation, which is chosen at compile time, and since it is often set to IEEE 754 double precision floating point, one cannot store 64 bit integers with full precision.
Lua numbers are stored as floating point (doubles) internally, not integers; thus while they can represent incredibly large numbers, above 2^53 they lose integral precision — they can’t represent every whole integer value. For example if you set a lua variable to the number 9007199254740992 and tried to increment it by 1, you’d get the same number because it can’t represent 9007199254740993 (only the even number 9007199254740994).
Therefore, in order to count higher than 2^53 in integers, we need a true integer type. The way this is done is with an explicit 'Int64' or 'UInt64' object (i.e., Lua userdata). This object has metamethods for all of the math and comparison operators, so you can handle it like any number variable. For the math operators, it can even be mixed with plain Lua numbers.
For example 'my64num = my64num + 1' will work even if 'my64num' is a Int64
or UInt64
object.
Note that comparison operators ('==','<=','>', etc.) will not work with plain numbers — only other Int64/UInt64 objects.
This is a limitation of Lua itself, in terms of how it handles operator overloading.
Warning | |
---|---|
Many of the UInt64/Int64 functions accept a Lua number as an argument. You should be very careful to never use Lua numbers bigger than 32 bits (i.e., the number value 4,294,967,295 or the literal 0xFFFFFFFF) for such arguments, because Lua itself does not handle bigger numbers consistently across platforms (32-bit vs. 64-bit systems), and because a Lua number is a C-code double which cannot have more than 53 bits of precision. Instead, use a Int64 or UInt64 for the argument. |
For example, do this…
local mynum = UInt64(0x2b89dd1e, 0x3f91df0b)
…instead of this:
-- Bad. Leads to inconsistent results across platforms local mynum = UInt64(0x3f91df0b2b89dd1e)
And do this…
local masked = mynum:band(UInt64(0, 0xFFFFFFFF))
…instead of this:
-- Bad. Leads to inconsistent results across platforms local masked = mynum:band(0xFFFFFFFF00000000)
Note | |
---|---|
Lua 5.3 and later adds a second number representation for integers, which is also chosen at compile time. It is usually a 64-bit signed integer type, even on 32-bit platforms.
(Lua 5.2 and earlier have an integer type, but this is not used for storing numbers, only for casting, and on 32-bit platforms is 32-bits wide.)
Wireshark 4.4 and later will use the Lua integer type where possible, but as storing
64-bit unsigned integers in a Lua Integer can result in signed number overflow, |
Int64
represents a 64 bit signed integer.
Note the caveats listed above.
Decodes an 8-byte Lua string, using the given endianness, into a new Int64
object.
nil
, native
host endian.
The Int64
object created, or nil on failure.
Creates a Int64
object.
The new Int64
object.
Creates an Int64
of the maximum possible positive value. In other words, this should return an Int64 object of the number 9,223,372,036,854,775,807.
The new Int64
object of the maximum value.
Creates an Int64
of the minimum possible negative value. In other words, this should return an Int64 object of the number -9,223,372,036,854,775,808.
The new Int64
object of the minimum value.
Creates an Int64
object from the given hexadecimal string.
The new Int64
object.
Encodes the Int64
number into an 8-byte Lua string using the given endianness.
nil
,
native host endian.
The Lua string.
Returns a hexadecimal string of the Int64
value.
The string hex.
Returns a Lua number of the higher 32 bits of the Int64
value. A negative Int64
will return a negative Lua number.
The Lua number.
Returns a Lua number of the lower 32 bits of the Int64
value. This will always be positive.
The Lua number.
Adds two Int64
together and returns a new one. The value may wrapped.
Subtracts two Int64
and returns a new one. The value may wrapped.
Multiplies two Int64
and returns a new one. The value may truncated.
Divides two Int64
and returns a new one. Integer divide, no remainder.
Trying to divide by zero results in a Lua error.
The Int64
object.
Divides two Int64
and returns a new one of the remainder.
Trying to modulo by zero results in a Lua error.
The Int64
object.
The first Int64
is taken to the power of the second Int64
, returning a new
one. This may truncate the value.
The Int64
object.
Returns true
if both Int64
are equal.
Returns true
if first Int64
is less than the second.
Returns true
if the first Int64
is less than or equal to the second.
Returns a Int64
of the bitwise 'and' operation with the given number/Int64
/UInt64
.
Note that multiple arguments are allowed.
Returns a Int64
of the bitwise 'or' operation, with the given number/Int64
/UInt64
.
Note that multiple arguments are allowed.
Returns a Int64
of the bitwise 'xor' operation, with the given number/Int64
/UInt64
.
Note that multiple arguments are allowed.
Returns a Int64
of the bitwise logical left-shift operation, by the given
number of bits.
The Int64
object.
Returns a Int64
of the bitwise logical right-shift operation, by the
given number of bits.
The Int64
object.
Returns a Int64
of the bitwise arithmetic right-shift operation, by the
given number of bits.
The Int64
object.
Returns a Int64
of the bitwise left rotation operation, by the given number of
bits (up to 63).
The Int64
object.
UInt64
represents a 64 bit unsigned integer, similar to Int64
.
Note the caveats listed above.
Decodes an 8-byte Lua binary string, using given endianness, into a new UInt64
object.
nil
,
native host endian.
The UInt64
object created, or nil on failure.
Creates a UInt64
object.
The new UInt64
object.
Creates a UInt64
of the maximum possible value. In other words, this should return an UInt64 object of the number 18,446,744,073,709,551,615.
The maximum value.
Creates a UInt64
of the minimum possible value. In other words, this should return an UInt64 object of the number 0.
The minimum value.
Creates a UInt64
object from the given hex string.
The new UInt64
object.
Encodes the UInt64
number into an 8-byte Lua binary string, using given endianness.
nil
,
native host endian.
The Lua binary string.
Returns a hex string of the UInt64
value.
The string hex.
Returns the UInt64
in a new UInt64
, since unsigned integers can’t be negated.
The UInt64
object.
Adds two UInt64
together and returns a new one. This may wrap the value.
Subtracts two UInt64
and returns a new one. This may wrap the value.
Multiplies two UInt64
and returns a new one. This may truncate the value.
Divides two UInt64
and returns a new one. Integer divide, no remainder.
Trying to divide by zero results in a Lua error.
The UInt64
result.
Divides two UInt64
and returns a new one of the remainder.
Trying to modulo by zero results in a Lua error.
The UInt64
result.
The first UInt64
is taken to the power of the second UInt64
/number,
returning a new one. This may truncate the value.
The UInt64
object.
Returns true if both UInt64
are equal.
Returns true if first UInt64
is less than the second.
Returns true if first UInt64
is less than or equal to the second.
Returns a UInt64
of the bitwise 'and' operation, with the given number/Int64
/UInt64
.
Note that multiple arguments are allowed.
Returns a UInt64
of the bitwise 'or' operation, with the given number/Int64
/UInt64
.
Note that multiple arguments are allowed.
Returns a UInt64
of the bitwise 'xor' operation, with the given number/Int64
/UInt64
.
Note that multiple arguments are allowed.
Returns a UInt64
of the bitwise logical left-shift operation, by the
given number of bits.
The UInt64
object.
Returns a UInt64
of the bitwise logical right-shift operation, by the
given number of bits.
The UInt64
object.
Returns a UInt64
of the bitwise arithmetic right-shift operation, by the
given number of bits.
The UInt64
object.
Returns a UInt64
of the bitwise left rotation operation, by the
given number of bits (up to 63).
The UInt64
object.