Malachite for FLINT Users: Integers
This page maps the functions of FLINT’s integer type, fmpz_t, onto their Malachite
counterparts:
Natural and
Integer, from
the malachite-nz crate. It follows the organization of the
fmpz.h chapter of the FLINT manual, as of FLINT 3.6.0, and
is a companion to Malachite for GMP Users: Integers; the
mapping index lists the whole family. The
Conventions of the GMP page, including
Allocation, apply here unchanged: where FLINT writes into an
output argument, Malachite returns the result. Functions whose names begin with an underscore are
FLINT-internal and are omitted.
Conventions
The fmpz representation
An fmpz stores values of absolute value at most \(2^{62}-1\) inline and promotes larger ones to
a GMP integer. A
Natural likewise
stores values below \(2^{64}\) inline, and an
Integer is a
sign and a Natural. (With 32-bit limbs, the thresholds are \(2^{30}-1\) and \(2^{32}\).) The
macros and constants of the tagged representation (COEFF_MAX, COEFF_MIN, COEFF_IS_MPZ,
PTR_TO_COEFF, COEFF_TO_PTR) have no counterparts, since Malachite’s representation is not part
of its public API. Arrays of fmpz become Vec<Integer> or slices.
Word types
FLINT’s ulong and slong are u64 and i64 on every 64-bit platform, Windows included. As on
the GMP page, most _ui and _si variants collapse into their base function’s row.
Aliasing
FLINT functions generally permit outputs to alias inputs. Rust does not; use the assign and
by-value forms described under Allocation. The case
fmpz_mul(x, x, x) is
Square,
with x.square_assign() as the in-place form.
Categories
Each function falls into one of five categories:
| meaning | |
|---|---|
| ✓ | A Malachite function does the same thing. |
| ≈ | A Malachite function serves the same purpose, but its specification differs. The notes say how. |
| ⚙ | Malachite does not expose this algorithm or helper; the Malachite column or the notes say what to call instead. |
| — | No counterpart is needed, either because Rust handles it for you or because it is outside Malachite’s scope. The notes say which. |
| ✗ | Malachite does not fully support this yet, but will in a future version. |
Memory management
The discussion on the GMP page of why Rust has no separate initialization step and nothing to clear applies here.
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_init (fmpz_t f) |
Natural::ZERO, Integer::ZERO |
| — | void fmpz_init2 (fmpz_t f, ulong limbs) |
|
| — | void fmpz_clear (fmpz_t f) |
|
| ✓ | void fmpz_init_set (fmpz_t f, const fmpz_t g) |
Clone |
| ✓ | void fmpz_init_set_ui (fmpz_t f, ulong g) |
From |
| ✓ | void fmpz_init_set_si (fmpz_t f, slong g) |
From, TryFrom |
fmpz_init. let x = Integer::ZERO;, which allocates nothing.
Default also returns zero.
fmpz_init2. A capacity hint; see the note under
mpz_init2 on the GMP page.
fmpz_clear. Memory is released when the value goes out of scope.
fmpz_init_set, fmpz_init_set_ui, fmpz_init_set_si. g.clone(), Natural::from(g),
and Integer::from(g), as in the
corresponding GMP section;
TryFrom turns a signed value
into a Natural.
Random generation
FLINT’s flint_rand_t state has the same shape as GMP’s gmp_randstate_t, and the
same note applies: Malachite’s stream
generators take a Seed
and return an infinite iterator, and its single-value get_* forms borrow a source of random
words mutably (a
StripedBitSource
for the striped forms). Random generation lives behind the random feature, in the
natural::random
and
integer::random
modules.
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_randbits_unsigned (fmpz_t f, flint_rand_t state, flint_bitcnt_t bits) |
get_random_natural_with_bits |
| ✓ | void fmpz_randbits (fmpz_t f, flint_rand_t state, flint_bitcnt_t bits) |
get_random_natural_with_bits, from_sign_and_abs |
| ≈ | void fmpz_randtest_unsigned (fmpz_t f, flint_rand_t state, flint_bitcnt_t bits) |
random_naturals, striped_random_naturals |
| ≈ | void fmpz_randtest (fmpz_t f, flint_rand_t state, flint_bitcnt_t bits) |
random_integers, striped_random_integers |
| ≈ | void fmpz_randtest_not_zero (fmpz_t f, flint_rand_t state, flint_bitcnt_t bits) |
random_nonzero_integers |
| ✓ | void fmpz_randm (fmpz_t f, flint_rand_t state, const fmpz_t m) |
get_random_natural_less_than, random_naturals_less_than |
| ≈ | void fmpz_randtest_mod (fmpz_t f, flint_rand_t state, const fmpz_t m) |
striped_random_natural_range |
| ≈ | void fmpz_randtest_mod_signed (fmpz_t f, flint_rand_t state, const fmpz_t m) |
striped_random_integer_range |
| ✗ | void fmpz_randprime (fmpz_t f, flint_rand_t state, flint_bitcnt_t bits, int proved) |
fmpz_randbits, fmpz_randbits_unsigned. get_random_natural_with_bits chooses uniformly
among the Naturals of exactly bits bits. FLINT’s signed version also picks a random sign;
compose it with Integer::from_sign_and_abs and a random bool.
The randtest family. The distributions differ, hence ≈. FLINT draws the bit length
uniformly from 0 to bits inclusive, with a hard cap. Malachite’s streams take a mean bit
length and draw sizes from a geometric distribution, with no cap; random_nonzero_integers
covers the not_zero variant. To reproduce FLINT’s shape, draw a length and then a value of that
length;
get_random_natural_with_up_to_bits
caps the length but is uniform over values, not over lengths.
fmpz_randm, fmpz_randtest_mod, fmpz_randtest_mod_signed. fmpz_randm is
get_random_natural_less_than, or the random_naturals_less_than stream. The two randtest_mod
forms bias toward the endpoints of the range (and toward zero, for the signed one); Malachite’s
range generators are uniform or striped instead, with no endpoint bias. The signed range
(-m/2, m/2] is an ordinary range for
uniform_random_integer_inclusive_range
or its striped counterpart.
fmpz_randprime. No counterpart: Malachite does not generate bignum primes.
FLINT’s limb-level random functions, in mpn_extras, are not mapped: Malachite’s limb-level functions are not public.
Conversion
Conversions to and from primitives follow the policy-trait scheme on the GMP page. The multi-word forms become Rust’s 128-bit primitives and Malachite’s limb-slice conversions.
| FLINT | Malachite | |
|---|---|---|
| ≈ | slong fmpz_get_si (const fmpz_t f) |
TryFrom, WrappingFrom, SaturatingFrom |
| ≈ | ulong fmpz_get_ui (const fmpz_t f) |
TryFrom, WrappingFrom, SaturatingFrom |
| ≈ | void fmpz_get_uiui (ulong * hi, ulong * low, const fmpz_t f) |
TryFrom, WrappingFrom |
| ✓ | ulong fmpz_get_nmod (const fmpz_t f, nmod_t mod) |
Mod |
| ≈ | double fmpz_get_d (const fmpz_t f) |
RoundingFrom, TryFrom |
| — | void fmpz_set_mpf (fmpz_t f, const mpf_t x) |
|
| — | void fmpz_get_mpf (mpf_t x, const fmpz_t f) |
|
| ✓ | void fmpz_get_mpfr (mpfr_t x, const fmpz_t f, mpfr_rnd_t rnd) |
from_integer_prec_round |
| ≈ | double fmpz_get_d_2exp (slong * exp, const fmpz_t f) |
SciMantissaAndExponent |
| — | void fmpz_get_mpz (mpz_t x, const fmpz_t f) |
|
| ✓ | int fmpz_get_mpn (nn_ptr * n, fmpz_t n_in) |
to_limbs_asc |
| ✓ | char * fmpz_get_str (char * str, int b, const fmpz_t f) |
ToStringBase, Display |
| ✓ | void fmpz_set_si (fmpz_t f, slong val) |
From, TryFrom |
| ✓ | void fmpz_set_ui (fmpz_t f, ulong val) |
From |
| ≈ | void fmpz_set_d (fmpz_t f, double c) |
RoundingFrom, TryFrom |
| ✓ | void fmpz_set_d_2exp (fmpz_t f, double d, slong exp) |
RoundingFrom, Shl |
| ✓ | void fmpz_neg_ui (fmpz_t f, ulong val) |
From, Neg |
| ✓ | void fmpz_set_uiui (fmpz_t f, ulong hi, ulong lo) |
From |
| ✓ | void fmpz_neg_uiui (fmpz_t f, ulong hi, ulong lo) |
From, Neg |
| ✓ | void fmpz_set_signed_uiui (fmpz_t f, ulong hi, ulong lo) |
From |
| ✓ | void fmpz_set_signed_uiuiui (fmpz_t f, ulong hi, ulong mid, ulong lo) |
from_twos_complement_limbs_asc |
| ✓ | void fmpz_set_ui_array (fmpz_t out, const ulong * in, slong n) |
from_limbs_asc |
| ✓ | void fmpz_set_signed_ui_array (fmpz_t out, const ulong * in, slong n) |
from_twos_complement_limbs_asc |
| ✓ | void fmpz_get_ui_array (ulong * out, slong n, const fmpz_t in) |
to_limbs_asc |
| ✓ | void fmpz_get_signed_ui_array (ulong * out, slong n, const fmpz_t in) |
to_twos_complement_limbs_asc |
| ✓ | void fmpz_set_mpn_large (fmpz_t z, nn_srcptr src, slong n, int negative) |
from_limbs_asc, from_sign_and_abs |
| ✓ | void fmpz_get_signed_uiui (ulong * hi, ulong * lo, const fmpz_t in) |
WrappingFrom |
| — | void fmpz_set_mpz (fmpz_t f, const mpz_t x) |
|
| ✓ | int fmpz_set_str (fmpz_t f, const char * str, int b) |
FromStringBase, FromStr |
| ✓ | void fmpz_set_ui_smod (fmpz_t f, ulong x, ulong m) |
BalancedMod |
| — | void flint_mpz_init_set_readonly (mpz_t z, const fmpz_t f) |
|
| — | void flint_mpz_clear_readonly (mpz_t z) |
|
| — | void fmpz_init_set_readonly (fmpz_t f, const mpz_t z) |
|
| — | void fmpz_clear_readonly (fmpz_t f) |
fmpz_get_si, fmpz_get_ui. The
policy-trait family from the GMP page: TryFrom
fails when the value does not fit, WrappingFrom keeps the low bits, SaturatingFrom clamps,
and
ConvertibleFrom
is the fits-test. FLINT leaves fmpz_get_ui of a negative number undefined (GMP’s mpz_get_ui
returns the low bits of the absolute value); each Malachite trait defines its result.
Words in pairs and arrays. The two-word forms are Rust’s 128-bit primitives:
fmpz_set_uiui(f, hi, lo) is Natural::from of a u128, fmpz_set_signed_uiui is
Integer::from of an i128, and the two neg forms compose with
Neg. fmpz_get_uiui is a u128
conversion under whichever policy you choose, and fmpz_get_signed_uiui (the value modulo
\(2^{128}\) in two’s complement) is i128::wrapping_from. To go between a u128 and a word pair,
use
JoinHalves
(u128::join_halves(hi, lo)) and
SplitInHalf
(split_in_half(), returning (hi, lo)). The array forms are the limb-slice conversions:
fmpz_set_ui_array is Natural::from_limbs_asc, the signed versions (including
fmpz_set_signed_uiuiui) are Integer::from_twos_complement_limbs_asc, and the get versions
are to_limbs_asc and to_twos_complement_limbs_asc. These return a minimal-length
Vec where FLINT fills exactly n
words; pad with zero words (or sign words, for two’s complement) if you need a fixed width.
fmpz_set_mpn_large is from_limbs_asc plus Integer::from_sign_and_abs, without its
preconditions: from_limbs_asc accepts any slice, unnormalized or empty. fmpz_get_mpn is
to_limbs_asc.
fmpz_get_d, fmpz_set_d, and the 2exp pair. fmpz_get_d truncates, so it is
f64::rounding_from(&f, Down); where FLINT leaves out-of-range values undefined, the
defined overflow behavior on the GMP page applies.
fmpz_set_d is Integer::rounding_from(c, Down); an infinity or NaN fails try_from and makes
rounding_from panic, and a subnormal (undefined in FLINT) truncates to zero. fmpz_get_d_2exp
is
SciMantissaAndExponent,
with the mantissa-normalization difference noted
on the GMP page for mpz_get_d_2exp.
fmpz_set_d_2exp rounds \(d \cdot 2^{exp}\) to the nearest integer; the exact spelling is
Rational::try_from(d) shifted by exp, then Integer::rounding_from(&q, Nearest).
The GMP and MPFR boundary. The conversions to and from mpz_t and mpf_t, including the
four readonly functions, have no counterpart because Malachite is not built on GMP. To pass a
value to C, or to GMP through bindings such as rug, use the
limb-slice conversions above, strings, or serde. For mpf_t, see the
note on the GMP page. fmpz_get_mpfr is
Float::from_integer_prec_round(f, prec, rnd) on
Float, which
takes the target precision explicitly and also returns an
Ordering giving the rounding
direction.
fmpz_get_nmod. Reduce with Natural::from(m) and
Mod,
then convert the result to a word. Malachite has no public counterpart of the precomputed
nmod_t context; see the mod-n page.
fmpz_get_str, fmpz_set_str. to_string_base and from_string_base, covering bases 2
through 62 with GMP’s digit alphabet, as described in
the notes on the GMP page:
Option replaces the -1
return and String replaces
the buffer. FLINT has no uppercase mode, so to_string_base covers all of fmpz_get_str. When
parsing, FLINT skips surrounding whitespace and tolerates interior whitespace; Malachite accepts
no whitespace, accepts a single leading + that FLINT rejects, and, like FLINT, rejects a doubled
minus sign.
fmpz_set_ui_smod. The representative of x modulo m in (-m/2, m/2], which is
BalancedMod,
returning an
Integer. FLINT
requires (without checking) 0 <= x < m; balanced_mod accepts any
Natural and
agrees wherever FLINT’s precondition holds.
Input and output
As on the GMP page, Malachite has no
FILE * functions: formatting and parsing work with any Rust reader or writer.
| FLINT | Malachite | |
|---|---|---|
| ✓ | int fmpz_read (fmpz_t f) |
FromStr |
| ✓ | int fmpz_fread (FILE * file, fmpz_t f) |
FromStr |
| ≈ | size_t fmpz_inp_raw (fmpz_t x, FILE * fin) |
Deserialize |
| ✓ | int fmpz_print (const fmpz_t x) |
Display |
| ✓ | int fmpz_fprint (FILE * fs, const fmpz_t x) |
Display |
| ≈ | size_t fmpz_out_raw (FILE * fout, const fmpz_t x) |
Serialize |
fmpz_read, fmpz_fread. Read a token and call parse::<Integer>() (decimal), or
from_string_base for other bases. Failure is an Err rather than a non-positive return.
FLINT rejects leading zeros; Malachite parses "00123".
fmpz_print, fmpz_fprint. print!("{x}"), or write!(f, "{x}") for any
Write. FLINT returns the number
of characters written; x.to_string().len() gives it if needed.
fmpz_out_raw, fmpz_inp_raw. These use GMP’s raw format, so the
discussion on the GMP page of mpz_out_raw
and mpz_inp_raw versus Malachite’s serde support applies, including the
encoding differences behind the ≈.
Basic properties and manipulation
| FLINT | Malachite | |
|---|---|---|
| ✓ | size_t fmpz_sizeinbase (const fmpz_t f, int b) |
SignificantBits, FloorLogBase |
| ✓ | flint_bitcnt_t fmpz_bits (const fmpz_t f) |
SignificantBits |
| ✓ | slong fmpz_size (const fmpz_t f) |
limb_count |
| ✓ | int fmpz_sgn (const fmpz_t f) |
Sign |
| ≈ | flint_bitcnt_t fmpz_val2 (const fmpz_t f) |
trailing_zeros |
| — | void fmpz_swap (fmpz_t f, fmpz_t g) |
|
| ✓ | void fmpz_set (fmpz_t f, const fmpz_t g) |
Clone |
| ✓ | void fmpz_zero (fmpz_t f) |
ZERO |
| ✓ | void fmpz_one (fmpz_t f) |
ONE |
| ✓ | int fmpz_abs_fits_ui (const fmpz_t f) |
ConvertibleFrom, UnsignedAbs |
| ✓ | int fmpz_fits_si (const fmpz_t f) |
ConvertibleFrom |
| ✓ | void fmpz_setbit (fmpz_t f, ulong i) |
BitAccess |
| ✓ | int fmpz_tstbit (const fmpz_t f, ulong i) |
BitAccess |
| ✓ | ulong fmpz_abs_lbound_ui_2exp (slong * exp, const fmpz_t x, int bits) |
sci_mantissa_and_exponent_round, ShrRound |
| ✓ | ulong fmpz_abs_ubound_ui_2exp (slong * exp, const fmpz_t x, int bits) |
sci_mantissa_and_exponent_round, ShrRound |
fmpz_sizeinbase, fmpz_bits, fmpz_size, fmpz_sgn. fmpz_bits is
significant_bits(), and fmpz_size is limb_count(), on a Natural or on an Integer’s
unsigned_abs_ref;
all return 0 for zero. fmpz_sgn is
Sign,
returning an Ordering. For
fmpz_sizeinbase, the digit count is f.floor_log_base(&base) + 1, but floor_log_base panics
on zero, so handle zero separately.
fmpz_val2. trailing_zeros(), on a Natural or on an Integer’s absolute value. For zero,
FLINT returns 0 and Malachite returns
None, hence ≈.
fmpz_swap, fmpz_set, fmpz_zero, fmpz_one.
std::mem::swap; x = y.clone() or
x.clone_from(&y); x = Integer::ZERO and x = Integer::ONE.
fmpz_abs_fits_ui, fmpz_fits_si. u64::convertible_from(f.unsigned_abs_ref()) and
i64::convertible_from(&f).
fmpz_setbit, fmpz_tstbit. f.set_bit(i) and f.get_bit(i), from
BitAccess,
with negative values acting as their two’s complement.
fmpz_abs_lbound_ui_2exp, fmpz_abs_ubound_ui_2exp.
sci_mantissa_and_exponent_round
with Floor or Ceiling gives a mantissa and exponent bounding the value from below or above,
but its mantissa is an f32 or f64 in [1, 2) (24 or 53 bits), where FLINT’s is an integer of
a caller-chosen width. For FLINT’s shape at width bits, let
e = x.significant_bits() as i64 - bits; the mantissa is
x.unsigned_abs_ref().shr_round(e, Floor).0, or Ceiling for the upper bound. As in FLINT, the
ceiling can carry to a power of two and gain a bit; shift once more if the width must be exact.
Comparison
As on the GMP page, comparisons return an
Ordering instead of a signed
int, and the _ui and _si variants use the same traits as their base functions.
| FLINT | Malachite | |
|---|---|---|
| ✓ | int fmpz_cmp (const fmpz_t f, const fmpz_t g) |
Ord |
| ✓ | int fmpz_cmp_ui (const fmpz_t f, ulong g) |
PartialOrd |
| ✓ | int fmpz_cmp_si (const fmpz_t f, slong g) |
PartialOrd |
| ✓ | int fmpz_cmpabs (const fmpz_t f, const fmpz_t g) |
OrdAbs |
| ✓ | int fmpz_cmp2abs (const fmpz_t f, const fmpz_t g) |
OrdAbsDouble |
| ✓ | int fmpz_equal (const fmpz_t f, const fmpz_t g) |
PartialEq |
| ✓ | int fmpz_equal_ui (const fmpz_t f, ulong g) |
PartialEq |
| ✓ | int fmpz_equal_si (const fmpz_t f, slong g) |
PartialEq |
| ✓ | int fmpz_is_zero (const fmpz_t f) |
PartialEq |
| ✓ | int fmpz_is_one (const fmpz_t f) |
PartialEq |
| ✓ | int fmpz_is_pm1 (const fmpz_t f) |
EqAbs |
| ✓ | int fmpz_is_even (const fmpz_t f) |
Parity |
| ✓ | int fmpz_is_odd (const fmpz_t f) |
Parity |
fmpz_cmp2abs. f.cmp_abs_double(&g), from
OrdAbsDouble,
compares |f| against |2g| without forming 2g. On
Natural, the
same comparison is
OrdDouble’s
cmp_double.
The predicates. fmpz_is_zero and fmpz_is_one are f == 0 and f == 1; fmpz_is_pm1 is
f.eq_abs(&1), from
EqAbs;
and the parity pair is f.even() and f.odd().
Basic arithmetic
This section is divided into subsections in the manual’s order. As
on the GMP page, the *Assign traits cover the
in-place case, every operator has borrowing forms, and the _ui and _si variants collapse into
their base function’s row.
Addition and multiplication
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_neg (fmpz_t f1, const fmpz_t f2) |
Neg, NegAssign |
| ✓ | void fmpz_abs (fmpz_t f1, const fmpz_t f2) |
Abs, UnsignedAbs |
| ✓ | void fmpz_add (fmpz_t f, const fmpz_t g, const fmpz_t h) |
Add, AddAssign |
| ✓ | void fmpz_add_ui (fmpz_t f, const fmpz_t g, ulong h) |
Add, AddAssign |
| ✓ | void fmpz_add_si (fmpz_t f, const fmpz_t g, slong h) |
Add, AddAssign |
| ≈ | void fmpz_sub (fmpz_t f, const fmpz_t g, const fmpz_t h) |
Sub, CheckedSub, SaturatingSub |
| ≈ | void fmpz_sub_ui (fmpz_t f, const fmpz_t g, ulong h) |
Sub, CheckedSub |
| ≈ | void fmpz_sub_si (fmpz_t f, const fmpz_t g, slong h) |
Sub, CheckedSub |
| ✓ | void fmpz_mul (fmpz_t f, const fmpz_t g, const fmpz_t h) |
Mul, MulAssign |
| ✓ | void fmpz_mul_ui (fmpz_t f, const fmpz_t g, ulong h) |
Mul, MulAssign |
| ✓ | void fmpz_mul_si (fmpz_t f, const fmpz_t g, slong h) |
Mul, MulAssign |
| ✓ | void fmpz_mul2_uiui (fmpz_t f, const fmpz_t g, ulong x, ulong y) |
Mul |
| ✓ | void fmpz_mul_2exp (fmpz_t f, const fmpz_t g, ulong e) |
Shl, ShlAssign |
| ✓ | void fmpz_one_2exp (fmpz_t f, ulong e) |
PowerOf2 |
| ✓ | void fmpz_addmul (fmpz_t f, const fmpz_t g, const fmpz_t h) |
AddMul, AddMulAssign |
| ✓ | void fmpz_addmul_ui (fmpz_t f, const fmpz_t g, ulong h) |
AddMul, AddMulAssign |
| ✓ | void fmpz_addmul_si (fmpz_t f, const fmpz_t g, slong h) |
AddMul, AddMulAssign |
| ≈ | void fmpz_submul (fmpz_t f, const fmpz_t g, const fmpz_t h) |
SubMul, SubMulAssign |
| ≈ | void fmpz_submul_ui (fmpz_t f, const fmpz_t g, ulong h) |
SubMul, SubMulAssign |
| ≈ | void fmpz_submul_si (fmpz_t f, const fmpz_t g, slong h) |
SubMul, SubMulAssign |
| ✓ | void fmpz_fmma (fmpz_t f, const fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_t d) |
MulAddMul, MulAddMulAssign |
| ≈ | void fmpz_fmms (fmpz_t f, const fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_t d) |
MulSubMul, MulSubMulAssign |
The operators. -g, g.abs(), g + h, g - h, g * h, and g << e, with
UnsignedAbs
producing the absolute value as a Natural. The subtraction and submul rows are ≈ because
on Natural a negative difference panics;
CheckedSub
and
SaturatingSub
are the alternatives. On Integer they match exactly.
fmpz_mul2_uiui. g * Natural::from(u128::from(x) * u128::from(y)); the word product
cannot overflow a u128.
fmpz_mul_2exp, fmpz_one_2exp. g << e, and Integer::power_of_2(e) from
PowerOf2.
FLINT’s restriction that e + FLINT_BITS must not overflow does not apply.
fmpz_addmul, fmpz_submul. f.add_mul_assign(&g, &h) and f.sub_mul_assign(&g, &h);
f.add_mul(&g, &h) and f.sub_mul(&g, &h) return the result instead.
fmpz_fmma, fmpz_fmms. \(ab + cd\) and \(ab - cd\) are a.mul_add_mul(b, c, d) and
a.mul_sub_mul(b, c, d). The fmms row is ≈ for the same reason as submul: on Natural a
negative result panics, and
CheckedMulSubMul
and
SaturatingMulSubMul
return None and 0 instead.
Division with rounding
FLINT uses GMP’s naming: cdiv rounds the quotient toward positive infinity, fdiv toward
negative infinity, and tdiv toward zero. As
on the GMP page, cdiv is
CeilingDivMod
and
CeilingMod,
fdiv is
DivMod
and Mod,
tdiv is
DivRem
and Rem (the / and %
operators), and a quotient alone under any mode is
DivRound
with Ceiling, Floor, or Down. A zero divisor raises an exception in FLINT and panics in
Malachite.
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_cdiv_qr (fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) |
CeilingDivMod |
| ✓ | void fmpz_fdiv_qr (fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) |
DivMod |
| ✓ | void fmpz_tdiv_qr (fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) |
DivRem |
| ≈ | void fmpz_ndiv_qr (fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) |
DivRound |
| ✓ | void fmpz_cdiv_q (fmpz_t f, const fmpz_t g, const fmpz_t h) |
DivRound, CeilingDivMod |
| ✓ | void fmpz_fdiv_q (fmpz_t f, const fmpz_t g, const fmpz_t h) |
DivRound, DivMod |
| ✓ | void fmpz_tdiv_q (fmpz_t f, const fmpz_t g, const fmpz_t h) |
Div, DivRound |
| ✓ | void fmpz_cdiv_q_si (fmpz_t f, const fmpz_t g, slong h) |
DivRound |
| ✓ | void fmpz_fdiv_q_si (fmpz_t f, const fmpz_t g, slong h) |
DivRound |
| ✓ | void fmpz_tdiv_q_si (fmpz_t f, const fmpz_t g, slong h) |
Div, DivRound |
| ✓ | void fmpz_cdiv_q_ui (fmpz_t f, const fmpz_t g, ulong h) |
DivRound |
| ✓ | void fmpz_fdiv_q_ui (fmpz_t f, const fmpz_t g, ulong h) |
DivRound |
| ✓ | void fmpz_tdiv_q_ui (fmpz_t f, const fmpz_t g, ulong h) |
Div, DivRound |
| ✓ | void fmpz_cdiv_q_2exp (fmpz_t f, const fmpz_t g, ulong exp) |
ShrRound |
| ✓ | void fmpz_fdiv_q_2exp (fmpz_t f, const fmpz_t g, ulong exp) |
Shr, ShrRound |
| ✓ | void fmpz_tdiv_q_2exp (fmpz_t f, const fmpz_t g, ulong exp) |
ShrRound |
| ✓ | void fmpz_fdiv_r (fmpz_t s, const fmpz_t g, const fmpz_t h) |
Mod |
| ✓ | void fmpz_cdiv_r_2exp (fmpz_t s, const fmpz_t g, ulong exp) |
CeilingModPowerOf2 |
| ✓ | void fmpz_fdiv_r_2exp (fmpz_t s, const fmpz_t g, ulong exp) |
ModPowerOf2 |
| ✓ | void fmpz_tdiv_r_2exp (fmpz_t s, const fmpz_t g, ulong exp) |
RemPowerOf2 |
| ✓ | ulong fmpz_cdiv_ui (const fmpz_t g, ulong h) |
CeilingMod, UnsignedAbs |
| ✓ | ulong fmpz_fdiv_ui (const fmpz_t g, ulong h) |
Mod |
| ✓ | ulong fmpz_tdiv_ui (const fmpz_t g, ulong h) |
Rem, UnsignedAbs |
fmpz_ndiv_qr. DivRound with Nearest rounds the quotient to the nearest integer, but
ties differ: FLINT rounds a tie toward zero, Malachite to even. For 3 / 2, fmpz_ndiv_qr gives
1 and (3).div_round(2, Nearest) gives 2. To reproduce FLINT’s rule, compare twice the truncated
remainder against the divisor (cmp_abs_double). DivRound returns only the quotient; the
remainder is g - &q * h, or one
SubMul.
The 2exp columns.
ShrRound
with Ceiling, Floor, or Down gives cdiv, fdiv, or tdiv; a plain g >> exp floors.
The remainders are ModPowerOf2 (floor, nonnegative), CeilingModPowerOf2 (ceiling,
nonpositive), and RemPowerOf2 (truncating, sign of g).
fmpz_cdiv_ui, fmpz_fdiv_ui, fmpz_tdiv_ui. These return the remainder’s absolute value
as a word. fmpz_fdiv_ui is Mod; the other two compose with
UnsignedAbs,
since the ceiling remainder is nonpositive and the truncated one takes g’s sign.
Exact division, divisibility, and modular reduction
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_divexact (fmpz_t f, const fmpz_t g, const fmpz_t h) |
DivExact, DivExactAssign |
| ✓ | void fmpz_divexact_si (fmpz_t f, const fmpz_t g, slong h) |
DivExact |
| ✓ | void fmpz_divexact_ui (fmpz_t f, const fmpz_t g, ulong h) |
DivExact |
| ✓ | void fmpz_divexact2_uiui (fmpz_t f, const fmpz_t g, ulong x, ulong y) |
DivExact |
| ✓ | int fmpz_divisible (const fmpz_t f, const fmpz_t g) |
DivisibleBy |
| ✓ | int fmpz_divisible_si (const fmpz_t f, slong g) |
DivisibleBy |
| ✓ | int fmpz_divides (fmpz_t q, const fmpz_t f, const fmpz_t g) |
DivMod |
| ✓ | void fmpz_mod (fmpz_t f, const fmpz_t g, const fmpz_t h) |
ModEuclidean |
| ✓ | ulong fmpz_mod_ui (fmpz_t f, const fmpz_t g, ulong h) |
ModEuclidean |
| ✓ | void fmpz_smod (fmpz_t f, const fmpz_t g, const fmpz_t h) |
BalancedMod |
| ✓ | void fmpz_preinvn_init (fmpz_preinvn_t inv, const fmpz_t f) |
DivModPrecomputed |
| — | void fmpz_preinvn_clear (fmpz_preinvn_t inv) |
|
| ✓ | void fmpz_fdiv_qr_preinvn (fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h, const fmpz_preinvn_t hinv) |
DivModPrecomputed, DivAssignModPrecomputed |
The divexact family. g.div_exact(&h). As in FLINT, exactness is not checked: if h
does not divide g, div_exact may panic or return a meaningless result. For
fmpz_divexact2_uiui, form x * y as a u128 and divide once.
fmpz_divisible, fmpz_divides. f.divisible_by(&g). For fmpz_divides, use
let (q, r) = f.div_mod(&g) and test r == 0. FLINT defines fmpz_divides(q, f, 0) to report
whether f is zero, while div_mod by zero panics, so test the divisor first if it can be zero.
fmpz_mod, fmpz_mod_ui. fmpz_mod returns a nonnegative remainder whatever the sign of
h, which is
ModEuclidean
(mod_euclidean, returning a Natural). For a positive divisor, as in fmpz_mod_ui,
Mod
agrees.
fmpz_smod. The remainder in (-|h|/2, |h|/2], which is
BalancedMod.
As in FLINT, only the magnitude of h matters, and a remainder of exactly |h|/2 is positive.
The preinvn trio.
DivModPrecomputed:
Integer::precompute_div_mod_data(&h) corresponds to fmpz_preinvn_init, and
g.div_mod_precomputed(&h, &data) to fmpz_fdiv_qr_preinvn (floor division).
DivAssignModPrecomputed
is the in-place form. As in FLINT, the data depends only on |h|. fmpz_preinvn_clear is
replaced by Drop.
Powers and logarithms
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_pow_ui (fmpz_t f, const fmpz_t g, ulong x) |
Pow, PowAssign |
| ✓ | void fmpz_ui_pow_ui (fmpz_t f, ulong g, ulong x) |
Pow |
| ✓ | int fmpz_pow_fmpz (fmpz_t f, const fmpz_t g, const fmpz_t x) |
Pow, TryFrom |
| ≈ | void fmpz_powm_ui (fmpz_t f, const fmpz_t g, ulong e, const fmpz_t m) |
ModPow |
| ≈ | void fmpz_powm (fmpz_t f, const fmpz_t g, const fmpz_t e, const fmpz_t m) |
ModPow |
| ✓ | slong fmpz_clog (const fmpz_t x, const fmpz_t b) |
CeilingLogBase |
| ✓ | slong fmpz_clog_ui (const fmpz_t x, ulong b) |
CeilingLogBase |
| ✓ | slong fmpz_flog (const fmpz_t x, const fmpz_t b) |
FloorLogBase |
| ✓ | slong fmpz_flog_ui (const fmpz_t x, ulong b) |
FloorLogBase |
| ✓ | double fmpz_dlog (const fmpz_t x) |
approx_log |
fmpz_pow_ui, fmpz_ui_pow_ui, fmpz_pow_fmpz. g.pow(x), with \(0^0 = 1\) in both
libraries. For fmpz_pow_fmpz, convert the exponent with u64::try_from(&x); its Err takes
the place of FLINT’s failure return (and of FLINT’s throw on a negative exponent). FLINT succeeds
for bases -1, 0, and 1 at any exponent, so handle those before converting.
fmpz_powm, fmpz_powm_ui. ModPow,
with the differences explained on the GMP page
for mpz_powm: the base must already be reduced, the residues are Naturals, and a negative
exponent is spelled as
ModInverse
followed by a positive power. FLINT’s abort on a zero modulus is a panic.
fmpz_clog, fmpz_flog. x.ceiling_log_base(&b) and x.floor_log_base(&b). Both panic
when x < 1 or b < 2, inputs FLINT assumes do not occur.
fmpz_dlog.
approx_log
on Rational,
via Rational::from(&x). FLINT’s result depends on the platform’s C log; Malachite’s uses the
libm crate and is identical on every platform.
Roots
| FLINT | Malachite | |
|---|---|---|
| ✓ | int fmpz_sqrtmod (fmpz_t b, const fmpz_t a, const fmpz_t p) |
ModSqrt |
| ✓ | void fmpz_sqrt (fmpz_t f, const fmpz_t g) |
FloorSqrt |
| ✓ | void fmpz_sqrtrem (fmpz_t f, fmpz_t r, const fmpz_t g) |
SqrtRem |
| ✓ | int fmpz_is_square (const fmpz_t f) |
IsSquare |
| ≈ | int fmpz_root (fmpz_t r, const fmpz_t f, slong n) |
FloorRoot, CeilingRoot, CheckedRoot |
| ✓ | int fmpz_is_perfect_power (fmpz_t root, const fmpz_t f) |
ExpressAsPower |
fmpz_sqrt, fmpz_sqrtrem, fmpz_is_square. g.floor_sqrt(), g.sqrt_rem(), and
f.is_square(); FLINT’s exception on a negative operand is a panic. sqrt_rem returns a tuple.
IsSquare is implemented only for Natural; for an Integer, test the sign first.
fmpz_root. The same ≈ as mpz_root,
explained on the GMP page: FLINT truncates
toward zero, so for a negative operand with odd n use
CeilingRoot,
and for a nonnegative one
FloorRoot.
For FLINT’s exactness flag, use
CheckedRoot
(the root only when exact) or
RootRem.
fmpz_sqrtmod. a.mod_sqrt(&p), returning an Option where FLINT sets an output and
returns a flag;
ModSqrt
is implemented for
Natural and the
unsigned primitives. As in FLINT, p is assumed prime but not checked, and for a composite p
the results match FLINT’s, including missed and spurious roots, with two exceptions where
Malachite returns the mathematically expected value: even moduli between 50 and 600, and
p = 2^64 - 1 or 2^64 - 3.
fmpz_is_perfect_power.
ExpressAsPower:
express_as_power on 64 returns Some((2, 6)), the root and the exponent, where
fmpz_is_perfect_power sets the root and returns the exponent. As in FLINT, 0 and 1 count as
perfect powers, and the root is not necessarily the smallest. For a negative
Integer, the
exponent is always odd (\(-8 = (-2)^3\)). The predicate alone is
IsPower.
Combinatorial functions and fused operations
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_fac_ui (fmpz_t f, ulong n) |
Factorial |
| ✓ | void fmpz_fib_ui (fmpz_t f, ulong n) |
Fibonacci |
| ✓ | void fmpz_bin_uiui (fmpz_t f, ulong n, ulong k) |
BinomialCoefficient |
| ✓ | void fmpz_rfac_ui (fmpz_t r, const fmpz_t x, ulong k) |
RisingFactorial |
| ✓ | void fmpz_rfac_uiui (fmpz_t r, ulong x, ulong k) |
RisingFactorial |
| ✓ | void fmpz_mul_tdiv_q_2exp (fmpz_t f, const fmpz_t g, const fmpz_t h, ulong exp) |
MulShrRound, MulShrRoundAssign |
| ✓ | void fmpz_mul_si_tdiv_q_2exp (fmpz_t f, const fmpz_t g, slong x, ulong exp) |
MulShrRound, MulShrRoundAssign |
fmpz_fac_ui, fmpz_fib_ui, fmpz_bin_uiui. Natural::factorial(n),
Natural::fibonacci(n), and Natural::binomial_coefficient(n, k).
fmpz_rfac_ui, fmpz_rfac_uiui. The rising factorial \(x (x+1) \cdots (x+k-1)\) is
x.rising_factorial(k): Integer::rising_factorial for fmpz_rfac_ui, with the same handling
of negative bases, and Natural::rising_factorial for fmpz_rfac_uiui, with a base of any size.
fmpz_mul_tdiv_q_2exp, fmpz_mul_si_tdiv_q_2exp. (&g).mul_shr_round(&h, exp, Down).0;
Down is truncation toward zero. The second return value reports how the result compares with
the exact quotient. A plain >> floors, so a negative product needs Down explicitly. For the
si variant, pass Integer::from(x).
Greatest common divisor
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_gcd_ui (fmpz_t f, const fmpz_t g, ulong h) |
Gcd |
| ✓ | void fmpz_gcd (fmpz_t f, const fmpz_t g, const fmpz_t h) |
Gcd |
| ✓ | void fmpz_gcd3 (fmpz_t f, const fmpz_t a, const fmpz_t b, const fmpz_t c) |
Gcd |
| ✓ | void fmpz_lcm (fmpz_t f, const fmpz_t g, const fmpz_t h) |
Lcm |
| ≈ | void fmpz_gcdinv (fmpz_t d, fmpz_t a, const fmpz_t f, const fmpz_t g) |
ModInverse, ExtendedGcd |
| ≈ | void fmpz_xgcd (fmpz_t d, fmpz_t a, fmpz_t b, const fmpz_t f, const fmpz_t g) |
ExtendedGcd |
| ✓ | void fmpz_xgcd_canonical_bezout (fmpz_t d, fmpz_t a, fmpz_t b, const fmpz_t f, const fmpz_t g) |
ExtendedGcd |
| ⚙ | void fmpz_xgcd_partial (fmpz_t co2, fmpz_t co1, fmpz_t r2, fmpz_t r1, const fmpz_t L) |
internal |
fmpz_gcd, fmpz_gcd3, fmpz_lcm.
Gcd
and
Lcm
are defined on
Natural; since
FLINT’s results are nonnegative, take
unsigned_abs
of each
Integer first.
fmpz_gcd3 is a.gcd(&b).gcd(&c).
The xgcd family. fmpz_xgcd_canonical_bezout normalizes the cofactors by
\(|a| < |g/2d|\) and \(|b| < |f/2d|\), the same normalization, edge cases included, as
ExtendedGcd,
so extended_gcd returns identical cofactors, as a tuple. Plain fmpz_xgcd follows the
fmpz_gcdinv convention instead, hence ≈.
fmpz_gcdinv. For 0 <= f < g, returns d = gcd(f, g) and a with
\(af \equiv d \pmod{g}\). For a modular inverse,
ModInverse
returns None when f and g
are not coprime. For d and a cofactor in every case, extended_gcd’s first cofactor satisfies
the same congruence after reduction modulo g, but is normalized differently, hence ≈.
fmpz_xgcd_partial. Malachite has an internal port of this function (Lehmer’s extended GCD
with early termination), but it is not public. There is no public way to stop the reduction at a
bound;
ExtendedGcd
computes the complete GCD and cofactors.
Modular arithmetic
| FLINT | Malachite | |
|---|---|---|
| ✓ | slong fmpz_remove (fmpz_t rop, const fmpz_t op, const fmpz_t f) |
RemovePower |
| ≈ | int fmpz_invmod (fmpz_t f, const fmpz_t g, const fmpz_t h) |
ModInverse |
| ✓ | void fmpz_negmod (fmpz_t f, const fmpz_t g, const fmpz_t h) |
ModNeg, NegMod |
| ≈ | int fmpz_jacobi (const fmpz_t a, const fmpz_t n) |
JacobiSymbol, KroneckerSymbol |
| ✓ | int fmpz_kronecker (const fmpz_t a, const fmpz_t n) |
KroneckerSymbol |
| ✓ | void fmpz_divides_mod_list (fmpz_t xstart, fmpz_t xstride, fmpz_t xlength, const fmpz_t a, const fmpz_t b, const fmpz_t n) |
ModDivList |
fmpz_remove. RemovePower,
which returns the reduced number and the count as a tuple. As in FLINT, a zero input removes
nothing, and a factor of 1 or less is rejected (FLINT aborts; Malachite panics).
fmpz_invmod. ModInverse
returns Option instead of a
flag. It is ≈ for two reasons: mod_inverse requires its input already reduced and nonzero,
where FLINT reduces it; and FLINT treats every value as invertible modulo h = ±1, with inverse
0, while mod_inverse rejects the only residue, 0. Test for a unit modulus first if one can
occur.
fmpz_negmod. FLINT requires g to be reduced but does not check. g.mod_neg(&h), from
ModNeg,
has the same precondition and panics if it fails. g.neg_mod(&h), from
NegMod,
accepts any g. Both agree on reduced inputs.
fmpz_jacobi, fmpz_kronecker. As
on the GMP page, KroneckerSymbol matches
for every input, while JacobiSymbol requires an odd positive denominator. FLINT’s fmpz_jacobi
does not check the parity or sign of n; where its result would be undefined, jacobi_symbol
panics, and kronecker_symbol returns the Kronecker symbol.
fmpz_divides_mod_list. The solutions of \(ax \equiv b \pmod n\), as an arithmetic
progression. b.mod_div_list(&a, &n) returns Some((start, stride, length)) in place of FLINT’s
three outputs and all-zeros-on-failure convention; note that the dividend b is the receiver, as
in mod_div on the mod-n page. The results agree
exactly with FLINT’s. FLINT reduces a modulo n itself, while mod_div_list requires both
inputs already reduced.
Bit packing and unpacking
The counterpart is
BitBlockAccess,
which reads or writes a block of bits at any position in a Natural or an Integer. Hold the
buffer as a
Natural
(the limb-slice conversions convert a raw buffer); FLINT’s limb pointer plus
sub-word shift becomes a single u64 bit position.
| FLINT | Malachite | |
|---|---|---|
| ≈ | int fmpz_bit_pack (ulong * arr, flint_bitcnt_t shift, flint_bitcnt_t bits, const fmpz_t coeff, int negate, int borrow) |
BitBlockAccess |
| ≈ | int fmpz_bit_unpack (fmpz_t coeff, ulong * arr, flint_bitcnt_t shift, flint_bitcnt_t bits, int negate, int borrow) |
BitBlockAccess |
| ✓ | void fmpz_bit_unpack_unsigned (fmpz_t coeff, const ulong * arr, flint_bitcnt_t shift, flint_bitcnt_t bits) |
BitBlockAccess |
fmpz_bit_unpack_unsigned. buffer.get_bits(pos, pos + bits).
fmpz_bit_pack, fmpz_bit_unpack. assign_bits and get_bits move raw fields, which
covers nonnegative coefficients with no borrow. FLINT’s negate and borrow parameters, which
store negative coefficients in two’s complement and carry a borrow into the next field, have no
counterpart, hence ≈. Also, fmpz_bit_pack adds its field into the array, assuming the bits
above shift are zero, while assign_bits overwrites the range.
Logic Operations
In both libraries, negative operands behave as infinitely sign-extended two’s complement; see the GMP page.
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_complement (fmpz_t r, const fmpz_t f) |
Not |
| ✓ | void fmpz_clrbit (fmpz_t f, ulong i) |
BitAccess |
| ✓ | void fmpz_combit (fmpz_t f, ulong i) |
BitAccess |
| ✓ | void fmpz_and (fmpz_t r, const fmpz_t a, const fmpz_t b) |
BitAnd |
| ✓ | void fmpz_or (fmpz_t r, const fmpz_t a, const fmpz_t b) |
BitOr |
| ✓ | void fmpz_xor (fmpz_t r, const fmpz_t a, const fmpz_t b) |
BitXor |
| ✓ | ulong fmpz_popcnt (const fmpz_t a) |
CountOnes |
The operators and bits. !f for the ones’ complement; a & b, a | b, and a ^ b with
their Assign forms; and f.clear_bit(i) and f.flip_bit(i), from
BitAccess.
fmpz_popcnt. count_ones() on a
Natural. FLINT
leaves negative input undefined; on an Integer,
checked_count_ones
returns None for negative
values.
Chinese remaindering
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_CRT_ui (fmpz_t out, const fmpz_t r1, const fmpz_t m1, ulong r2, ulong m2, int sign) |
Crt, BalancedCrt |
| ✓ | void fmpz_CRT (fmpz_t out, const fmpz_t r1, const fmpz_t m1, const fmpz_t r2, const fmpz_t m2, int sign) |
Crt, BalancedCrt |
fmpz_CRT, fmpz_CRT_ui. FLINT’s sign flag selects the representative in
\([0, m_1m_2)\) or in \((-m_1m_2/2, m_1m_2/2]\); Malachite has a function for each.
Natural::crt is sign = 0, and Integer::balanced_crt is sign = 1, taking its first residue
as an Integer anywhere in \([-m_1, m_1)\), so a balanced result can be fed into the next
combination. FLINT treats coprimality as an unchecked precondition and throws when m1 is not
invertible; both Malachite functions return an
Option, None exactly when the
moduli share a factor. On their shared domain, the results agree with FLINT’s.
| FLINT | Malachite | |
|---|---|---|
| ⚙ | void fmpz_multi_CRT_init (fmpz_multi_CRT_t CRT) |
internal |
| ⚙ | int fmpz_multi_CRT_precompute (fmpz_multi_CRT_t CRT, const fmpz * moduli, slong len) |
internal |
| ⚙ | void fmpz_multi_CRT_precomp (fmpz_t output, const fmpz_multi_CRT_t P, const fmpz * inputs, int sign) |
internal |
| ✓ | int fmpz_multi_CRT (fmpz_t output, const fmpz * moduli, const fmpz * values, slong len, int sign) |
Natural::multi_crt, Integer::multi_balanced_crt |
| ⚙ | void fmpz_multi_CRT_clear (fmpz_multi_CRT_t P) |
internal |
The fmpz_multi_CRT family. Natural::multi_crt is fmpz_multi_CRT with sign = 0, and
Integer::multi_balanced_crt is sign = 1. The precomputed context (init, precompute,
precomp, clear) is ported but not public, so each call takes the moduli afresh.
Failure is None, under FLINT’s
conditions: with one modulus, only 0 is rejected; with two or more, any 0 or 1, or any
non-coprime pair, is rejected. FLINT reduces arbitrary inputs, while Malachite requires each
residue already reduced modulo its modulus. Otherwise the results agree with FLINT’s, edge cases
included.
| FLINT | Malachite | |
|---|---|---|
| ⚙ | void fmpz_multi_mod_ui (ulong * out, const fmpz_t in, const fmpz_comb_t comb, fmpz_comb_temp_t temp) |
internal |
| ⚙ | void fmpz_multi_CRT_ui (fmpz_t output, nn_srcptr residues, const fmpz_comb_t comb, fmpz_comb_temp_t ctemp, int sign) |
internal |
| ⚙ | void fmpz_comb_init (fmpz_comb_t comb, nn_srcptr primes, slong num_primes) |
internal |
| ⚙ | void fmpz_comb_temp_init (fmpz_comb_temp_t temp, const fmpz_comb_t comb) |
internal |
| ⚙ | void fmpz_comb_clear (fmpz_comb_t comb) |
internal |
| ⚙ | void fmpz_comb_temp_clear (fmpz_comb_temp_t temp) |
internal |
The comb. Malachite has an internal port of FLINT’s multimodular comb, but it is not public.
To reduce a value modulo many word-sized moduli, use Mod for each; to recombine, use
Natural::multi_crt or Integer::multi_balanced_crt.
Primality testing
This section is not mapped row by row. Malachite does not test the primality of Naturals or
Integers, so fmpz_is_prime, fmpz_is_probabprime and its variants, fmpz_nextprime, the
fmpz_lucas_chain functions, and fmpz_divisor_in_residue_class_lenstra have no counterparts.
Special functions
| FLINT | Malachite | |
|---|---|---|
| ✓ | void fmpz_primorial (fmpz_t res, ulong n) |
Primorial |
| ✗ | void fmpz_euler_phi (fmpz_t res, const fmpz_t n) |
|
| ✗ | void fmpz_factor_euler_phi (fmpz_t res, const fmpz_factor_t fac) |
|
| ✗ | int fmpz_moebius_mu (const fmpz_t n) |
|
| ✗ | int fmpz_factor_moebius_mu (const fmpz_factor_t fac) |
|
| ✗ | void fmpz_divisor_sigma (fmpz_t res, ulong k, const fmpz_t n) |
|
| ✗ | void fmpz_factor_divisor_sigma (fmpz_t res, ulong k, const fmpz_factor_t fac) |
fmpz_primorial. Natural::primorial(n), the product of the primes up to and including
n, as in FLINT.
The multiplicative functions. Euler’s totient, the Möbius function, and the divisor sums
\(\sigma_k\) have no counterparts, nor does a factorization type corresponding to
fmpz_factor_t.