Wim Couwenberg - July 2007
The package offers the GNU multiple precision arithmetic library [1] for Lua 5.1. Currently it supports only the integer, floating point and random state types. I have no plans (yet) to add support for rationals.
The package consists of a single C file “lgmp.c” and a single Lua file “gmp.lua”. The libraries for Lua and GMP should already be available on your system. Compile and link lgmp.c into a bundle (OSX), dynamic link library (Win32) or shared library (Unix) called either “c-gmp.so” (OSX, Unix) or “c-gmp.dll” (Win32). Link against both the Lua and GMP libraries if necessary. Here is the command line I use to build c-gmp.so on OSX 10.4.10 (the Lua library is a dylib and the GMP library is a static archive on my system):
gcc -bundle -O2 -Wall -llua -lgmp -o c-gmp.so
lgmp.c
Place the file c-gmp.so (or c-gmp.dll) and gmp.lua in the proper
locations on your system so that they will be found through
package.cpath and package.path
respectively.
Load the lgmp package with require “gmp”.
This makes the lgmp functionality available through a global table
named “gmp”. The package defines a handful of
global functions to create and compute gmp objects. Objects can be
manipulated through a large number of methods. The lgmp package covers
most of the GMP library functions available for integer, floating point
and random state types. The string gmp.version reflects
the version of the underlying GMP library. On my system it currently
reads:
> =gmp.version
4.2.1
All lgmp types are mutable, i.e. the value of an instance can
change. This is hardly surprising for a random state but it can become
a bit confusing for integer and floating point types. The library is
set up in such a way that most functions and methods do not change
their operands by default. (Though some methods, like
set, addmul and submul, are
designed to update their self operand.) The design of the
lgmp package with respect to mutability is as follows. Whenever a
function or method returns n objects of integer or floating
point type, then that function or method accepts n optional
extra arguments that can specify existing objects of the same type.
When these extra arguments are provided then their value is changed and
the function or method returns these arguments. The following examples
illustrate this principle.
> -- load lgmp package
> require “gmp”
> -- create two gmp integers
> x = gmp.z(123)
> y = gmp.z(456)
> -- compute their sum
> =x:add(y)
579
> -- x and y are left unchanged
> =x, y
123 456
> -- compute sum, update and return x
> =x:add(y,x)
579
> -- x is updated
> =x, y
579 456
> -- compute quotient and remainder
> =x:fdiv_qr(y)
1 123
> -- x and y are left unchanged
> =x, y
579 456
> -- update y with remainder and return quotient, y
> =x:fdiv_qr(y, nil, y)
1 123
> -- y is updated, x is left unchanged
> =x, y
579 123
> -- update x and y to quotient and remainder and return x, y
> =x:fdiv_qr(y, x, y)
4 87
> -- x and y are both updated
> =x, y
4 87
> -- returns nothing but updates “self”
> =x:addmul(y, 3)
> =x, y
265 87
> -- returns nothing but sets “self” to new integer value
> =x:set "123456789123456789123456789"
> =x
123456789123456789123456789
The table below lists the global functions in the lgmp package. Arguments in italics are optional. Refer to the GMP manual [2] for further details.
| Function | Implemented with | Description |
bin(a1, a2, res) |
mpz_bin_ui |
Computes the binomial coefficient a1 over
a2. Argument a1 may be negative.
Argument a2 must be a Lua number in the
unsigned long range. Returns a gmp integer. |
f(value, base) |
mpf_init |
Create a floating point object. If no initial
value is specified then it is initialized to 0
(zero). The inital value can be a Lua number,
an integer object, a floating point object or a string. If
value is a string then base can
optionally specify the base between -62 and -2 or between 2
and 62 inclusive. (Refer to the mpf_set_str
function in the GMP manual [2] for
details.) If no base is specified it defaults
to 10. |
fac(a, res) |
mpz_fac_ui |
Argument a must be a Lua number in the
unsigned long range. |
fib(a, res) |
mpz_fib_ui |
Argument a must be a Lua number in the
unsigned long range. |
lucnum(a, res) |
mpz_lucnum_ui |
Argument a must be a Lua number in the
unsigned long range. |
pow(a1, a2, res) |
mpz_pow_ui |
Argument a2 must be a Lua number in the
unsigned long range. Returns a gmp integer. |
rand(a) |
gmp_randinit_default |
Create a random state object. An initial random state can
be provided in a to create a copy of that
state. If no argument is provided then a default random
state is created. |
set_default_prec(a) |
mpf_set_default_prec |
Set default minimal precision for new floating point
objects to a bits. |
sqrt(a, res) |
mpf_sqrt_ui |
The argument a must be in the unsigned long
range. Returns a floating point number. |
z(value, base) |
mpz_init |
Create an integer object. If no arguments are given then
its value is initialized to 0 (zero). The initial
value can be specified as a Lua number, an
integer object, a floating point object or a string. If
value is a string then base can
be optionally specify a base between 2 and 62 (inclusive)
or base can be 0 (zero) in which case the actual base is
implied by a prefix of value. (Refer to the
mpz_set_str function in the GMP manual [2] for details.) If no
base is specified it defaults to 10. |
The table below lists the methods of an integer object. Arguments in italics are optional. Refer to the GMP manual [2] for further details.
| Method | Implemented with | Description |
z:__tostring() |
mpz_get_str |
|
z:__concat(a) |
mpz_get_str |
|
z:__add(a) |
mpz_add |
|
z:__mul(a) |
mpz_mul |
|
z:__div(a) |
mpz_fdiv_q |
The implementations of __div and
__mod are chosen such that __mod
extends the Lua % operator and x =
(x/y)*y + x%y for all integer objects
x and y. |
z:__pow(a) |
mpz_pow_ui |
The exponent a must be in the unsigned long
range. |
z:__unm() |
mpz_neg |
|
z:__lt(a) |
mpz_cmp |
|
z:__gc() |
mpz_clear |
|
z:abs(res) |
mpz_abs |
|
z:add(a, res) |
mpz_add |
|
z:addmul(a1, a2) |
mpz_addmul |
Changes self to self + a1*a2.
Returns nothing. |
z:And(a, res) |
mpz_and |
Named with a capital A to avoid a name clash
with the built-in operator and. |
z:bin(a, res) |
mpz_bin_ui |
Computes the binomial coefficient self over
a. The value of self may be
negative. Argument a must be a Lua number in
the unsigned long range. |
z:cdiv_q(a, res) |
mpz_cdiv_q |
If a is a Lua number in the (un)signed long
range then z:cdiv_q, z:cdiv_r and
z:cdiv_qr all return the remainder as
an additional Lua number return value. The method
z:cdiv takes an argument in the (un)signed
long range and returns only the remainder as a Lua
number. |
z:clrbit(a, res) |
mpz_clrbit |
|
z:cmp(a) |
mpz_cmp |
|
z:com(res) |
mpz_com |
|
z:congruent(a1, a2) |
mpz_congruent_p |
Result is a boolean |
z:divexact(a, res) |
mpz_divexact |
Result is a boolean |
z:divisible(a) |
mpz_divisible_p |
Result is a boolean |
z:fdiv_q(a, res) |
mpz_fdiv_q |
If a is a Lua number in the (un)signed long
range then z:fdiv_q, z:fdiv_r and
z:fdiv_qr all return the remainder as
an additional Lua number return value. The method
z:fdiv takes an argument in the (un)signed
long range and returns only the remainder as a Lua
number. |
z:fits_sint() |
mpz_fits_sint_p |
Result is a boolean |
z:format(fmt, prec) |
gmp_asprintf |
Formats self according to the format specifier
fmt. The leading ‘%’
character is optional. The type
‘Z’ is implied but may be
specified explicitly. The conversion character is
restricted to one of “dioxX”. If
the precision is given by “.*”
then the second argument prec must specify the
precision. Otherwise prec must be
unspecified. |
z:gcd(a, res) |
mpz_gcd |
|
z:get_d() |
mpz_get_d |
|
z:get_str(base) |
mpz_get_str |
If base is not specified it defaults to
10. |
z:hamdist(a) |
mpz_hamdist |
|
z:invert(a, res) |
mpz_invert |
Returns nothing if no inverse exists |
z:ior(a, res) |
mpz_ior |
|
z:jacobi(a) |
mpz_kronecker |
The functions z:jacobi,
z:legendre and z:kronecker are
identical |
z:rjacobi(a) |
mpz_kronecker |
As z:jacobi, z:legendre and
z:kronecker but with reversed arguments. All
three functions are identical |
z:lcm(a, res) |
mpz_lcm |
|
z:mod(a, res) |
mpz_mod |
If a is a Lua number in the (un)signed long
range then the modulus as a Lua number is returned as a
second return value. |
z:mul(a, res) |
mpz_mul |
|
z:neg(res) |
mpz_neg |
|
z:nextprime(res) |
mpz_nextprime |
|
z:perfect_power() |
mpz_perfect_power_p |
Result is a boolean |
z:perfect_square() |
mpz_perfect_square_p |
Result is a boolean |
z:popcount() |
mpz_popcount |
|
z:pow(a, res) |
mpz_pow_ui |
The exponent a must be in the unsigned long
range. |
z:powm(a1, a2, res) |
mpz_powm |
|
z:probab_prime(a) |
mpz_probab_prime_p |
Result is false, 1 or
2. If the number a of tests is
not specified it defaults to 10. |
z:remove(a, res) |
mpz_remove |
|
z:root(a, res) |
mpz_root |
|
z:scan0(a) |
mpz_scan0 |
A a is not specified then it defaults to 0
(zero). |
z:set(a, base) |
mpz_set |
Changes the value of self. Returns nothing.
If a is a string then an optional base can be
specified. See the description of global function
z for further details. |
z:setbit(a, res) |
mpz_setbit |
|
z:sgn() |
mpz_sgn |
|
z:sizeinbase(a) |
mpz_sizeinbase |
If the base a is not specified then it
defaults to 10. |
z:sqrt(res) |
mpz_sqrt |
|
z:sub(a, res) |
mpz_sub |
Method z:rsub acts as z:sub but
with reversed operands. |
z:submul(a1, a2) |
mpz_submul |
Changes the value of self to self -
a1*a2. Returns nothing. |
z:tdiv_q(a, res) |
mpz_tdiv_q |
If a is a Lua number in the (un)signed long
range then z:tdiv_q, z:tdiv_r and
z:tdiv_qr all return the remainder as
an additional Lua number return value. The method
z:tdiv takes an argument in the (un)signed
long range and returns only the remainder as a Lua
number. |
z:tstbit(a) |
mpz_tstbit |
Returns 0 or 1. |
z:xor(a, res) |
mpz_xor |
The table below lists the methods of floating point object. Arguments in italics are optional. Refer to the GMP manual [2] for further details.
| Method | Implemented with | Description |
f:__tostring() |
gmp_asprintf |
The floating point is formatted with the format specifier
“%.Fg”. |
f:__add(a) |
mpf_add |
|
f:__mul(a) |
mpf_mul |
|
f:__div(a) |
mpf_div |
|
f:__unm() |
mpf_neg |
|
f:__pow(a) |
mpf_pow_ui |
The exponent a must be in the unsigned long
range. |
f:__lt(a) |
mpf_cmp |
|
f:__gc() |
mpf_clear |
|
f:abs(res) |
mpf_abs |
|
f:add(a, res) |
mpf_add |
|
f:ceil(res) |
mpf_ceil |
|
f:cmp(a) |
mpf_cmp |
|
f:div(a, res) |
mpf_div |
The function f:rdiv is identical to
f:div but with reversed arguments. |
f:eq(a1, a2) |
mpf_eq |
Result is a boolean. |
f:fits_sint() |
mpf_fits_sint_p |
Result is a boolean. |
f:floor(res) |
mpf_floor |
|
f:format(fmt, prec) |
gmp_asprintf |
Formats self according to the format specifier
string fmt. The leading
‘%’ character is optional. The
type ‘F’ is implied but may be
specified explicitly. The conversion character is
restricted to one of “aAeEfgG”.
If the precision is given by “.*”
then prec must specify the precision.
Otherwise prec must be unspecified. |
f:get_d() |
mpf_get_d |
|
f:get_prec() |
mpf_get_prec |
|
f:get_str(base, size) |
mpf_get_str |
Returns a string of digits and an exponent. If
base is unspecified it defaults to 10. If
size is unspecified it defaults to the
precision of self in the given base. |
f:integer() |
mpf_integer_p |
Result is a boolean. |
f:mul(a, res) |
mpf_mul |
|
f:neg(res) |
mpf_neg |
|
f:pow(a, res) |
mpf_pow_ui |
The exponent a must be int the unsigned long
range. |
f:reldiff(a, res) |
mpf_reldiff |
|
f:set_prec(a) |
mpf_set_prec |
|
f:set(a, base) |
mpf_set |
Change the value of self. Returns nothing.
See the description of the global function f
for details. |
f:sgn() |
mpf_sgn |
|
f:sqrt(res) |
mpf_sqrt |
|
f:sub(a, res) |
mpf_sub |
Method f:rsub is identical to
f:sub but with reversed arguments. |
f:trunc(res) |
mpf_trunc |
The table below lists the methods of a random state object. Arguments in italics are optional. Refer to the GMP manual [2] for further details.
| Method | Implemented with | Description |
rand:__tostring() |
N/A |
|
rand:__gc() |
gmp_randclear |
|
rand:seed(a) |
gmp_randseed |
Set a seed value for the random state. |
rand:zbits(a, res) |
mpz_urandomb |
Generate an integer of at most a bits. |
rand:z(a, res) |
mpz_urandomm |
Generate an integer in the interval [0, a). |
rand:fbits(a, res) |
mpf_urandomb |
Generate a floating point in the interval [0, 1) with a
mantissa of at most a bits. |
The lgmp package is distributed under the MIT license. See the “COPYRIGHT” file in the distribution of lgmp.
| [1] | GMP «Arithmetic without limitations» |
| [2] | GNU MP Manual |