summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile114
-rw-r--r--src/lgmp.lua1639
-rw-r--r--src/plugin-luagmp.cc2532
3 files changed, 4285 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..d255e83
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,114 @@
+ifeq ($(SYSTEM),)
+SYSTEM=$(shell uname)
+endif
+TRUESYSTEM=$(shell uname)
+MACHINE=$(shell uname -m)
+DISTRIB=$(shell cat /etc/issue | cut -f 1 -d\ | head -1)
+GL_GLUE=gl-glue.s
+CC = gcc
+CXX = g++
+LD = g++
+AS = as
+AR = ar rcs
+USR=/usr
+LIBXM = -lXm
+ifeq ($(SYSTEM),Darwin)
+ARCH_FLAGS=-arch i386
+SHARED_FLAGS=-dynamiclib
+SHARED_EXT=dylib
+CPPFLAGS = -dynamic
+LD = g++ -arch i386
+STRIP = strip -x
+FINK=
+ifeq ($(TRUESYSTEM),Linux)
+CC = i686-apple-darwin9-gcc
+CXX = i686-apple-darwin9-g++
+LD = i686-apple-darwin9-g++ -arch i386 -mmacosx-version-min=10.5
+STRIP = i686-apple-darwin9-strip -x
+AS = i686-apple-darwin9-as -arch i386
+LIPO = i686-apple-darwin9-lipo
+AR = i686-apple-darwin9-ar rcs
+ARCH_FLAGS =
+LDFLAGS_MESA = -all_load ../Mesa-7.4.4-darwin9/lib/libGLU.a ../Mesa-7.4.4-darwin
+LUAJIT = ../LuaJIT-darwin9/src/libluajit.a
+USR=/usr/i686-apple-darwin9
+FINK=$(USR)
+LIBXM = $(FINK)
+endif
+LIBXM = $(FINK)/sw/lib/libXm.a -lXp
+else
+ARCH_FLAGS=-march=i686 -m32
+SHARED_FLAGS=-shared
+SHARED_EXT=so
+LD = g++ -m32
+STRIP = strip --strip-unneeded
+endif
+
+INCLUDES = \
+-I../Baltisot/include \
+-I../LuaJIT/src \
+-I $(FINK)/sw/include \
+
+HAVES = -DHAVE_VSSCANF -DHAVE_LIBJPEG -DHAVE_FCNTL -DHAVE_UNISTD_H -DHAVE_FORK -DHAVE_PIPE -DHAVE_FSYNC -DHAVE_MALLOC_H -DHAVE_ASPRINTF -DHAVE_BYTESWAP_H -DCD_NO_OLD_INTERFACE -DGTK_DISABLE_DEPRECATED -DIUPLUA_USELOH -DUSE_STATIC
+
+CPPFLAGS_NO_ARCH += $(INCLUDES) -O4 -fexceptions -DSTDC_HEADERS -DREADLINE_STATIC -DHOOK_STDS -DWORDS_LITTLEENDIAN $(HAVES) -DTEC_LITTLEENDIAN -g -DNDEBUG -DUSE_MGL_NAMESPACE
+CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
+
+LDFLAGS += $(ARCH_FLAGS) $(SHARED_FLAGS) -L$(FINK)/sw/lib ./lua-interface.$(SHARED_EXT)
+
+vpath %.c ../Baltisot/lib:../Baltisot/src:src
+vpath %.cc ../Baltisot/lib:../Baltisot/src:src
+vpath %.cpp ../Baltisot/lib:../Baltisot/src:src
+vpath %.lua ../Baltisot/lib:../Baltisot/src:src
+
+GMP_SOURCES = \
+plugin-luagmp.cc \
+lgmp.lua \
+
+GMP_LIBS = -lgmp
+
+WHOLE_SOURCES = \
+$(GMP_SOURCES) \
+
+MODULES_LIST = \
+luagmp.$(SHARED_EXT) \
+
+ALL_OBJECTS = $(addsuffix .o, $(notdir $(basename $(WHOLE_SOURCES))))
+ALL_DEPS = $(addsuffix .dep, $(notdir $(basename $(WHOLE_SOURCES))))
+
+all: dep modules
+
+dist: modules
+ mkdir -p ../lua-interface-dist
+ $(STRIP) $(MODULES_LIST)
+ cp $(MODULES_LIST) ../lua-interface-dist
+
+modules: $(MODULES_LIST)
+
+dep: $(ALL_DEPS)
+
+luagmp.a: $(addsuffix .o, $(notdir $(basename $(GMP_SOURCES))))
+ $(AR) $@ $+
+
+luagmp.$(SHARED_EXT): plugin-luagmp.o luagmp.a
+ $(LD) $(LDFLAGS) -o $@ $+ $(IM_LIBS) $(CD_LIBS) $(IUP_LIBS)
+
+clean:
+ rm -f *.o *.dep *.so *.dylib *.a
+
+%.dep : %.c
+ $(CC) $(CPPFLAGS_NO_ARCH) -M -MF $@ $<
+
+%.dep : %.cpp
+ $(CXX) $(CPPFLAGS_NO_ARCH) -M -MF $@ $<
+
+%.dep : %.cc
+ $(CXX) $(CPPFLAGS_NO_ARCH) -M -MF $@ $<
+
+%.c : %.lua
+ bin2c $< $@ $(basename $@)
+
+-include $(ALL_DEPS)
+
+.PHONY: dist clean
+
diff --git a/src/lgmp.lua b/src/lgmp.lua
new file mode 100644
index 0000000..2a09639
--- /dev/null
+++ b/src/lgmp.lua
@@ -0,0 +1,1639 @@
+
+--
+-- This file is part of the lgmp package for Lua 5.1.
+--
+-- Author: Wim Couwenberg
+-- Date : 2007/7/28
+--
+-- The lgmp package is distributed under the MIT license. See the "COPYRIGHT"
+-- file that came with the distribution of lgmp for license details.
+--
+
+--
+-- Adapted for lua-interface by Nicolas "Pixel" Noble
+--
+
+local type = type
+local getmetatable = getmetatable
+local assert = assert
+local error = error
+local match = string.match
+
+local prv
+local aux
+local randmeta = {}
+local zmeta = {}
+local fmeta = {}
+
+randmeta.__index = randmeta
+zmeta.__index = zmeta
+fmeta.__index = fmeta
+
+local function isrand(obj)
+ return type(obj) == "userdata" and getmetatable(obj) == randmeta
+end
+
+local function isz(obj)
+ return type(obj) == "userdata" and getmetatable(obj) == zmeta
+end
+
+local function isf(obj)
+ return type(obj) == "userdata" and getmetatable(obj) == fmeta
+end
+
+local function ntype(obj)
+ local t = type(obj)
+ if t == "number" then
+ if obj%1 == 0 then
+ if obj >= 0 and obj <= prv.ULONG_MAX then
+ return "u"
+ elseif obj >= prv.LONG_MIN and obj < 0 then
+ return "s"
+ elseif obj >= -prv.ULONG_MAX and obj < prv.LONG_MIN then
+ return "n"
+ end
+ end
+ return "d"
+ elseif t == "userdata" then
+ local m = getmetatable(obj)
+ if m == zmeta then
+ return "z"
+ elseif m == fmeta then
+ return "f"
+ end
+ end
+ return "?"
+end
+
+local function checkrand(obj)
+ assert(isrand(obj), "gmp random state expected")
+end
+
+local function checku(obj)
+ assert(type(obj) == "number" and obj >= 0 and obj <= prv.ULONG_MAX and obj%1 == 0, "unsigned integer expected")
+end
+
+local function checkn(obj)
+ assert(type(obj) == "number" and obj >= 0 and obj <= prv.LONG_MAX and obj%1 == 0, "non-negative intger expected")
+end
+
+local function checkbase(obj)
+ assert(type(obj) == "number" and obj >= 2 and obj <= 62 and obj%1 == 0, "gmp number base must be an integer between 2 and 62")
+end
+
+local function checkz(obj)
+ assert(isz(obj), "gmp integer expected")
+end
+
+local function checkzopt(obj)
+ assert(obj == nil or isz(obj), "gmp integer expected")
+end
+
+local function checkf(obj)
+ assert(isf(obj), "gmp floating point expected")
+end
+
+local function checkfopt(obj)
+ assert(obj == nil or isf(obj), "gmp floating point expected")
+end
+
+local dtoz = prv.mpz_init_set_d
+local dtof = prv.mpf_init_set_d
+
+function z(value, base)
+ if value == nil then
+ return prv.mpz_init()
+ elseif type(value) == "number" then
+ return dtoz(value)
+ elseif type(value) == "string" then
+ if base == nil then
+ base = 0
+ elseif base ~= 0 then
+ checkbase(base)
+ end
+ local res = prv.mpz_init_set_str(value, base)
+ if res then return res end
+ error("not a valid integer constant in base " .. base .. ": " .. value)
+ elseif isz(value) then
+ return prv.mpz_init_set(value)
+ elseif isf(value) then
+ local res = prv.mpz_init()
+ prv.mpz_set_f(res, value)
+ return res
+ else
+ error("cannot initialize gmp integer from " .. type(value))
+ end
+end
+
+function f(value, base)
+ if value == nil then
+ return prv.mpf_init()
+ elseif type(value) == "number" then
+ return dtof(value)
+ elseif type(value) == "string" then
+ if base == nil then
+ base = 10
+ elseif type(base) == "number" and base < 0 then
+ checkbase(-base)
+ else
+ checkbase(base)
+ end
+ local res = prv.mpf_init_set_str(value, base)
+ if res then return res end
+ error("not a valid floating point constant in base " .. base .. ": " .. value)
+ elseif isf(value) then
+ return prv.mpf_init_set(value)
+ elseif isz(value) then
+ local res = prv.mpf_init()
+ prv.mpf_set_z(res, value)
+ return res
+ else
+ error("cannot initialize gmp floating point from " .. type(value))
+ end
+end
+
+function zmeta:__tostring()
+ checkz(self)
+ return prv.mpz_get_str(10, self)
+end
+
+function zmeta:__concat(other)
+ if isz(self) then
+ return zmeta.get_str(self) .. other
+ else
+ return self .. zmeta.get_str(other)
+ end
+end
+
+function zmeta:__add(other)
+ if isz(self) then
+ return zmeta.add(self, other)
+ else
+ return zmeta.add(other, self)
+ end
+end
+
+function zmeta:__sub(other)
+ if isz(self) then
+ return zmeta.sub(self, other)
+ else
+ return zmeta.rsub(other, self)
+ end
+end
+
+function zmeta:__mul(other)
+ if isz(self) then
+ return zmeta.mul(self, other)
+ else
+ return zmeta.mul(other, self)
+ end
+end
+
+function zmeta:__div(other)
+ if isz(self) then
+ return zmeta.fdiv_q(self, other)
+ elseif type(other) == "number" then
+ return zmeta.fdiv_q(dtoz(self), other)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:__mod(other)
+ if isz(self) then
+ return zmeta.fdiv_r(self, other)
+ elseif type(self) == "number" then
+ return zmeta.fdiv_r(dtoz(self), other)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:__pow(exp)
+ checkz(self)
+ checku(exp)
+ return prv.mpz_pow_ui(self, exp)
+end
+
+function zmeta:__unm()
+ checkz(self)
+ return prv.mpz_neg(self)
+end
+
+function zmeta:__lt(other)
+ checkz(self)
+ checkz(other)
+ return prv.mpz_cmp(self, other) < 0
+end
+
+function zmeta:__le(other)
+ checkz(self)
+ checkz(other)
+ return prv.mpz_cmp(self, other) <= 0
+end
+
+function zmeta:__eq(other)
+ checkz(self)
+ checkz(other)
+ return prv.mpz_cmp(self, other) == 0
+end
+
+function zmeta:__gc()
+ checkz(self)
+ return prv.mpz_clear(self)
+end
+
+function zmeta:abs(res)
+ checkz(self)
+ checkzopt(res)
+ return prv.mpz_abs(self, res)
+end
+
+function zmeta:add(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_add(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_add_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_sub_ui(self, -a, res)
+ elseif t == "z" then
+ return prv.mpz_add(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:addmul(a1, a2)
+ checkz(self)
+ checkz(a1)
+ local t = ntype(a2)
+ if t == "d" then
+ prv.mpz_addmul(self, a1, dtoz(a2))
+ elseif t == "u" then
+ prv.mpz_addmul_ui(self, a1, a2)
+ elseif t == "s" or t == "n" then
+ prv.mpz_submul_ui(self, a1, -a2)
+ elseif t == "z" then
+ prv.mpz_addmul(self, a1, a2)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:And(a, res)
+ checkz(self)
+ checkzopt(res)
+ if type(a) == "number" then
+ return prv.mpz_and(self, dtoz(a), res)
+ elseif isz(a) then
+ return prv.mpz_and(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:bin(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+
+ return prv.mpz_bin_ui(self, a, res)
+end
+
+function bin(a1, a2, res)
+ checku(a2)
+ checkzopt(res)
+ local t = ntype(a1)
+ if t == "d" then
+ return prv.mpz_bin_ui(dtoz(a1), a2, res)
+ elseif t == "u" then
+ return prv.mpz_bin_uiui(a1, a2, res)
+ elseif t == "s" or t == "n" then
+ if a2 <= prv.ULONG_MAX + a1 then
+ res = prv.mpz_bin_uiui(a2 - a1 - 1, a2, res)
+ if a2%2 ~= 0 then
+ prv.mpz_neg(res, res)
+ end
+ return res
+ else
+ return prv.mpz_bin_ui(dtoz(a1), a2, res)
+ end
+ elseif t == "z" then
+ return prv.mpz_bin_ui(a1, a2, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:cdiv_q(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_cdiv_q(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_cdiv_q_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ local r2
+ res, r2 = prv.mpz_fdiv_q_ui(self, -a, res)
+ return prv.mpz_neg(res, res), r2
+ elseif t == "z" then
+ return prv.mpz_cdiv_q(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:cdiv_q_2exp(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_cdiv_q_2exp(self, a, res)
+end
+
+function zmeta:cdiv_qr(a, r1, r2)
+ checkz(self)
+ checkzopt(r1)
+ checkzopt(r2)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_cdiv_qr(self, dtoz(a), r1, r2)
+ elseif t == "u" then
+ return prv.mpz_cdiv_qr_ui(self, a, r1, r2)
+ elseif t == "s" or t == "n" then
+ local r3
+ r1, r2, r3 = prv.mpz_fdiv_qr_ui(self, -a, r1, r2)
+ return prv.mpz_neg(r1, r1), r2, r3
+ elseif t == "z" then
+ return prv.mpz_cdiv_qr(self, a, r1, r2)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:cdiv_r(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_cdiv_r(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_cdiv_r_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_fdiv_r_ui(self, -a, res)
+ elseif t == "z" then
+ return prv.mpz_cdiv_r(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:cdiv_r_2exp(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_cdiv_r_2exp(self, a, res)
+end
+
+function zmeta:cdiv(a)
+ checkz(self)
+ local t = ntype(a)
+ if t == "u" then
+ return prv.mpz_cdiv_ui(self, a)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_cdiv_ui(self, -a)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:clrbit(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_clrbit(self, a, res)
+end
+
+function zmeta:cmp(a)
+ checkz(self)
+ local t = ntype(a)
+ if t == "d" or t == "n" then
+ return prv.mpz_cmp_d(self, a)
+ elseif t == "u" then
+ return prv.mpz_cmp_ui(self, a)
+ elseif t == "s" then
+ return prv.mpz_cmp_si(self, a)
+ elseif t == "z" then
+ return prv.mpz_cmp(self, a)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:cmpabs(a)
+ checkz(self)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_cmpabs_d(self, a)
+ elseif t == "u" then
+ return prv.mpz_cmpabs_ui(self, a)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_cmpabs_ui(self, -a)
+ elseif t == "z" then
+ return prv.mpz_cmpabs(self, a)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:com(res)
+ checkz(self)
+ checkzopt(res)
+ return prv.mpz_com(self, res)
+end
+
+function zmeta:combit(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_combit(self, a, res)
+end
+
+function zmeta:congruent(a1, a2)
+ checkz(self)
+ local t1, t2 = ntype(a1), ntype(a2)
+ if t1 == "z" and t2 == "z" then
+ return prv.mpz_congruent_p(self, a1, a2) ~= 0
+ elseif t1 == "u" and t2 == "u" then
+ return prv.mpz_congruent_ui_p(self, a1, a2) ~= 0
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:congruent_2exp(a1, a2)
+ checkz(self)
+ checkz(a1)
+ checku(a2)
+ return prv.mpz_congruent_2exp_p(self, a1, a2) ~= 0
+end
+
+function zmeta:divexact(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_divexact(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_divexact_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ res = prv.mpz_divexact_ui(self, -a, res)
+ return prv.mpz_neg(res, res)
+ elseif t == "z" then
+ return prv.mpz_divexact(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:divisible(a)
+ checkz(self)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_divisible_p(self, dtoz(a)) ~= 0
+ elseif t == "u" then
+ return prv.mpz_divisible_ui_p(self, a) ~= 0
+ elseif t == "s" or t == "n" then
+ return prv.mpz_divisible_ui_p(self, -a) ~= 0
+ elseif t == "z" then
+ return prv.mpz_divisible_p(self, a) ~= 0
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:divisible_2exp(a)
+ checkz(self)
+ checku(a)
+ return prv.mpz_divisible_2exp_p(self, a) ~= 0
+end
+
+function fac(a, res)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_fac_ui(a, res)
+end
+
+function zmeta:fdiv_q(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_fdiv_q(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_fdiv_q_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ local r2
+ res, r2 = prv.mpz_cdiv_q_ui(self, -a, res)
+ return prv.mpz_neg(res, res), r2
+ elseif t == "z" then
+ return prv.mpz_fdiv_q(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:fdiv_q_2exp(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_fdiv_q_2exp(self, a, res)
+end
+
+function zmeta:fdiv_qr(a, r1, r2)
+ checkz(self)
+ checkzopt(r1)
+ checkzopt(r2)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_fdiv_qr(self, dtoz(a), r1, r2)
+ elseif t == "u" then
+ return prv.mpz_fdiv_qr_ui(self, a, r1, r2)
+ elseif t == "s" or t == "n" then
+ local r3
+ r1, r2, r3 = prv.mpz_cdiv_qr_ui(self, -a, r1, r2)
+ return prv.mpz_neg(r1, r1), r2, r3
+ elseif t == "z" then
+ return prv.mpz_fdiv_qr(self, a, r1, r2)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:fdiv_r(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_fdiv_r(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_fdiv_r_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_cdiv_r_ui(self, -a, res)
+ elseif t == "z" then
+ return prv.mpz_fdiv_r(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:fdiv_r_2exp(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_fdiv_r_2exp(self, a, res)
+end
+
+function zmeta:fdiv(a)
+ checkz(self)
+ local t = ntype(a)
+ if t == "u" then
+ return prv.mpz_fdiv_ui(self, a)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_fdiv_ui(self, -a)
+ else
+ error("unsupported type")
+ end
+end
+
+function fib(a, res)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_fib_ui(a, res)
+end
+
+function fib2(a, r1, r2)
+ checku(a)
+ checkzopt(r1)
+ checkzopt(r2)
+ return prv.mpz_fib2_ui(a, r1, r2)
+end
+
+function zmeta:fits_sint()
+ checkz(self)
+ return prv.mpz_fits_sint_p(self) ~= 0
+end
+
+function zmeta:fits_slong()
+ checkz(self)
+ return prv.mpz_fits_slong_p(self) ~= 0
+end
+
+function zmeta:fits_sshort()
+ checkz(self)
+ return prv.mpz_fits_sshort_p(self) ~= 0
+end
+
+function zmeta:fits_uint()
+ checkz(self)
+ return prv.mpz_fits_uint_p(self) ~= 0
+end
+
+function zmeta:fits_ulong()
+ checkz(self)
+ return prv.mpz_fits_ulong_p(self) ~= 0
+end
+
+function zmeta:fits_ushort()
+ checkz(self)
+ return prv.mpz_fits_ushort_p(self) ~= 0
+end
+
+function zmeta:gcd(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_gcd(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_gcd_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_gcd_ui(self, -a, res)
+ elseif t == "z" then
+ return prv.mpz_gcd(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:gcdext(a, r1, r2, r3)
+ checkz(self)
+ checkz(a)
+ checkzopt(r1)
+ checkzopt(r2)
+ checkzopt(r3)
+ return prv.mpz_gcdext(self, a, r1, r2, r3)
+end
+
+function zmeta:get_d()
+ checkz(self)
+ return prv.mpz_get_d(self)
+end
+
+function zmeta:get_d_2exp()
+ checkz(self)
+ return prv.mpz_get_d_2exp(self)
+end
+
+function zmeta:get_str(base)
+ checkz(self)
+ if base == nil then base = 10 else checkbase(base) end
+ return prv.mpz_get_str(base, self)
+end
+
+function zmeta:hamdist(a)
+ checkz(self)
+ checkz(a)
+ return prv.mpz_hamdist(self, a)
+end
+
+function zmeta:invert(a, res)
+ checkz(self)
+ checkz(a)
+ checkzopt(res)
+ local r2
+ res, r2 = prv.mpz_invert(self, a, res)
+ if r2 ~= 0 then
+ return res
+ end
+end
+
+function zmeta:ior(a, res)
+ checkz(self)
+ checkzopt(res)
+ if type(a) == "number" then
+ return prv.mpz_ior(self, dtoz(a), res)
+ elseif isz(a) then
+ return prv.mpz_ior(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:kronecker(a)
+ checkz(self)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_kronecker(self, dtoz(a))
+ elseif t == "u" then
+ return prv.mpz_kronecker_ui(self, a)
+ elseif t == "s" then
+ return prv.mpz_kronecker_si(self, a)
+ elseif t == "n" then
+ return prv.mpz_kronecker(self, dtoz(a))
+ elseif t == "z" then
+ return prv.mpz_kronecker(self, a)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:rkronecker(a)
+ checkz(self)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_kronecker(dtoz(a), self)
+ elseif t == "u" then
+ return prv.mpz_ui_kronecker(a, self)
+ elseif t == "s" then
+ return prv.mpz_si_kronecker(a, self)
+ elseif t == "n" then
+ return prv.mpz_kronecker(dtoz(a), self)
+ elseif t == "z" then
+ return prv.mpz_kronecker(a, self)
+ else
+ error("unsupported type")
+ end
+end
+
+zmeta.jacobi = zmeta.kronecker
+zmeta.rjacobi = zmeta.rkronecker
+
+zmeta.legendre = zmeta.kronecker
+zmeta.rlegendre = zmeta.rkronecker
+
+function zmeta:lcm(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_lcm(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_lcm_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_lcm_ui(self, -a, res)
+ elseif t == "z" then
+ return prv.mpz_lcm(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function lucnum(a, res)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_lucnum_ui(a, res)
+end
+
+function lucnum2(a, r1, r2)
+ checku(a)
+ checkzopt(r1)
+ checkzopt(r2)
+ return prv.mpz_lucnum2_ui(a, r1, r2)
+end
+
+function zmeta:mod(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_mod(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_fdiv_r_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_cdiv_r_ui(self, -a, res)
+ elseif t == "z" then
+ return prv.mpz_mod(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:mul(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_mul(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_mul_ui(self, a, res)
+ elseif t == "s" then
+ return prv.mpz_mul_si(self, a, res)
+ elseif t == "n" then
+ res = prv.mpz_mul_ui(self, -a, res)
+ return prv.mpz_neg(res, res)
+ elseif t == "z" then
+ return prv.mpz_mul(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:mul_2exp(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(self)
+ return prv.mpz_mul_2exp(self, a, res)
+end
+
+function zmeta:neg(res)
+ checkz(self)
+ checkzopt(res)
+ return prv.mpz_neg(self, res)
+end
+
+function zmeta:nextprime(res)
+ checkz(self)
+ checkzopt(res)
+ return prv.mpz_nextprime(self, res)
+end
+
+function zmeta:perfect_power()
+ checkz(self)
+ return prv.mpz_perfect_power_p(self) ~= 0
+end
+
+function zmeta:perfect_square()
+ checkz(self)
+ return prv.mpz_perfect_square_p(self) ~= 0
+end
+
+function zmeta:popcount()
+ checkz(self)
+ return prv.mpz_popcount(self)
+end
+
+function zmeta:pow(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_pow_ui(self, a, res)
+end
+
+function zmeta:powm(a1, a2, res)
+ checkz(self)
+ checkz(a2)
+ checkzopt(res)
+ local t = ntype(a1)
+ if t == "d" then
+ return prv.mpz_powm(self, dtoz(a1), a2, res)
+ elseif t == "u" then
+ return prv.mpz_powm_ui(self, a1, a2, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_powm(self, dtoz(a1), a2, res)
+ elseif t == "z" then
+ return prv.mpz_powm(self, a1, a2, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:probab_prime(a)
+ checkz(self)
+ if a == nil then a = 10 else ckechn(a) end
+ local res = prv.mpz_probab_prime_p(self, a)
+ return res ~= 0 and res
+end
+
+function zmeta:remove(a, res)
+ checkz(self)
+ checkzopt(res)
+ if type(a) == "number" then
+ return prv.mpz_remove(self, dtoz(a), res)
+ elseif isz(a) then
+ return prv.mpz_rempve(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:root(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ local r2
+ res, r2 = prv.mpz_root(self, a, res)
+ return res, r2 ~= 0
+end
+
+function zmeta:rootrem(a, r1, r2)
+ checkz(self)
+ checku(a)
+ checkzopt(r1)
+ checkzopt(r2)
+ return prv.mpz_rootrem(self, a, r1, r2)
+end
+
+function zmeta:scan0(a)
+ checkz(self)
+ if a == nil then a = 0 else checku(a) end
+ return prv.mpz_scan0(self, a)
+end
+
+function zmeta:scan1(a)
+ checkz(self)
+ if a == nil then a = 0 else checku(a) end
+ return prv.mpz_scan1(self, a)
+end
+
+function zmeta:set(a, base)
+ checkz(self)
+ if type(a) == "number" then
+ prv.mpz_set_d(self, a)
+ elseif type(a) == "string" then
+ if base == nil then
+ base = 0
+ elseif base ~= 0 then
+ checkbase(base)
+ end
+ if prv.mpz_set_str(self, a, base) ~= 0 then
+ error("not a valid integer constant in base " .. base .. ": " .. a)
+ end
+ elseif isz(a) then
+ prv.mpz_set(self, a)
+ elseif isf(a) then
+ prv.mpz_set_f(self, a)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:setbit(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_setbit(self, a, res)
+end
+
+function zmeta:sgn()
+ checkz(self)
+ return prv.mpz_sgn(self)
+end
+
+function zmeta:sizeinbase(a)
+ checkz(self)
+ if a == nil then a = 10 else checkbase(a) end
+ return prv.mpz_sizeinbase(self, a)
+end
+
+function zmeta:sqrt(res)
+ checkz(self)
+ assert(prv.mpz_sgn(self) >= 0, "taking square of negative number")
+ checkzopt(res)
+ return prv.mpz_sqrt(self, res)
+end
+
+function zmeta:sqrtrem(r1, r2)
+ checkz(self)
+ assert(prv.mpz_sgn(self) >= 0, "taking square of negative number")
+ checkzopt(r1)
+ checkzopt(r2)
+ return prv.mpz_sqrtrem(self, r1, r2)
+end
+
+function zmeta:sub(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_sub(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_sub_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_add_ui(self, -a, res)
+ elseif t == "z" then
+ return prv.mpz_sub(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:rsub(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a1)
+ if t == "d" then
+ return prv.mpz_sub(dtoz(a), self, res)
+ elseif t == "u" then
+ return prv.mpz_ui_sub(a, self, res)
+ elseif t == "s" or t == "n" then
+ res = prv.mpz_add_ui(self, -a, res)
+ return prv.mpz_neg(res, res)
+ elseif t == "z" then
+ return prv.mpz_sub(a, self, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:submul(a1, a2)
+ checkz(self)
+ checkz(a1)
+ local t = ntype(a2)
+ if t == "d" then
+ prv.mpz_submul(self, a1, dtoz(a2))
+ elseif t == "u" then
+ prv.mpz_submul_ui(self, a1, a2)
+ elseif t == "s" or t == "n" then
+ prv.mpz_addmul_ui(self, a1, -a2)
+ elseif t == "z" then
+ prv.mpz_submul(self, a1, a2)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:tdiv_q(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_tdiv_q(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_tdiv_q_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ local r2
+ res, r2 = prv.mpz_tdiv_q_ui(self, -a, res)
+ return prv.mpz_neg(res, res), r2
+ elseif t == "z" then
+ return prv.mpz_tdiv_q(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:tdiv_q_2exp(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_tdiv_q_2exp(self, a, res)
+end
+
+function zmeta:tdiv_qr(a, r1, r2)
+ checkz(self)
+ checkzopt(r1)
+ checkzopt(r2)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_tdiv_qr(self, dtoz(a), r1, r2)
+ elseif t == "u" then
+ return prv.mpz_tdiv_qr_ui(self, a, r1, r2)
+ elseif t == "s" or t == "n" then
+ local r3
+ r1, r2, r3 = prv.mpz_tdiv_qr_ui(self, -a, r1, r2)
+ return prv.mpz_neg(r1, r1), r2, r3
+ elseif t == "z" then
+ return prv.mpz_tdiv_qr(self, a, r1, r2)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:tdiv_r(a, res)
+ checkz(self)
+ checkzopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpz_tdiv_r(self, dtoz(a), res)
+ elseif t == "u" then
+ return prv.mpz_tdiv_r_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_tdiv_r_ui(self, -a, res)
+ elseif t == "z" then
+ return prv.mpz_tdiv_r(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:tdiv_r_2exp(a, res)
+ checkz(self)
+ checku(a)
+ checkzopt(res)
+ return prv.tdiv_r_2exp(self, a, res)
+end
+
+function zmeta:tdiv(a)
+ checkz(self)
+ local t = ntype(a)
+ if t == "u" then
+ return prv.mpz_tdiv_ui(self, a)
+ elseif t == "s" or t == "n" then
+ return prv.mpz_tdiv_ui(self, -a)
+ else
+ error("unsupported type")
+ end
+end
+
+function zmeta:tstbit(a)
+ checkz(self)
+ checku(a)
+ return prv.mpz_tstbit(self, a)
+end
+
+function pow(a1, a2, res)
+ checku(a2)
+ checkzopt(res)
+ local t = ntype(a1)
+ if t == "d" then
+ return prv.mpz_pow_ui(dtoz(a1), a2, res)
+ elseif t == "u" then
+ return prv.mpz_ui_pow_ui(a1, a2, res)
+ elseif t == "s" or t == "n" then
+ res = prv.mpz_ui_pow_ui(-a1, a2, res)
+ if a2%2 ~= 0 then
+ prv.mpz_neg(res, res)
+ end
+ return res
+ elseif t == "z" then
+ return prv.mpz_pow_ui(a1, a2, res)
+ else
+ error("unsupported type")
+ end
+ return prv.mpz_ui_pow_ui(a1, a2, res)
+end
+
+function zmeta:xor(a, res)
+ checkz(self)
+ checkzopt(res)
+ if type(a) == "number" then
+ return prv.mpz_xor(self, dtoz(a), res)
+ elseif isz(a) then
+ return prv.mpz_xor(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function fmeta:abs(res)
+ checkf(self)
+ checkfopt(res)
+ return prv.mpf_abs(self, res)
+end
+
+function fmeta:add(a, res)
+ checkf(self)
+ checkfopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpf_add(self, dtof(a), res)
+ elseif t == "u" then
+ return prv.mpf_add_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpf_sub_ui(self, -a, res)
+ elseif t == "f" then
+ return prv.mpf_add(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function fmeta:ceil(res)
+ checkf(self)
+ checkfopt(res)
+ return prv.mpf_ceil(self, res)
+end
+
+function fmeta:cmp(a)
+ checkf(self)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpf_cmp_d(self, a)
+ elseif t == "u" then
+ return prv.mpf_cmp_ui(self, a)
+ elseif t == "s" then
+ return prv.mpf_cmp_si(self, a)
+ elseif t == "n" then
+ return prv.mpf_cmp(self, dtof(a))
+ elseif t == "f" then
+ return prv.mpf_cmp(self, a)
+ else
+ error("unsupported type")
+ end
+end
+
+function fmeta:div(a, res)
+ checkf(self)
+ checkfopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpf_div(self, dtof(a), res)
+ elseif t == "u" then
+ return prv.mpf_div_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ res = prv.mpf_div_ui(self, -a, res)
+ return prv.mpf_neg(res, res);
+ elseif t == "f" then
+ return prv.mpf_div(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function fmeta:eq(a1, a2)
+ checkf(self)
+ checkf(a1)
+ checku(a2)
+ return prv.mpf_eq(self, a1, a2) ~= 0
+end
+
+function fmeta:fits_sint()
+ checkf(self)
+ return prv.mpf_fits_sint_p(self) ~= 0
+end
+
+function fmeta:fits_sshort()
+ checkf(self)
+ return prv.mpf_fits_sshort_p(self) ~= 0
+end
+
+function fmeta:fits_uint()
+ checkf(self)
+ return prv.mpf_fits_uint_p(self) ~= 0
+end
+
+function fmeta:fits_ulong()
+ checkf(self)
+ return prv.mpf_fits_ulong_p(self) ~= 0
+end
+
+function fmeta:fits_ushort()
+ checkf(self)
+ return prv.mpf_fits_ushort_p(self) ~= 0
+end
+
+function fmeta:floor(res)
+ checkf(self)
+ checkfopt(res)
+ return prv.mpf_floor(self, res)
+end
+
+function fmeta:get_d()
+ checkf(self)
+ return prv.mpf_get_d(self)
+end
+
+function fmeta:get_d_2exp()
+ checkf(self)
+ return prv.mpf_get_d_2exp(self)
+end
+
+get_default_prec = prv.mpf_get_default_prec
+
+function fmeta:get_prec()
+ checkf(self)
+ return prv.mpf_get_prec(self)
+end
+
+function fmeta:get_str(base, size)
+ checkf(self)
+ if base == nil then base = 10 else checkbase(base) end
+ if size == nil then size = 0 else checkn(size) end
+ return prv.mpf_get_str(base, size, self)
+end
+
+function fmeta:integer()
+ checkf(self)
+ return prv.mpf_integer_p(self) ~= 0
+end
+
+function fmeta:mul(a, res)
+ checkf(self)
+ checkfopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpf_mul(self, dtof(a), res)
+ elseif t == "u" then
+ return prv.mpf_mul_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ res = prv.mpf_mul_ui(self, -a, res)
+ return prv.mpf_neg(res, res)
+ elseif t == "f" then
+ return prv.mpf_mul(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function fmeta:mul_2exp(a, res)
+ checkf(self)
+ checku(a)
+ checkfopt(res)
+ return prv.mpf_mul_2exp(self, a, res)
+end
+
+function fmeta:neg(res)
+ checkf(self)
+ checkfopt(res)
+ return prv.mpf_neg(self, res)
+end
+
+function fmeta:pow(a, res)
+ checkf(self)
+ checku(a)
+ checkfopt(res)
+ return prv.mpf_pow_ui(self, a, res)
+end
+
+function fmeta:reldiff(a, res)
+ checkf(self)
+ checkf(a)
+ checkfopt(res)
+ return prv.mpf_reldiff(self, a, res)
+end
+
+function set_default_prec(a)
+ checku(a)
+ prv.mpf_set_default_prec(a)
+end
+
+function fmeta:set_prec(a)
+ checkf(self)
+ checku(a)
+ prv.mpf_set_prec(self, a)
+end
+
+function fmeta:set(a, base)
+ checkf(self)
+ if type(a) == "number" then
+ prv.mpf_set_d(self, a)
+ elseif type(a) == "string" then
+ if base == nil then
+ base = 10
+ elseif type(base) == "number" and base < 0 then
+ checkbase(-base)
+ else
+ checkbase(base)
+ end
+ if prv.mpf_set_str(self, a, base) ~= 0 then
+ error("not a valid floating point constant in base " .. base .. ": " .. a)
+ end
+ elseif isf(a) then
+ prv.mpf_set(self, a)
+ elseif isz(a) then
+ prv.mpf_set_z(self, a)
+ else
+ error("unsupported type")
+ end
+end
+
+function fmeta:sgn()
+ checkf(self)
+ return prv.mpf_sgn(self)
+end
+
+function fmeta:sqrt(res)
+ checkf(self)
+ checkfopt(res)
+ return prv.mpf_sqrt(self, res)
+end
+
+function sqrt(a, res)
+ checku(a)
+ checkfopt(res)
+ return prv.mpf_sqrt_ui(a, res)
+end
+
+function fmeta:sub(a, res)
+ checkf(self)
+ checkfopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpf_sub(self, dtof(a), res)
+ elseif t == "u" then
+ return prv.mpf_sub_ui(self, a, res)
+ elseif t == "s" or t == "n" then
+ return prv.mpf_add_ui(self, -a, res)
+ elseif t == "f" then
+ return prv.mpf_sub(self, a, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function fmeta:trunc(res)
+ checkf(self)
+ checkfopt(res)
+ return prv.mpf_trunc(self, res)
+end
+
+function fmeta:rdiv(a, res)
+ checkf(self)
+ checkfopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpf_div(dtof(a), self, res)
+ elseif t == "u" then
+ return prv.mpf_ui_div(a, self, res)
+ elseif t == "s" or t == "n" then
+ res = prv.mpf_ui_div(-a, self, res)
+ return prv.mpf_neg(res, res)
+ elseif t == "f" then
+ return prv.mpf_div(a, self, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function fmeta:rsub(a, res)
+ checkf(self)
+ checkfopt(res)
+ local t = ntype(a)
+ if t == "d" then
+ return prv.mpf_sub(dtof(a), self, res)
+ elseif t == "u" then
+ return prv.mpf_ui_sub(a, self, res)
+ elseif t == "s" or t == "n" then
+ res = prv.mpf_add_ui(self, -a, res)
+ return prv.mpf_neg(res, res)
+ elseif t == "f" then
+ return prv.mpf_sub(a, self, res)
+ else
+ error("unsupported type")
+ end
+end
+
+function fmeta:__add(a)
+ if isf(self) then
+ return fmeta.add(self, a)
+ else
+ return fmeta.add(a, self)
+ end
+end
+
+function fmeta:__sub(a)
+ if isf(self) then
+ return fmeta.sub(self, a)
+ else
+ return fmeta.rsub(a, self)
+ end
+end
+
+function fmeta:__mul(a)
+ if isf(self) then
+ return fmeta.mul(self, a)
+ else
+ return fmeta.mul(a, self)
+ end
+end
+
+function fmeta:__div(a)
+ if isf(self) then
+ return fmeta.div(self, a)
+ else
+ return fmeta.rdiv(a, self)
+ end
+end
+
+function fmeta:__unm()
+ checkf(self)
+ return prv.mpf_neg(self)
+end
+
+function fmeta:__pow(a)
+ checkf(self)
+ checku(a)
+ return prv.mpf_pow_ui(self, a)
+end
+
+function fmeta:__lt(a)
+ checkf(self)
+ checkf(a)
+ return prv.mpf_cmp(self, a) < 0
+end
+
+function fmeta:__le(a)
+ checkf(self)
+ checkf(a)
+ return prv.mpf_cmp(self, a) <= 0
+end
+
+function fmeta:__eq(a)
+ checkf(self)
+ checkf(a)
+ return prv.mpf_cmp(self, a) == 0
+end
+
+function fmeta:__tostring()
+ return fmeta.format(self, ".g")
+end
+
+function fmeta:__concat(other)
+ if isf(self) then
+ return fmeta.__tostring(self) .. other
+ else
+ return self .. fmeta.__tostring(other)
+ end
+end
+
+function fmeta:__gc()
+ checkf(self)
+ return prv.mpf_clear(self)
+end
+
+function rand(a)
+ if a == nil then
+ return prv.gmp_randinit_default()
+ else
+ checkrand(a)
+ return prv.gmp_randinit_set(a)
+ end
+end
+
+function randmeta:seed(a)
+ checkrand(self)
+ local t = ntype(a)
+ if a == "u" then
+ prv.gmp_randseed_ui(self, a)
+ elseif a == "z" then
+ prv.gmp_randseed(self, a)
+ else
+ error("unsupported type")
+ end
+end
+
+function randmeta:zbits(a, res)
+ checkrand(self)
+ checku(a)
+ checkzopt(res)
+ return prv.mpz_urandomb(self, a, res)
+end
+
+function randmeta:z(a, res)
+ checkrand(self)
+ checkz(a)
+ checkzopt(res)
+ return prv.mpz_urandomm(self, a, res)
+end
+
+function randmeta:fbits(a, res)
+ checkrand(self)
+ checku(a)
+ checkfopt(res)
+ return prv.mpf_urandomb(self, a, res)
+end
+
+function randmeta:__gc()
+ checkrand(self)
+ prv.gmp_randclear(self)
+end
+
+function randmeta:__tostring()
+ checkrand(self)
+ return "gmp random state"
+end
+
+function zmeta:format(fmt, p)
+ checkz(self)
+ assert(type(fmt) == "string", "gmp integer format string expected")
+ local fw, prec, conv =
+ match(fmt, "^%%?([0#+ ]?%d*)(%.?%*?%d*)Z?([dioxX])$")
+
+ if not conv or prec ~= "" and prec ~= ".*" and not match(prec, "^%.%d*$") then
+ error("invalid format string for gmp integer: " .. fmt)
+ end
+
+ if prec == ".*" then
+ checkn(p)
+ else
+ assert(p == nil, "precision incorrectly specified")
+ end
+
+ return prv.mpz_asprintf("%" .. fw .. prec .. "Z" .. conv, self, p)
+end
+
+function fmeta:format(fmt, p)
+ checkf(self)
+ assert(type(fmt) == "string", "gmp floating point format string expected")
+ local fw, prec, conv =
+ match(fmt, "^%%?([0#+ ]?%d*)(%.?%*?%d*)F?([aAeEfgG])$")
+
+ if not conv or prec ~= "" and prec ~= ".*" and not match(prec, "^%.%d*$") then
+ error("invalid format string for gmp floating point: " .. fmt)
+ end
+
+ if prec == ".*" then
+ checkn(p)
+ else
+ assert(p == nil, "precision incorrectly specified")
+ end
+
+ return prv.mpf_asprintf("%" .. fw .. prec .. "F" .. conv, self, p)
+end
+
+function lgmp_lua_init(l_prv, l_aux)
+ aux.randmeta = randmeta
+ aux.zmeta = zmeta
+ aux.fmeta = fmeta
+
+ prv = l_prv
+ aux = l_aux
+
+ lgmpversion = prv.version
+
+ lgmp_init = nil
+end
+
diff --git a/src/plugin-luagmp.cc b/src/plugin-luagmp.cc
new file mode 100644
index 0000000..f843400
--- /dev/null
+++ b/src/plugin-luagmp.cc
@@ -0,0 +1,2532 @@
+
+/*
+ * This file is part of the lgmp package for Lua 5.1.
+ *
+ * Author: Wim Couwenberg
+ * Date : 2007/7/28
+ *
+ * The lgmp package is distributed under the MIT license. See the file
+ * "COPYRIGHT" that came with the lgmp package distribution for license
+ * details.
+ */
+
+/*
+ * Adapted for lua-interface by Nicolas "Pixel" Noble
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "BLua.h"
+#include "Buffer.h"
+#include "gmp.h"
+
+#ifdef FROM_LUAINTERFACE
+#define NO_DLL
+#endif
+
+#ifndef WIN32
+#define WEAK __attribute__ ((weak))
+#else
+#define WEAK
+#endif
+
+static const char lgmp_metarand[] = "randmeta";
+static const char lgmp_metaz[] = "zmeta";
+static const char lgmp_metaf[] = "fmeta";
+
+static void lgmp_free_str(char *data)
+{
+ void (*current_free)(void *data, size_t size);
+
+ mp_get_memory_functions(NULL, NULL, &current_free);
+
+ if (current_free == NULL)
+ free(data);
+ else
+ (*current_free)(data, strlen(data) + 1);
+}
+
+static gmp_randstate_t *lgmp_rawrand(lua_State *L)
+{
+ gmp_randstate_t *pr = (gmp_randstate_t *)lua_newuserdata(L, sizeof(gmp_randstate_t));
+ lua_getfield(L, LUA_ENVIRONINDEX, lgmp_metarand);
+ lua_setmetatable(L, -2);
+
+ return pr;
+}
+
+static gmp_randstate_t *lgmp_torand(lua_State *L, int idx)
+{
+ return (gmp_randstate_t *)lua_touserdata(L, idx);
+}
+
+static mpz_t *lgmp_toz(lua_State *L, int idx)
+{
+ return (mpz_t *)lua_touserdata(L, idx);
+}
+
+static mpz_t *lgmp_rawz(lua_State *L)
+{
+ mpz_t *pz = (mpz_t *)lua_newuserdata(L, sizeof(mpz_t));
+ lua_getfield(L, LUA_ENVIRONINDEX, lgmp_metaz);
+ lua_setmetatable(L, -2);
+
+ return pz;
+}
+
+static mpz_t *lgmp_optz(lua_State *L, int idx, int top)
+{
+ mpz_t *pz;
+
+ if (top > 0)
+ lua_settop(L, top);
+
+ if (!lua_isnil(L, idx))
+ pz = lgmp_toz(L, idx);
+ else
+ {
+ pz = lgmp_rawz(L);
+ mpz_init(*pz);
+ lua_replace(L, idx);
+ }
+
+ return pz;
+}
+
+static mpf_t *lgmp_tof(lua_State *L, int idx)
+{
+ return (mpf_t *)lua_touserdata(L, idx);
+}
+
+static mpf_t *lgmp_rawf(lua_State *L)
+{
+ mpf_t *pf = (mpf_t *)lua_newuserdata(L, sizeof(mpf_t));
+ lua_getfield(L, LUA_ENVIRONINDEX, lgmp_metaf);
+ lua_setmetatable(L, -2);
+
+ return pf;
+}
+
+static mpf_t *lgmp_optf(lua_State *L, int idx, int top)
+{
+ mpf_t *pf;
+
+ if (top > 0)
+ lua_settop(L, top);
+
+ if (!lua_isnil(L, idx))
+ pf = lgmp_tof(L, idx);
+ else
+ {
+ pf = lgmp_rawf(L);
+ mpf_init(*pf);
+ lua_replace(L, idx);
+ }
+
+ return pf;
+}
+
+static int lmpz_asprintf(lua_State *L)
+{
+ char *str;
+ const char *a1 = lua_tostring(L, 1);
+ mpz_t *a2 = lgmp_toz(L, 2);
+
+ if (lua_isnil(L, 3))
+ gmp_asprintf(&str, a1, *a2);
+ else
+ {
+ int a3 = lua_tointeger(L, 3);
+ gmp_asprintf(&str, a1, a3, *a2);
+ }
+
+ lua_pushstring(L, str);
+ lgmp_free_str(str);
+
+ return 1;
+}
+
+static int lmpf_asprintf(lua_State *L)
+{
+ char *str;
+ const char *a1 = lua_tostring(L, 1);
+ mpf_t *a2 = lgmp_tof(L, 2);
+
+ if (lua_isnil(L, 3))
+ gmp_asprintf(&str, a1, *a2);
+ else
+ {
+ int a3 = lua_tointeger(L, 3);
+ gmp_asprintf(&str, a1, a3, *a2);
+ }
+
+ lua_pushstring(L, str);
+ lgmp_free_str(str);
+
+ return 1;
+}
+
+static int lgmp_randinit_default(lua_State *L)
+{
+ gmp_randstate_t *res = lgmp_rawrand(L);
+
+ gmp_randinit_default(*res);
+
+ return 1;
+}
+
+static int lgmp_randinit_lc_2exp(lua_State *L)
+{
+ gmp_randstate_t *res = lgmp_rawrand(L);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+ unsigned long arg3 = (unsigned long)lua_tonumber(L, 3);
+
+ gmp_randinit_lc_2exp(*res, *arg1, arg2, arg3);
+
+ return 1;
+}
+
+static int lgmp_randinit_lc_2exp_size(lua_State *L)
+{
+ gmp_randstate_t *res = lgmp_rawrand(L);
+ unsigned long arg = (unsigned long)lua_tonumber(L, 1);
+
+ lua_pushinteger(L, gmp_randinit_lc_2exp_size(*res, arg));
+
+ return 2;
+}
+
+static int lgmp_randinit_mt(lua_State *L)
+{
+ gmp_randstate_t *res = lgmp_rawrand(L);
+
+ gmp_randinit_mt(*res);
+
+ return 1;
+}
+
+static int lgmp_randinit_set(lua_State *L)
+{
+ gmp_randstate_t *res = lgmp_rawrand(L);
+ gmp_randstate_t *arg = lgmp_torand(L, 1);
+
+ gmp_randinit_set(*res, *arg);
+
+ return 1;
+}
+
+static int lgmp_randseed(lua_State *L)
+{
+ gmp_randstate_t *arg1 = lgmp_torand(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ gmp_randseed(*arg1, *arg2);
+
+ return 0;
+}
+
+static int lgmp_randseed_ui(lua_State *L)
+{
+ gmp_randstate_t *arg1 = lgmp_torand(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ gmp_randseed_ui(*arg1, arg2);
+
+ return 0;
+}
+
+static int lgmp_randclear(lua_State *L)
+{
+ gmp_randstate_t *arg = lgmp_torand(L, 1);
+
+ gmp_randclear(*arg);
+
+ return 0;
+}
+
+static int lmpz_abs(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 2, 2);
+ mpz_t *src = lgmp_toz(L, 1);
+
+ mpz_abs(*res, *src);
+
+ return 1;
+}
+
+static int lmpz_add(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_add(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_add_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_add_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_addmul(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+ mpz_t *arg3 = lgmp_toz(L, 3);
+
+ mpz_addmul(*arg1, *arg2, *arg3);
+
+ return 0;
+}
+
+static int lmpz_addmul_ui(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+ unsigned long arg3 = (unsigned long)lua_tonumber(L, 3);
+
+ mpz_addmul_ui(*arg1, *arg2, arg3);
+
+ return 0;
+}
+
+static int lmpz_and(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_and(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+#if 0
+#define mpz_array_init __gmpz_array_init
+__GMP_DECLSPEC void mpz_array_init __GMP_PROTO ((mpz_ptr, mp_size_t, mp_size_t));
+#endif
+
+static int lmpz_bin_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_bin_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_bin_uiui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ unsigned long arg1 = (unsigned long)lua_tonumber(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_bin_uiui(*res, arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_cdiv_q(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_cdiv_q(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_cdiv_q_2exp(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_cdiv_q_2exp(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_cdiv_q_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_cdiv_q_ui(*res, *arg1, arg2));
+
+ return 2;
+}
+
+static int lmpz_cdiv_qr(lua_State *L)
+{
+ mpz_t *resq = lgmp_optz(L, 3, 4);
+ mpz_t *resr = lgmp_optz(L, 4, 0);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_cdiv_qr(*resq, *resr, *arg1, *arg2);
+
+ return 2;
+}
+
+static int lmpz_cdiv_qr_ui(lua_State *L)
+{
+ mpz_t *resq = lgmp_optz(L, 3, 4);
+ mpz_t *resr = lgmp_optz(L, 4, 0);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_cdiv_qr_ui(*resq, *resr, *arg1, arg2));
+
+ return 3;
+}
+
+static int lmpz_cdiv_r(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_cdiv_r(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_cdiv_r_2exp(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_cdiv_r_2exp(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_cdiv_r_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_cdiv_r_ui(*res, *arg1, arg2));
+
+ return 2;
+}
+
+static int lmpz_cdiv_ui(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_cdiv_ui(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_clear(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ mpz_clear(*arg);
+
+ return 0;
+}
+
+static int lmpz_clrbit(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_clrbit(*arg1, arg2);
+
+ return 0;
+}
+
+static int lmpz_cmp(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ lua_pushinteger(L, mpz_cmp(*arg1, *arg2));
+
+ return 1;
+}
+
+static int lmpz_cmp_d(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ double arg2 = lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_cmp_d(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_cmp_si(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ signed long arg2 = (signed long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_cmp_si(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_cmp_ui(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_cmp_ui(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_cmpabs(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ lua_pushinteger(L, mpz_cmpabs(*arg1, *arg2));
+
+ return 1;
+}
+
+static int lmpz_cmpabs_d(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ double arg2 = lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_cmpabs_d(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_cmpabs_ui(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_cmpabs_ui(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_com(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 2, 2);
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ mpz_com(*res, *arg);
+
+ return 1;
+}
+
+static int lmpz_combit(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_combit(*arg1, arg2);
+
+ return 0;
+}
+
+static int lmpz_congruent_p(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+ mpz_t *arg3 = lgmp_toz(L, 3);
+
+ lua_pushinteger(L, mpz_congruent_p(*arg1, *arg2, *arg3));
+
+ return 1;
+}
+
+static int lmpz_congruent_2exp_p(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+ unsigned long arg3 = (unsigned long)lua_tonumber(L, 3);
+
+ lua_pushinteger(L, mpz_congruent_2exp_p(*arg1, *arg2, arg3));
+
+ return 1;
+}
+
+static int lmpz_congruent_ui_p(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+ unsigned long arg3 = (unsigned long)lua_tonumber(L, 3);
+
+ lua_pushinteger(L, mpz_congruent_ui_p(*arg1, arg2, arg3));
+
+ return 1;
+}
+
+static int lmpz_divexact(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_divexact(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_divexact_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_divexact_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_divisible_p(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ lua_pushinteger(L, mpz_divisible_p(*arg1, *arg2));
+
+ return 1;
+}
+
+static int lmpz_divisible_ui_p(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_divisible_ui_p(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_divisible_2exp_p(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_divisible_2exp_p(*arg1, arg2));
+
+ return 1;
+}
+
+#if 0
+#define mpz_dump __gmpz_dump
+__GMP_DECLSPEC void mpz_dump __GMP_PROTO ((mpz_srcptr));
+
+#define mpz_export __gmpz_export
+__GMP_DECLSPEC void *mpz_export __GMP_PROTO ((void *, size_t *, int, size_t, int, size_t, mpz_srcptr));
+#endif
+
+static int lmpz_fac_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 2, 2);
+ unsigned long arg = (unsigned long)lua_tonumber(L, 1);
+
+ mpz_fac_ui(*res, arg);
+
+ return 1;
+}
+
+static int lmpz_fdiv_q(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_fdiv_q(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_fdiv_q_2exp(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_fdiv_q_2exp(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_fdiv_q_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_fdiv_q_ui(*res, *arg1, arg2));
+
+ return 2;
+}
+
+static int lmpz_fdiv_qr(lua_State *L)
+{
+ mpz_t *resq = lgmp_optz(L, 3, 4);
+ mpz_t *resr = lgmp_optz(L, 4, 0);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_fdiv_qr(*resq, *resr, *arg1, *arg2);
+
+ return 2;
+}
+
+static int lmpz_fdiv_qr_ui(lua_State *L)
+{
+ mpz_t *resq = lgmp_optz(L, 3, 4);
+ mpz_t *resr = lgmp_optz(L, 4, 0);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_fdiv_qr_ui(*resq, *resr, *arg1, arg2));
+
+ return 3;
+}
+
+static int lmpz_fdiv_r(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_fdiv_r(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_fdiv_r_2exp(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_fdiv_r_2exp(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_fdiv_r_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_fdiv_r_ui(*res, *arg1, arg2));
+
+ return 2;
+}
+
+static int lmpz_fdiv_ui(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_fdiv_ui(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_fib_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 2, 2);
+ unsigned long arg = (unsigned long)lua_tonumber(L, 1);
+
+ mpz_fib_ui(*res, arg);
+
+ return 1;
+}
+
+static int lmpz_fib2_ui(lua_State *L)
+{
+ mpz_t *res1 = lgmp_optz(L, 2, 3);
+ mpz_t *res2 = lgmp_optz(L, 3, 0);
+ unsigned long arg = (unsigned long)lua_tonumber(L, 1);
+
+ mpz_fib2_ui(*res1, *res2, arg);
+
+ return 2;
+}
+
+static int lmpz_fits_sint_p(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushinteger(L, mpz_fits_sint_p(*arg));
+
+ return 1;
+}
+
+static int lmpz_fits_slong_p(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushinteger(L, mpz_fits_slong_p(*arg));
+
+ return 1;
+}
+
+static int lmpz_fits_sshort_p(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushinteger(L, mpz_fits_sshort_p(*arg));
+
+ return 1;
+}
+
+static int lmpz_fits_uint_p(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushinteger(L, mpz_fits_uint_p(*arg));
+
+ return 1;
+}
+
+static int lmpz_fits_ulong_p(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushinteger(L, mpz_fits_ulong_p(*arg));
+
+ return 1;
+}
+
+static int lmpz_fits_ushort_p(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushinteger(L, mpz_fits_ushort_p(*arg));
+
+ return 1;
+}
+
+static int lmpz_gcd(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_gcd(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_gcd_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_gcd_ui(*res, *arg1, arg2));
+
+ return 2;
+}
+
+static int lmpz_gcdext(lua_State *L)
+{
+ mpz_t *resg = lgmp_optz(L, 3, 5);
+ mpz_t *resp = lgmp_optz(L, 4, 0);
+ mpz_t *resq = lgmp_optz(L, 5, 0);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_gcdext(*resg, *resp, *resq, *arg1, *arg2);
+
+ return 3;
+}
+
+static int lmpz_get_d(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushnumber(L, mpz_get_d(*arg));
+
+ return 1;
+}
+
+static int lmpz_get_d_2exp(lua_State *L)
+{
+ signed long resexp;
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushnumber(L, mpz_get_d_2exp(&resexp, *arg));
+ lua_pushinteger(L, resexp);
+
+ return 2;
+}
+
+#if 0
+#define mpz_get_si __gmpz_get_si
+__GMP_DECLSPEC /* signed */ long int mpz_get_si __GMP_PROTO ((mpz_srcptr)) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+static int lmpz_get_str(lua_State *L)
+{
+ int arg1 = lua_tointeger(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ char *res = mpz_get_str(NULL, arg1, *arg2);
+ lua_pushstring(L, res);
+ lgmp_free_str(res);
+
+ return 1;
+}
+
+#if 0
+#define mpz_get_ui __gmpz_get_ui
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_get_ui)
+__GMP_DECLSPEC unsigned long int mpz_get_ui __GMP_PROTO ((mpz_srcptr)) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpz_getlimbn __gmpz_getlimbn
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_getlimbn)
+__GMP_DECLSPEC mp_limb_t mpz_getlimbn __GMP_PROTO ((mpz_srcptr, mp_size_t)) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+#endif
+
+static int lmpz_hamdist(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ lua_pushnumber(L, mpz_hamdist(*arg1, *arg2));
+
+ return 1;
+}
+
+#if 0
+#define mpz_import __gmpz_import
+__GMP_DECLSPEC void mpz_import __GMP_PROTO ((mpz_ptr, size_t, int, size_t, int, size_t, __gmp_const void *));
+#endif
+
+static int lmpz_init(lua_State *L)
+{
+ mpz_t *res = lgmp_rawz(L);
+ mpz_init(*res);
+
+ return 1;
+}
+
+#if 0
+#define mpz_init2 __gmpz_init2
+__GMP_DECLSPEC void mpz_init2 __GMP_PROTO ((mpz_ptr, unsigned long));
+#endif
+
+static int lmpz_init_set(lua_State *L)
+{
+ mpz_t *res = lgmp_rawz(L);
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ mpz_init_set(*res, *arg);
+
+ return 1;
+}
+
+static int lmpz_init_set_d(lua_State *L)
+{
+ mpz_t *res = lgmp_rawz(L);
+ double arg = lua_tonumber(L, 1);
+
+ mpz_init_set_d(*res, arg);
+
+ return 1;
+}
+
+#if 0
+#define mpz_init_set_si __gmpz_init_set_si
+__GMP_DECLSPEC void mpz_init_set_si __GMP_PROTO ((mpz_ptr, signed long int));
+#endif
+
+static int lmpz_init_set_str(lua_State *L)
+{
+ mpz_t *res = lgmp_rawz(L);
+ const char *arg1 = lua_tostring(L, 1);
+ int arg2 = lua_tointeger(L, 2);
+
+ if (mpz_init_set_str(*res, arg1, arg2) != 0)
+ lua_pushnil(L);
+
+ return 1;
+}
+
+#if 0
+#define mpz_init_set_ui __gmpz_init_set_ui
+__GMP_DECLSPEC void mpz_init_set_ui __GMP_PROTO ((mpz_ptr, unsigned long int));
+
+#define mpz_inp_raw __gmpz_inp_raw
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpz_inp_raw __GMP_PROTO ((mpz_ptr, FILE *));
+#endif
+
+#define mpz_inp_str __gmpz_inp_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpz_inp_str __GMP_PROTO ((mpz_ptr, FILE *, int));
+#endif
+#endif
+
+static int lmpz_invert(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ lua_pushinteger(L, mpz_invert(*res, *arg1, *arg2));
+
+ return 2;
+}
+
+static int lmpz_ior(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_ior(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_kronecker(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ lua_pushinteger(L, mpz_kronecker(*arg1, *arg2));
+
+ return 1;
+}
+
+static int lmpz_kronecker_si(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ long arg2 = (long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_kronecker_si(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_kronecker_ui(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_kronecker_ui(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_si_kronecker(lua_State *L)
+{
+ long arg1 = (long)lua_tonumber(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ lua_pushinteger(L, mpz_si_kronecker(arg1, *arg2));
+
+ return 1;
+}
+
+static int lmpz_ui_kronecker(lua_State *L)
+{
+ unsigned long arg1 = (unsigned long)lua_tonumber(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ lua_pushinteger(L, mpz_ui_kronecker(arg1, *arg2));
+
+ return 1;
+}
+
+static int lmpz_lcm(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_lcm(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_lcm_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_lcm_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_lucnum_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 2, 2);
+ unsigned long arg = (unsigned long)lua_tonumber(L, 1);
+
+ mpz_lucnum_ui(*res, arg);
+
+ return 1;
+}
+
+static int lmpz_lucnum2_ui(lua_State *L)
+{
+ mpz_t *res1 = lgmp_optz(L, 2, 3);
+ mpz_t *res2 = lgmp_optz(L, 3, 0);
+ unsigned long arg = (unsigned long)lua_tonumber(L, 1);
+
+ mpz_lucnum2_ui(*res1, *res2, arg);
+
+ return 2;
+}
+
+static int lmpz_millerrabin(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ int arg2 = lua_tointeger(L, 2);
+
+ lua_pushinteger(L, mpz_millerrabin(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_mod(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_mod(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+#if 0
+#define mpz_mod_ui mpz_fdiv_r_ui /* same as fdiv_r because divisor unsigned */
+#endif
+
+static int lmpz_mul(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_mul(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_mul_2exp(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_mul_2exp(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_mul_si(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ long arg2 = (long)lua_tonumber(L, 2);
+
+ mpz_mul_si(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_mul_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_mul_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_neg(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 2, 2);
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ mpz_neg(*res, *arg);
+
+ return 1;
+}
+
+static int lmpz_nextprime(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 2, 2);
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ mpz_nextprime(*res, *arg);
+
+ return 1;
+}
+
+#if 0
+#define mpz_out_raw __gmpz_out_raw
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpz_out_raw __GMP_PROTO ((FILE *, mpz_srcptr));
+#endif
+
+#define mpz_out_str __gmpz_out_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpz_out_str __GMP_PROTO ((FILE *, int, mpz_srcptr));
+#endif
+#endif
+
+static int lmpz_perfect_power_p(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushinteger(L, mpz_perfect_power_p(*arg));
+
+ return 1;
+}
+
+static int lmpz_perfect_square_p(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushinteger(L, mpz_perfect_square_p(*arg));
+
+ return 1;
+}
+
+static int lmpz_popcount(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushnumber(L, mpz_popcount(*arg));
+
+ return 1;
+}
+
+static int lmpz_pow_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_pow_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_powm(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 4, 4);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+ mpz_t *arg3 = lgmp_toz(L, 3);
+
+ mpz_powm(*res, *arg1, *arg2, *arg3);
+
+ return 1;
+}
+
+static int lmpz_powm_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 4, 4);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+ mpz_t *arg3 = lgmp_toz(L, 3);
+
+ mpz_powm_ui(*res, *arg1, arg2, *arg3);
+
+ return 1;
+}
+
+static int lmpz_probab_prime_p(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ int arg2 = lua_tointeger(L, 2);
+
+ lua_pushinteger(L, mpz_probab_prime_p(*arg1, arg2));
+
+ return 1;
+}
+
+#if 0
+#define mpz_random __gmpz_random
+__GMP_DECLSPEC void mpz_random __GMP_PROTO ((mpz_ptr, mp_size_t));
+
+#define mpz_random2 __gmpz_random2
+__GMP_DECLSPEC void mpz_random2 __GMP_PROTO ((mpz_ptr, mp_size_t));
+
+#define mpz_realloc2 __gmpz_realloc2
+__GMP_DECLSPEC void mpz_realloc2 __GMP_PROTO ((mpz_ptr, unsigned long));
+#endif
+
+static int lmpz_remove(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_remove(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_root(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_root(*res, *arg1, arg2));
+
+ return 2;
+}
+
+static int lmpz_rootrem(lua_State *L)
+{
+ mpz_t *resro = lgmp_optz(L, 3, 4);
+ mpz_t *resre = lgmp_optz(L, 4, 0);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_rootrem(*resro, *resre, *arg1, arg2);
+
+ return 2;
+}
+
+static int lmpz_rrandomb(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ gmp_randstate_t *arg1 = lgmp_torand(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_rrandomb(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_scan0(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_scan0(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_scan1(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_scan1(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_set(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_set(*arg1, *arg2);
+
+ return 0;
+}
+
+static int lmpz_set_d(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ double arg2 = lua_tonumber(L, 2);
+
+ mpz_set_d(*arg1, arg2);
+
+ return 0;
+}
+
+static int lmpz_set_f(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ mpz_set_f(*arg1, *arg2);
+
+ return 0;
+}
+
+#if 0
+#define mpz_set_q __gmpz_set_q
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_set_q)
+__GMP_DECLSPEC void mpz_set_q __GMP_PROTO ((mpz_ptr, mpq_srcptr));
+#endif
+
+#define mpz_set_si __gmpz_set_si
+__GMP_DECLSPEC void mpz_set_si __GMP_PROTO ((mpz_ptr, signed long int));
+#endif
+
+static int lmpz_set_str(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ const char *arg2 = lua_tostring(L, 2);
+ int arg3 = lua_tointeger(L, 3);
+
+ lua_pushinteger(L, mpz_set_str(*arg1, arg2, arg3));
+
+ return 1;
+}
+
+#if 0
+#define mpz_set_ui __gmpz_set_ui
+__GMP_DECLSPEC void mpz_set_ui __GMP_PROTO ((mpz_ptr, unsigned long int));
+#endif
+
+static int lmpz_setbit(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_setbit(*arg1, arg2);
+
+ return 0;
+}
+
+static int lmpz_sgn(lua_State *L)
+{
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ lua_pushinteger(L, mpz_sgn(*arg));
+
+ return 1;
+}
+
+#if 0
+#define mpz_size __gmpz_size
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_size)
+__GMP_DECLSPEC size_t mpz_size __GMP_PROTO ((mpz_srcptr)) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+#endif
+
+static int lmpz_sizeinbase(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ int arg2 = lua_tointeger(L, 2);
+
+ lua_pushinteger(L, mpz_sizeinbase(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_sqrt(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 2, 2);
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ mpz_sqrt(*res, *arg);
+
+ return 1;
+}
+
+static int lmpz_sqrtrem(lua_State *L)
+{
+ mpz_t *ress = lgmp_optz(L, 2, 3);
+ mpz_t *resr = lgmp_optz(L, 3, 0);
+ mpz_t *arg = lgmp_toz(L, 1);
+
+ mpz_sqrtrem(*ress, *resr, *arg);
+
+ return 2;
+}
+
+static int lmpz_sub(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_sub(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_sub_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_sub_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_ui_sub(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ unsigned long arg1 = (unsigned long)lua_tonumber(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_ui_sub(*res, arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_submul(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+ mpz_t *arg3 = lgmp_toz(L, 3);
+
+ mpz_submul(*arg1, *arg2, *arg3);
+
+ return 0;
+}
+
+static int lmpz_submul_ui(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+ unsigned long arg3 = (unsigned long)lua_tonumber(L, 3);
+
+ mpz_submul_ui(*arg1, *arg2, arg3);
+
+ return 0;
+}
+
+#if 0
+#define mpz_swap __gmpz_swap
+__GMP_DECLSPEC void mpz_swap __GMP_PROTO ((mpz_ptr, mpz_ptr)) __GMP_NOTHROW;
+#endif
+
+static int lmpz_tdiv_q(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_tdiv_q(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_tdiv_q_2exp(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_tdiv_q_2exp(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_tdiv_q_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_tdiv_q_ui(*res, *arg1, arg2));
+
+ return 2;
+}
+
+static int lmpz_tdiv_qr(lua_State *L)
+{
+ mpz_t *resq = lgmp_optz(L, 3, 4);
+ mpz_t *resr = lgmp_optz(L, 4, 0);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_tdiv_qr(*resq, *resr, *arg1, *arg2);
+
+ return 2;
+}
+
+static int lmpz_tdiv_qr_ui(lua_State *L)
+{
+ mpz_t *resq = lgmp_optz(L, 3, 4);
+ mpz_t *resr = lgmp_optz(L, 4, 0);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_tdiv_qr_ui(*resq, *resr, *arg1, arg2));
+
+ return 3;
+}
+
+static int lmpz_tdiv_r(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_tdiv_r(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_tdiv_r_2exp(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_tdiv_r_2exp(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_tdiv_r_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_tdiv_r_ui(*res, *arg1, arg2));
+
+ return 2;
+}
+
+static int lmpz_tdiv_ui(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushnumber(L, mpz_tdiv_ui(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_tstbit(lua_State *L)
+{
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpz_tstbit(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpz_ui_pow_ui(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ unsigned long arg1 = (unsigned long)lua_tonumber(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_ui_pow_ui(*res, arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_urandomb(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ gmp_randstate_t *arg1 = lgmp_torand(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpz_urandomb(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpz_urandomm(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ gmp_randstate_t *arg1 = lgmp_torand(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_urandomm(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpz_xor(lua_State *L)
+{
+ mpz_t *res = lgmp_optz(L, 3, 3);
+ mpz_t *arg1 = lgmp_toz(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpz_xor(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpf_abs(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 2, 2);
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ mpf_abs(*res, *arg);
+
+ return 1;
+}
+
+static int lmpf_add(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ mpf_add(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpf_add_ui(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpf_add_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpf_ceil(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 2, 2);
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ mpf_ceil(*res, *arg);
+
+ return 1;
+}
+
+static int lmpf_clear(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ mpf_clear(*arg);
+
+ return 0;
+}
+
+static int lmpf_cmp(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ lua_pushinteger(L, mpf_cmp(*arg1, *arg2));
+
+ return 1;
+}
+
+static int lmpf_cmp_d(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ double arg2 = lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpf_cmp_d(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpf_cmp_si(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ signed long arg2 = (signed long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpf_cmp_si(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpf_cmp_ui(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ lua_pushinteger(L, mpf_cmp_ui(*arg1, arg2));
+
+ return 1;
+}
+
+static int lmpf_div(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ mpf_div(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpf_div_2exp(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpf_div_2exp(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpf_div_ui(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpf_div_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+#if 0
+#define mpf_dump __gmpf_dump
+__GMP_DECLSPEC void mpf_dump __GMP_PROTO ((mpf_srcptr));
+#endif
+
+static int lmpf_eq(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+ unsigned long arg3 = (unsigned long)lua_tonumber(L, 3);
+
+ lua_pushinteger(L, mpf_eq(*arg1, *arg2, arg3));
+
+ return 1;
+}
+
+static int lmpf_fits_sint_p(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushinteger(L, mpf_fits_sint_p(*arg));
+
+ return 1;
+}
+
+static int lmpf_fits_slong_p(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushinteger(L, mpf_fits_slong_p(*arg));
+
+ return 1;
+}
+
+static int lmpf_fits_sshort_p(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushinteger(L, mpf_fits_sshort_p(*arg));
+
+ return 1;
+}
+
+static int lmpf_fits_uint_p(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushinteger(L, mpf_fits_uint_p(*arg));
+
+ return 1;
+}
+
+static int lmpf_fits_ulong_p(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushinteger(L, mpf_fits_ulong_p(*arg));
+
+ return 1;
+}
+
+static int lmpf_fits_ushort_p(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushinteger(L, mpf_fits_ushort_p(*arg));
+
+ return 1;
+}
+
+static int lmpf_floor(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 2, 2);
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ mpf_floor(*res, *arg);
+
+ return 1;
+}
+
+static int lmpf_get_d(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushnumber(L, mpf_get_d(*arg));
+
+ return 1;
+}
+
+static int lmpf_get_d_2exp(lua_State *L)
+{
+ signed long exp;
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushnumber(L, mpf_get_d_2exp(&exp, *arg));
+ lua_pushnumber(L, exp);
+
+ return 2;
+}
+
+static int lmpf_get_default_prec(lua_State *L)
+{
+ lua_pushnumber(L, mpf_get_default_prec());
+
+ return 1;
+}
+
+static int lmpf_get_prec(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushnumber(L, mpf_get_prec(*arg));
+
+ return 1;
+}
+
+#if 0
+#define mpf_get_si __gmpf_get_si
+__GMP_DECLSPEC long mpf_get_si __GMP_PROTO ((mpf_srcptr)) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+static int lmpf_get_str(lua_State *L)
+{
+ mp_exp_t exp;
+ int arg1 = lua_tointeger(L, 1);
+ size_t arg2 = lua_tointeger(L, 2);
+ mpf_t *arg3 = lgmp_tof(L, 3);
+
+ char *res = mpf_get_str(NULL, &exp, arg1, arg2, *arg3);
+ lua_pushstring(L, res);
+ lua_pushnumber(L, exp);
+ lgmp_free_str(res);
+
+ return 2;
+}
+
+#if 0
+#define mpf_get_ui __gmpf_get_ui
+__GMP_DECLSPEC unsigned long mpf_get_ui __GMP_PROTO ((mpf_srcptr)) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+static int lmpf_init(lua_State *L)
+{
+ mpf_t *res = lgmp_rawf(L);
+
+ mpf_init(*res);
+
+ return 1;
+}
+
+#if 0
+#define mpf_init2 __gmpf_init2
+__GMP_DECLSPEC void mpf_init2 __GMP_PROTO ((mpf_ptr, unsigned long int));
+#endif
+
+static int lmpf_init_set(lua_State *L)
+{
+ mpf_t *res = lgmp_rawf(L);
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ mpf_init_set(*res, *arg);
+
+ return 1;
+}
+
+static int lmpf_init_set_d(lua_State *L)
+{
+ mpf_t *res = lgmp_rawf(L);
+ double arg = lua_tonumber(L, 1);
+
+ mpf_init_set_d(*res, arg);
+
+ return 1;
+}
+
+#if 0
+#define mpf_init_set_si __gmpf_init_set_si
+__GMP_DECLSPEC void mpf_init_set_si __GMP_PROTO ((mpf_ptr, signed long int));
+#endif
+
+static int lmpf_init_set_str(lua_State *L)
+{
+ mpf_t *res = lgmp_rawf(L);
+ const char *arg1 = lua_tostring(L, 1);
+ int arg2 = lua_tonumber(L, 2);
+
+ if (mpf_init_set_str(*res, arg1, arg2) != 0)
+ {
+ lua_pushnil(L);
+ lua_replace(L, -2);
+ }
+
+ return 1;
+}
+
+#if 0
+#define mpf_init_set_ui __gmpf_init_set_ui
+__GMP_DECLSPEC void mpf_init_set_ui __GMP_PROTO ((mpf_ptr, unsigned long int));
+
+#define mpf_inp_str __gmpf_inp_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpf_inp_str __GMP_PROTO ((mpf_ptr, FILE *, int));
+#endif
+#endif
+
+static int lmpf_integer_p(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushinteger(L, mpf_integer_p(*arg));
+
+ return 1;
+}
+
+static int lmpf_mul(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ mpf_mul(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpf_mul_2exp(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpf_mul_2exp(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpf_mul_ui(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpf_mul_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpf_neg(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 2, 2);
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ mpf_neg(*res, *arg);
+
+ return 1;
+}
+
+#if 0
+#define mpf_out_str __gmpf_out_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpf_out_str __GMP_PROTO ((FILE *, int, size_t, mpf_srcptr));
+#endif
+#endif
+
+static int lmpf_pow_ui(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpf_pow_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static int lmpf_random2(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mp_size_t arg1 = (mp_size_t)lua_tonumber(L, 1);
+ mp_exp_t arg2 = (mp_exp_t)lua_tonumber(L, 2);
+
+ mpf_random2(*res, arg1, arg2);
+
+ return 1;
+}
+
+static int lmpf_reldiff(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ mpf_reldiff(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpf_set(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ mpf_set(*arg1, *arg2);
+
+ return 0;
+}
+
+static int lmpf_set_d(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ double arg2 = lua_tonumber(L, 2);
+
+ mpf_set_d(*arg1, arg2);
+
+ return 0;
+}
+
+static int lmpf_set_default_prec(lua_State *L)
+{
+ unsigned int arg = (unsigned int)lua_tonumber(L, 1);
+
+ mpf_set_default_prec(arg);
+
+ return 0;
+}
+
+static int lmpf_set_prec(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpf_set_prec(*arg1, arg2);
+
+ return 0;
+}
+
+#if 0
+#define mpf_set_prec_raw __gmpf_set_prec_raw
+__GMP_DECLSPEC void mpf_set_prec_raw __GMP_PROTO ((mpf_ptr, unsigned long int)) __GMP_NOTHROW;
+
+#define mpf_set_q __gmpf_set_q
+__GMP_DECLSPEC void mpf_set_q __GMP_PROTO ((mpf_ptr, mpq_srcptr));
+
+#define mpf_set_si __gmpf_set_si
+__GMP_DECLSPEC void mpf_set_si __GMP_PROTO ((mpf_ptr, signed long int));
+#endif
+
+static int lmpf_set_str(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ const char *arg2 = lua_tostring(L, 2);
+ int arg3 = lua_tointeger(L, 3);
+
+ lua_pushinteger(L, mpf_set_str(*arg1, arg2, arg3));
+
+ return 1;
+}
+
+#if 0
+#define mpf_set_ui __gmpf_set_ui
+__GMP_DECLSPEC void mpf_set_ui __GMP_PROTO ((mpf_ptr, unsigned long int));
+#endif
+
+static int lmpf_set_z(lua_State *L)
+{
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ mpz_t *arg2 = lgmp_toz(L, 2);
+
+ mpf_set_z(*arg1, *arg2);
+
+ return 0;
+}
+
+static int lmpf_sgn(lua_State *L)
+{
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ lua_pushinteger(L, mpf_sgn(*arg));
+
+ return 1;
+}
+
+#if 0
+#define mpf_size __gmpf_size
+__GMP_DECLSPEC size_t mpf_size __GMP_PROTO ((mpf_srcptr)) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+static int lmpf_sqrt(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 2, 2);
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ mpf_sqrt(*res, *arg);
+
+ return 1;
+}
+
+static int lmpf_sqrt_ui(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 2, 2);
+ unsigned int arg = (unsigned int)lua_tonumber(L, 1);
+
+ mpf_sqrt_ui(*res, arg);
+
+ return 1;
+}
+
+static int lmpf_sub(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ mpf_sub(*res, *arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpf_sub_ui(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ mpf_t *arg1 = lgmp_tof(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpf_sub_ui(*res, *arg1, arg2);
+
+ return 1;
+}
+
+#if 0
+#define mpf_swap __gmpf_swap
+__GMP_DECLSPEC void mpf_swap __GMP_PROTO ((mpf_ptr, mpf_ptr)) __GMP_NOTHROW;
+#endif
+
+static int lmpf_trunc(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 2, 2);
+ mpf_t *arg = lgmp_tof(L, 1);
+
+ mpf_trunc(*res, *arg);
+
+ return 1;
+}
+
+static int lmpf_ui_div(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ unsigned long arg1 = (unsigned long)lua_tonumber(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ mpf_ui_div(*res, arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpf_ui_sub(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ unsigned long arg1 = (unsigned long)lua_tonumber(L, 1);
+ mpf_t *arg2 = lgmp_tof(L, 2);
+
+ mpf_ui_sub(*res, arg1, *arg2);
+
+ return 1;
+}
+
+static int lmpf_urandomb(lua_State *L)
+{
+ mpf_t *res = lgmp_optf(L, 3, 3);
+ gmp_randstate_t *arg1 = lgmp_torand(L, 1);
+ unsigned long arg2 = (unsigned long)lua_tonumber(L, 2);
+
+ mpf_urandomb(*res, *arg1, arg2);
+
+ return 1;
+}
+
+static const luaL_Reg lgmp_prv[] =
+{
+ {"gmp_randinit_default", lgmp_randinit_default},
+ {"gmp_randinit_lc_2exp", lgmp_randinit_lc_2exp},
+ {"gmp_randinit_lc_2exp_size", lgmp_randinit_lc_2exp_size},
+ {"gmp_randinit_mt", lgmp_randinit_mt},
+ {"gmp_randinit_set", lgmp_randinit_set},
+ {"gmp_randseed", lgmp_randseed},
+ {"gmp_randseed_ui", lgmp_randseed_ui},
+ {"gmp_randclear", lgmp_randclear},
+ {"mpz_abs", lmpz_abs},
+ {"mpz_add", lmpz_add},
+ {"mpz_add_ui", lmpz_add_ui},
+ {"mpz_addmul", lmpz_addmul},
+ {"mpz_addmul_ui", lmpz_addmul_ui},
+ {"mpz_and", lmpz_and},
+ {"mpz_asprintf", lmpz_asprintf},
+ {"mpz_bin_ui", lmpz_bin_ui},
+ {"mpz_bin_uiui", lmpz_bin_uiui},
+ {"mpz_cdiv_q", lmpz_cdiv_q},
+ {"mpz_cdiv_q_2exp", lmpz_cdiv_q_2exp},
+ {"mpz_cdiv_q_ui", lmpz_cdiv_q_ui},
+ {"mpz_cdiv_qr", lmpz_cdiv_qr},
+ {"mpz_cdiv_qr_ui", lmpz_cdiv_qr_ui},
+ {"mpz_cdiv_r", lmpz_cdiv_r},
+ {"mpz_cdiv_r_2exp", lmpz_cdiv_r_2exp},
+ {"mpz_cdiv_r_ui", lmpz_cdiv_r_ui},
+ {"mpz_cdiv_ui", lmpz_cdiv_ui},
+ {"mpz_clear", lmpz_clear},
+ {"mpz_clrbit", lmpz_clrbit},
+ {"mpz_cmp", lmpz_cmp},
+ {"mpz_cmp_d", lmpz_cmp_d},
+ {"mpz_cmp_si", lmpz_cmp_si},
+ {"mpz_cmp_ui", lmpz_cmp_ui},
+ {"mpz_cmpabs", lmpz_cmpabs},
+ {"mpz_cmpabs_d", lmpz_cmpabs_d},
+ {"mpz_cmpabs_ui", lmpz_cmpabs_ui},
+ {"mpz_com", lmpz_com},
+ {"mpz_combit", lmpz_combit},
+ {"mpz_congruent_p", lmpz_congruent_p},
+ {"mpz_congruent_2exp_p", lmpz_congruent_2exp_p},
+ {"mpz_congruent_ui_p", lmpz_congruent_ui_p},
+ {"mpz_divexact", lmpz_divexact},
+ {"mpz_divexact_ui", lmpz_divexact_ui},
+ {"mpz_divisible_p", lmpz_divisible_p},
+ {"mpz_divisible_ui_p", lmpz_divisible_ui_p},
+ {"mpz_divisible_2exp_p", lmpz_divisible_2exp_p},
+ {"mpz_fac_ui", lmpz_fac_ui},
+ {"mpz_fdiv_q", lmpz_fdiv_q},
+ {"mpz_fdiv_q_2exp", lmpz_fdiv_q_2exp},
+ {"mpz_fdiv_q_ui", lmpz_fdiv_q_ui},
+ {"mpz_fdiv_qr", lmpz_fdiv_qr},
+ {"mpz_fdiv_qr_ui", lmpz_fdiv_qr_ui},
+ {"mpz_fdiv_r", lmpz_fdiv_r},
+ {"mpz_fdiv_r_2exp", lmpz_fdiv_r_2exp},
+ {"mpz_fdiv_r_ui", lmpz_fdiv_r_ui},
+ {"mpz_fdiv_ui", lmpz_fdiv_ui},
+ {"mpz_fib_ui", lmpz_fib_ui},
+ {"mpz_fib2_ui", lmpz_fib2_ui},
+ {"mpz_fits_sint_p", lmpz_fits_sint_p},
+ {"mpz_fits_slong_p", lmpz_fits_slong_p},
+ {"mpz_fits_sshort_p", lmpz_fits_sshort_p},
+ {"mpz_fits_uint_p", lmpz_fits_uint_p},
+ {"mpz_fits_ulong_p", lmpz_fits_ulong_p},
+ {"mpz_fits_ushort_p", lmpz_fits_ushort_p},
+ {"mpz_gcd", lmpz_gcd},
+ {"mpz_gcd_ui", lmpz_gcd_ui},
+ {"mpz_gcdext", lmpz_gcdext},
+ {"mpz_get_d", lmpz_get_d},
+ {"mpz_get_d_2exp", lmpz_get_d_2exp},
+ {"mpz_get_str", lmpz_get_str},
+ {"mpz_hamdist", lmpz_hamdist},
+ {"mpz_init", lmpz_init},
+ {"mpz_init_set", lmpz_init_set},
+ {"mpz_init_set_d", lmpz_init_set_d},
+ {"mpz_init_set_str", lmpz_init_set_str},
+ {"mpz_invert", lmpz_invert},
+ {"mpz_ior", lmpz_ior},
+ {"mpz_kronecker", lmpz_kronecker},
+ {"mpz_kronecker_si", lmpz_kronecker_si},
+ {"mpz_kronecker_ui", lmpz_kronecker_ui},
+ {"mpz_si_kronecker", lmpz_si_kronecker},
+ {"mpz_ui_kronecker", lmpz_ui_kronecker},
+ {"mpz_lcm", lmpz_lcm},
+ {"mpz_lcm_ui", lmpz_lcm_ui},
+ {"mpz_lucnum_ui", lmpz_lucnum_ui},
+ {"mpz_lucnum2_ui", lmpz_lucnum2_ui},
+ {"mpz_millerrabin", lmpz_millerrabin},
+ {"mpz_mod", lmpz_mod},
+ {"mpz_mul", lmpz_mul},
+ {"mpz_mul_2exp", lmpz_mul_2exp},
+ {"mpz_mul_si", lmpz_mul_si},
+ {"mpz_mul_ui", lmpz_mul_ui},
+ {"mpz_neg", lmpz_neg},
+ {"mpz_nextprime", lmpz_nextprime},
+ {"mpz_perfect_power_p", lmpz_perfect_power_p},
+ {"mpz_perfect_square_p", lmpz_perfect_square_p},
+ {"mpz_popcount", lmpz_popcount},
+ {"mpz_pow_ui", lmpz_pow_ui},
+ {"mpz_powm", lmpz_powm},
+ {"mpz_powm_ui", lmpz_powm_ui},
+ {"mpz_probab_prime_p", lmpz_probab_prime_p},
+ {"mpz_remove", lmpz_remove},
+ {"mpz_root", lmpz_root},
+ {"mpz_rootrem", lmpz_rootrem},
+ {"mpz_rrandomb", lmpz_rrandomb},
+ {"mpz_scan0", lmpz_scan0},
+ {"mpz_scan1", lmpz_scan1},
+ {"mpz_set", lmpz_set},
+ {"mpz_set_d", lmpz_set_d},
+ {"mpz_set_f", lmpz_set_f},
+ {"mpz_set_str", lmpz_set_str},
+ {"mpz_setbit", lmpz_setbit},
+ {"mpz_sgn", lmpz_sgn},
+ {"mpz_sizeinbase", lmpz_sizeinbase},
+ {"mpz_sqrt", lmpz_sqrt},
+ {"mpz_sqrtrem", lmpz_sqrtrem},
+ {"mpz_sub", lmpz_sub},
+ {"mpz_sub_ui", lmpz_sub_ui},
+ {"mpz_ui_sub", lmpz_ui_sub},
+ {"mpz_submul", lmpz_submul},
+ {"mpz_submul_ui", lmpz_submul_ui},
+ {"mpz_tdiv_q", lmpz_tdiv_q},
+ {"mpz_tdiv_q_2exp", lmpz_tdiv_q_2exp},
+ {"mpz_tdiv_q_ui", lmpz_tdiv_q_ui},
+ {"mpz_tdiv_qr", lmpz_tdiv_qr},
+ {"mpz_tdiv_qr_ui", lmpz_tdiv_qr_ui},
+ {"mpz_tdiv_r", lmpz_tdiv_r},
+ {"mpz_tdiv_r_2exp", lmpz_tdiv_r_2exp},
+ {"mpz_tdiv_r_ui", lmpz_tdiv_r_ui},
+ {"mpz_tdiv_ui", lmpz_tdiv_ui},
+ {"mpz_tstbit", lmpz_tstbit},
+ {"mpz_ui_pow_ui", lmpz_ui_pow_ui},
+ {"mpz_urandomb", lmpz_urandomb},
+ {"mpz_urandomm", lmpz_urandomm},
+ {"mpz_xor", lmpz_xor},
+ {"mpf_abs", lmpf_abs},
+ {"mpf_add", lmpf_add},
+ {"mpf_add_ui", lmpf_add_ui},
+ {"mpf_asprintf", lmpf_asprintf},
+ {"mpf_ceil", lmpf_ceil},
+ {"mpf_clear", lmpf_clear},
+ {"mpf_cmp", lmpf_cmp},
+ {"mpf_cmp_d", lmpf_cmp_d},
+ {"mpf_cmp_si", lmpf_cmp_si},
+ {"mpf_cmp_ui", lmpf_cmp_ui},
+ {"mpf_div", lmpf_div},
+ {"mpf_div_2exp", lmpf_div_2exp},
+ {"mpf_div_ui", lmpf_div_ui},
+ {"mpf_eq", lmpf_eq},
+ {"mpf_fits_sint_p", lmpf_fits_sint_p},
+ {"mpf_fits_slong_p", lmpf_fits_slong_p},
+ {"mpf_fits_sshort_p", lmpf_fits_sshort_p},
+ {"mpf_fits_uint_p", lmpf_fits_uint_p},
+ {"mpf_fits_ulong_p", lmpf_fits_ulong_p},
+ {"mpf_fits_ushort_p", lmpf_fits_ushort_p},
+ {"mpf_floor", lmpf_floor},
+ {"mpf_get_d", lmpf_get_d},
+ {"mpf_get_d_2exp", lmpf_get_d_2exp},
+ {"mpf_get_default_prec", lmpf_get_default_prec},
+ {"mpf_get_prec", lmpf_get_prec},
+ {"mpf_get_str", lmpf_get_str},
+ {"mpf_init", lmpf_init},
+ {"mpf_init_set", lmpf_init_set},
+ {"mpf_init_set_d", lmpf_init_set_d},
+ {"mpf_init_set_str", lmpf_init_set_str},
+ {"mpf_integer_p", lmpf_integer_p},
+ {"mpf_mul", lmpf_mul},
+ {"mpf_mul_2exp", lmpf_mul_2exp},
+ {"mpf_mul_ui", lmpf_mul_ui},
+ {"mpf_neg", lmpf_neg},
+ {"mpf_pow_ui", lmpf_pow_ui},
+ {"mpf_random2", lmpf_random2},
+ {"mpf_reldiff", lmpf_reldiff},
+ {"mpf_set", lmpf_set},
+ {"mpf_set_d", lmpf_set_d},
+ {"mpf_set_default_prec", lmpf_set_default_prec},
+ {"mpf_set_prec", lmpf_set_prec},
+ {"mpf_set_str", lmpf_set_str},
+ {"mpf_set_z", lmpf_set_z},
+ {"mpf_sgn", lmpf_sgn},
+ {"mpf_sqrt", lmpf_sqrt},
+ {"mpf_sqrt_ui", lmpf_sqrt_ui},
+ {"mpf_sub", lmpf_sub},
+ {"mpf_sub_ui", lmpf_sub_ui},
+ {"mpf_trunc", lmpf_trunc},
+ {"mpf_ui_div", lmpf_ui_div},
+ {"mpf_ui_sub", lmpf_ui_sub},
+ {"mpf_urandomb", lmpf_urandomb},
+ {NULL, NULL}
+};
+
+static int lgmp_initialize(lua_State *L)
+{
+ lua_pushnumber(L, ULONG_MAX);
+ lua_setfield(L, 1, "ULONG_MAX");
+
+ lua_pushnumber(L, LONG_MIN);
+ lua_setfield(L, 1, "LONG_MIN");
+
+ lua_pushnumber(L, LONG_MAX);
+ lua_setfield(L, 1, "LONG_MAX");
+
+ lua_pushstring(L, gmp_version);
+ lua_setfield(L, 1, "version");
+
+ lua_pushvalue(L, 2);
+ lua_replace(L, LUA_ENVIRONINDEX);
+
+ lua_pushvalue(L, 1);
+ luaL_register(L, NULL, lgmp_prv);
+
+ return 0;
+}
+
+extern "C" {
+extern unsigned int size_lgmplib;
+extern unsigned char lgmplib[];
+}
+
+static int _init_plugin(Lua *L)
+{
+ L->newtable(); // [1] = prv
+ L->newtable(); // [2] = aux
+ L->wrap_open(lgmp_initialize);
+
+ Buffer lgmplib_buff;
+ lgmplib_buff.write(lgmplib, size_lgmplib);
+ L->load(&lgmplib_buff);
+
+ L->call("lgmp_lua_init", LUA_GLOBALSINDEX, 2, 0);
+
+ return 0;
+}
+
+extern "C" {
+
+#ifndef NO_DLL
+WEAK void init_plugin(Lua * L) {
+ _init_plugin(L);
+}
+#endif
+
+void luagmp_init(Lua * L) {
+ _init_plugin(L);
+}
+
+}
+