This class provides big integers.
The API follows the following guidelines:
- If it is known, that at least one operand is a
mpz
, then the operators (metamethods) can be used.
exception: For the comparison operators both operands must bempz
's. - If it is possible, that both/all operands can be Lua integers, then the functions from the
mpz
table must be used. - (As of January 2023 operator-like member methods of each
mpz
are reserved for compound assignments like+=
,<<=
.)
Because as of January 2023 no method/functions change a mpz
in-place,
all mpz
's can be considered as immutable.
(Do not forget to prefix each declaration or first assignment of a variable with local
,
if you do not need a variable that can be accessed from everywhere.)
local mpz = require("lomp-mpz")
my_mpz = mpz.new(lua_int)
my_mpz = mpz.new(other_mpz) -- copy constructor, equals mpz.copy(mpz_or_lua_int)
my_lua_int = my_mpz:to_lua_int()
my_lua_int = mpz.to_lua_int(mpz_or_lua_int)
- only returns a Lua integer if
my_mpz
is<= math.maxinteger
and>= math.mininteger
else an exception is raised and returnsnil
.
Only works when both operands are mpz
's !
my_mpz_a < my_mpz_b
my_mpz_a <= my_mpz_b
my_mpz_a == my_mpz_b
my_mpz_a >= my_mpz_b
my_mpz_a > my_mpz_b
also works if one or both operands are Lua integers
mpz.less (mpz_or_lua_int_a, mpz_or_lua_int_b)
mpz.less_equal (mpz_or_lua_int_a, mpz_or_lua_int_b)
mpz.equal (mpz_or_lua_int_a, mpz_or_lua_int_b)
mpz.greater_equal(mpz_or_lua_int_a, mpz_or_lua_int_b)
mpz.greater (mpz_or_lua_int_a, mpz_or_lua_int_b)
also works if one or both operands are Lua integers
cmp_res = mpz.cmp(mpz_or_lua_int_a, mpz_or_lua_int_b)
- returns a negative Lua integer if the 1st operand is less than the 2nd operand
- returns the Lua integer zero if the 1st operand equals the 2nd operand
- returns a positive Lua integer if the 1st operand is greater than the 2nd operand
copy_mpz = my_mpz:copy()
copy_mpz = mpz.copy(mpz_or_lua_int) -- equals mpz.new(mpz_or_lua_int)
- This creates a deep copy.
abs_of_my_mpz = mpz.abs(mpz_or_lua_int)
neg_of_my_mpz = - my_mpz
neg_of_my_mpz = mpz.neg(mpz_or_lua_int)
sum_mpz = mpz_or_lua_int_a + mpz_or_lua_int_b -- At least one operand must be a mpz!
sum_mpz = mpz.add(mpz_or_lua_int_a, mpz_or_lua_int_b)
diff_mpz = my_mpz_a - my_mpz_b -- At least one operand must be a mpz!
diff_mpz = mpz.sub(mpz_or_lua_int_a, mpz_or_lua_int_b)
- This computes the "directed difference" which can be negative.
prod_mpz = mpz_or_lua_int_a * mpz_or_lua_int_b -- At least one operand must be a mpz!
prod_mpz = mpz.mul(mpz_or_lua_int_a, mpz_or_lua_int_b)
quot_mpz = mpz_or_lua_int_a // mpz_or_lua_int_b -- At least one operand must be a mpz!
quot_mpz = mpz.div(mpz_or_lua_int_a, mpz_or_lua_int_b)
- The divisor (second operand) must not be zero.
Else an exception is raised andnil
is returned. - rounds towards zero (thus truncates resp. floors the absolute value)
This is in contrast to the Lua specification, that floor division rounds towards minus infinity (strictly floors). - returns no remainder
sqr_mpz = my_mpz^2 -- Note: The 2 as the 2nd operand must be a Lua integer!
sqr_mpz = mpz.sqr(mpz_or_lua_int)
computes the greatest integer whose square is less than or equals the operand*
sqrt_mpz = mpz.sqrt(mpz_or_lua_int)
* If the operand is negative, then returns the negative of the integer square root of the absolute value of the operand
The 2nd operand must be a Lua integer!
pow_mpz = my_mpz^lua_int
pow_mpz = mpz.pow(mpz_or_lua_int, lua_int)
The 2nd operand must be a Lua integer!
left_shifted_mpz = my_mpz << lua_int
left_shifted_mpz = mpz.shl(mpz_or_lua_int, lua_int)
- preserves the sign Thus performs an arithmetic left shift.
- Thus effectively multiplies by a power of two.
The 2nd operand must be a Lua integer!
right_shifted_mpz = my_mpz >> lua_int
right_shifted_mpz = mpz.shr(mpz_or_lua_int, lua_int)
- preserves the sign (unless all 1 bits are shifted out) Thus performs an arithmetic right shift.
- Thus effectively divides by a power of two and rounds towards zero.
This means creating a string of digits in a certain radix (positional notation).
- The string is prefixed with a minus character (
-
) if thempz
is negative. - The string is
0
if thempz
is zero. - The digits are not grouped.
- No padding digits are prefixed.
oct_str = my_mpz:oct()
oct_str = mpz.oct(mpz_or_lua_int)
dec_str = my_mpz:dec()
dec_str = mpz.dec(mpz_or_lua_int)
hex_str = my_mpz:hex()
hex_str = mpz.hex(mpz_or_lua_int)
hex_lc_str = my_mpz:hex_lowercase()
hex_lc_str = mpz.hex_lowercase(mpz_or_lua_int)
debug_str_of_mpz = my_mpz:debug_str()
debug_str_of_mpz = tostring(my_mpz)
- returns a string which denotes the individual limbs in hexadecimal digits