How Malachite Is Tested: Integers
This page lists every public function of
Integer, the
signed integer type of the malachite-nz crate, and records which independent implementations it
is checked against. The introduction describes the oracles and the testing they
sit in; this page is the ledger. It follows the organization of the crate’s documentation, one
section per module, so that a function is where its documentation is. An Integer is a sign and a
Natural absolute value, and many of its functions reduce to the
Natural ones, but each is listed and checked here in its own right.
Reading the tables
Each row is one operation, named after the module that implements it and linked to that module’s
documentation. The Functions column lists the traits and methods the module implements; a
trait’s by-value and by-reference implementations, and its *Assign form, count as one function,
since they compute the same thing, while functions with genuinely different results (div_mod
against div_rem, Add against Sum) are listed separately. The remaining columns are the
oracles of the introduction:
| meaning | |
|---|---|
| ✓ | The oracle computes this function and agrees with Malachite on every input tried. |
| ≈ | The oracle agrees, after an adaptation on the oracle side that is more than a change of spelling: a convention of Malachite’s that the oracle does not share is applied to the oracle’s output before the comparison. The mapping pages say what the adaptation is. |
| The oracle does not check this function. |
A function with no mark in any column is checked only by Malachite’s own unit and property tests. Those rows are collected at the end of the page, in What is not yet cross-checked, which is the list of what the oracles, Azurite first, should gain next.
Functions that are not part of the public interface are not listed: the limbs_* functions that
operate on limb slices and the other #[doc(hidden)] helpers are exercised by the same runs as
the functions built on them, but they are implementation details.
Basic
The constants and the standard traits of the type itself, from
malachite_nz::integer.
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| constants | Zero, One, Two, NegativeOne |
|||||
| default | Default |
|||||
| named | Named |
|||||
| hash | Hash |
|||||
| clone | Clone |
✓ | ✓ |
The constants are the values 0, 1, 2, and -1; every oracle run uses them on the way to
checking something else, but no run checks them as such. Named gives the type’s name as a string
and Hash is derived from the sign and absolute value, so neither has anything to compare against.
Clone, also derived, is checked against GMP’s and num’s copies.
Unlike Natural, Integer has no Min or Max.
Comparison
From
malachite_nz::integer::comparison.
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| cmp | Ord, PartialOrd |
✓ | ✓ | ✓ | ||
| eq | PartialEq, Eq |
✓ | ✓ | ✓ | ||
| cmp_abs | OrdAbs, PartialOrdAbs |
✓ | ||||
| cmp_abs | OrdAbsDouble, PartialOrdAbsDouble |
|||||
| eq_abs | EqAbs |
|||||
| partial_cmp_natural | PartialOrd<Natural> and the reverse direction |
✓ | ||||
| partial_eq_natural | PartialEq<Natural> and the reverse direction |
✓ | ||||
| cmp_abs_natural | PartialOrdAbs<Natural> and the reverse direction |
✓ | ||||
| eq_abs_natural | EqAbs<Natural> and the reverse direction |
|||||
| partial_cmp_primitive_int | PartialOrd<u8>, …, PartialOrd<isize>, and the reverse directions |
✓ | ✓ | |||
| partial_eq_primitive_int | PartialEq<u8>, …, PartialEq<isize>, and the reverse directions |
✓ | ✓ | |||
| cmp_abs_primitive_int | PartialOrdAbs<u8>, …, PartialOrdAbs<isize>, and the reverse directions |
|||||
| eq_abs_primitive_int | EqAbs<u8>, …, EqAbs<isize>, and the reverse directions |
|||||
| partial_cmp_primitive_float | PartialOrd<f32>, PartialOrd<f64>, and the reverse directions |
✓ | ||||
| partial_eq_primitive_float | PartialEq<f32>, PartialEq<f64>, and the reverse directions |
✓ | ||||
| cmp_abs_primitive_float | PartialOrdAbs<f32>, PartialOrdAbs<f64>, and the reverse directions |
|||||
| eq_abs_primitive_float | EqAbs<f32>, EqAbs<f64>, and the reverse directions |
The order and equality of two Integers are checked by Azurite, GMP, and num. Comparison with a
Natural and with the primitive integers is checked by GMP, and with the unsigned primitives also
by num. Azurite checks these mixed comparisons with the Integer on the left (x < n, x == 5),
but not the reverse direction, whose demos exist but are not yet run, so those rows carry no
Azurite mark. Comparison of absolute values is checked by GMP’s cmp_abs for two Integers and
for an Integer and a Natural; the absolute-value comparisons with primitives, the
absolute-value equalities, and the doubled comparison cmp_abs_double
(\(\operatorname{cmp}(|x|, 2|y|)\)) have no oracle. Comparison with f32 and f64 is checked
by GMP.
Arithmetic
From
malachite_nz::integer::arithmetic.
The module is large, so its rows are grouped by theme. Integer has no modular arithmetic family
and no logarithms; those are Natural functions.
Addition, subtraction, and multiplication
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| add | Add |
✓ | ✓ | ✓ | ||
| add | Sum |
✓ | ||||
| sub | Sub |
✓ | ✓ | ✓ | ||
| abs_diff | AbsDiff |
|||||
| neg | Neg |
✓ | ✓ | ✓ | ||
| mul | Mul |
✓ | ✓ | ✓ | ||
| mul | Product |
✓ | ||||
| square | Square |
|||||
| abs_squared | AbsSquared |
|||||
| add_mul | AddMul |
|||||
| sub_mul | SubMul |
|||||
| mul_add_mul | MulAddMul |
|||||
| mul_sub_mul | MulSubMul |
|||||
| average | Average |
|||||
| average | AverageRound |
Addition, subtraction, multiplication, and negation are checked by Azurite (AzInt.add, sub,
mul, neg) and by GMP and num. Sum and Product are checked against a reference
implementation that folds + and * one term at a time. AzInt has no squaring function,
so square is not yet cross-checked, though the Natural one is checked by Azurite. The fused operations (add_mul,
sub_mul, mul_add_mul, mul_sub_mul), abs_diff, abs_squared, and average are not yet
cross-checked: their property tests compare them with the unfused combinations of operations that
are, which is a strong check but not an independent one.
Shifts
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| shl | Shl<u8>, …, Shl<isize> |
✓ | ✓ | ✓ | ||
| shr | Shr<u8>, …, Shr<isize> |
✓ | ✓ | ✓ | ||
| shl_round | ShlRound<i8>, …, ShlRound<isize> |
|||||
| shr_round | ShrRound<u8>, …, ShrRound<isize> |
✓ | ||||
| mul_shr_round | MulShrRound |
|||||
| round_to_multiple_of_power_of_2 | RoundToMultipleOfPowerOf2 |
Shifting by a primitive integer is checked by Azurite’s shiftLeft and shiftRight for every shift
type, a negative count reversing the direction, and against GMP; the shifts by unsigned counts also
against num. A right shift of a negative Integer rounds toward \(-\infty\), as an arithmetic
shift does, and Azurite’s shiftRight has the same convention. shr_round is checked by Azurite’s
shiftRightRound in every rounding mode, Exact being checked as “the shift is exact and the
Ordering is Equal”.
Division
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| div | Div |
✓ | ✓ | |||
| div | CheckedDiv |
✓ | ||||
| div_mod | DivMod |
✓ | ✓ | ✓ | ||
| div_mod | DivRem |
✓ | ✓ | |||
| div_mod | CeilingDivMod |
✓ | ||||
| div_mod | DivModPrecomputed |
|||||
| mod_op | Mod |
✓ | ✓ | ✓ | ||
| mod_op | Rem |
✓ | ✓ | |||
| mod_op | CeilingMod |
✓ | ||||
| div_euclidean | DivEuclidean |
✓ | ||||
| mod_euclidean | ModEuclidean |
✓ | ||||
| div_mod_euclidean | DivModEuclidean |
✓ | ||||
| div_exact | DivExact |
✓ | ✓ | |||
| div_round | DivRound |
✓ | ✓ | ✓ | ||
| divisible_by | DivisibleBy |
✓ | ✓ | |||
| eq_mod | EqMod |
✓ | ||||
| round_to_multiple | RoundToMultiple |
|||||
| balanced_mod | BalancedMod |
On Integers the division conventions differ, so each gets its own row: / and div_rem
truncate the quotient toward zero, div_mod and mod_op round it toward \(-\infty\) (the
remainder taking the divisor’s sign), ceiling_div_mod and ceiling_mod round it toward
\(+\infty\), and the Euclidean forms keep the remainder non-negative. GMP has all four families and
checks every one; num checks the truncating and floor forms. Azurite’s / is Euclidean, and it also has
floor division (fdivMod), against which the floor forms (div_mod, mod_op) are checked; the
truncating and ceiling forms are not yet run against it. div_exact,
div_round (every rounding mode, Exact checked as an exact division), and the Euclidean forms
are checked by Azurite, and div_exact, div_round, divisible_by, and eq_mod by GMP.
DivModPrecomputed, which reuses a precomputed inverse of the divisor, is compared with div_mod;
round_to_multiple and balanced_mod, the remainder in \((-m/2, m/2]\), are covered by property
tests alone.
Signs, units, and parity
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| sign | Sign |
✓ | ✓ | ✓ | ||
| abs | Abs |
✓ | ✓ | |||
| abs | UnsignedAbs, unsigned_abs_ref |
✓ | ||||
| abs | mutate_unsigned_abs |
|||||
| parity | Parity |
✓ | ||||
| is_unit | IsUnit |
|||||
| conjugate | Conjugate |
|||||
| canonicalize_unit | CanonicalizeUnit |
|||||
| canonical_unit_i_pow | CanonicalUnitIPow |
sign is checked by Azurite, GMP, and num, and abs by GMP and num. unsigned_abs, which returns
the absolute value as a Natural, is checked by Azurite’s natAbs; even and odd by Azurite’s
isEven and isOdd. mutate_unsigned_abs, which applies a function to the absolute value in
place, has no counterpart to compare with. The unit functions (is_unit, conjugate,
canonicalize_unit, canonical_unit_i_pow) are the trivial cases of functions that matter for
Gaussian integers and polynomials, where they are cross-checked.
Arithmetic modulo a power of 2
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| mod_power_of_2 | ModPowerOf2 |
✓ | ||||
| mod_power_of_2 | RemPowerOf2 |
|||||
| mod_power_of_2 | CeilingModPowerOf2 |
|||||
| eq_mod_power_of_2 | EqModPowerOf2 |
✓ |
mod_power_of_2, the residue of an Integer in \([0, 2^k)\), is checked by Azurite’s
AzZModPow2.ofAzInt. The truncating and ceiling forms (rem_power_of_2, whose result takes the
sign of the input, and ceiling_mod_power_of_2, the non-positive residue) are not yet run against
it, and eq_mod_power_of_2 is checked against GMP’s is_congruent_2pow.
Chinese remaindering
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| crt | BalancedCrt |
✓ | ✓ | |||
| multi_crt | Integer::multi_balanced_crt |
✓ |
The balanced Chinese remainder functions return the solution in \((-M/2, M/2]\) rather than
\([0, M)\). balanced_crt is checked against FLINT’s fmpz_CRT with its sign flag set and a
reference that takes the solution in \([0, M)\) and shifts it into the balanced range, and
multi_balanced_crt against FLINT’s fmpz_multi_CRT with the same flag.
Powers and roots
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| pow | Pow<u64> |
✓ | ✓ | ✓ | ||
| sqrt | FloorSqrt |
✓ | ✓ | |||
| sqrt | CeilingSqrt |
|||||
| sqrt | CheckedSqrt |
|||||
| root | FloorRoot<u64> |
✓ | ✓ | |||
| root | CeilingRoot<u64> |
✓ | ✓ | |||
| root | CheckedRoot<u64> |
|||||
| root | RootRem<u64> |
✓ |
pow is checked by Azurite, GMP, and num. Square roots are defined only for non-negative
Integers, and floor_sqrt is checked against GMP and num; odd roots of negative numbers are
defined, and GMP’s and num’s roots round toward zero, so they check floor_root on non-negative
inputs and ceiling_root on negative ones, where those functions round toward zero too.
root_rem is checked against GMP. ceiling_sqrt, checked_sqrt, and checked_root are not yet
cross-checked for Integer, though their Natural counterparts are checked by Azurite.
Powers of 2
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| power_of_2 | PowerOf2<u64> |
✓ | ||||
| is_power_of_2 | IsPowerOf2 |
✓ | ✓ | |||
| divisible_by_power_of_2 | DivisibleByPowerOf2 |
✓ |
power_of_2 and is_power_of_2 are checked by Azurite, and is_power_of_2 and
divisible_by_power_of_2 by GMP.
GCD and number theory
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| gcd | Gcd |
✓ | ||||
| extended_gcd | ExtendedGcd |
✓ | ✓ | |||
| kronecker_symbol | JacobiSymbol |
✓ | ||||
| kronecker_symbol | LegendreSymbol |
✓ | ||||
| kronecker_symbol | KroneckerSymbol |
✓ |
gcd, which returns a Natural, is checked by Azurite’s NormalizedGcd instance on AzInt. extended_gcd is checked
against GMP and num, which compare the Bézout pair exactly; Azurite’s extended GCD is run on the
Natural version only (as ≈, for the normalization described on the naturals
page). The Jacobi, Legendre, and Kronecker symbols
are checked against GMP.
Combinatorial functions
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| binomial_coefficient | BinomialCoefficient |
✓ | ||||
| falling_factorial | FallingFactorial |
✓ | ||||
| rising_factorial | RisingFactorial |
✓ |
The binomial coefficient, which takes a negative first argument through the identity
\(\binom{-n}{k} = (-1)^k \binom{n+k-1}{k}\), is checked against GMP; falling_factorial against the defining product;
and rising_factorial against FLINT’s fmpz_rfac.
Conversion
From
malachite_nz::integer::conversion.
Naturals
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| from_natural | From<Natural> |
✓ | ||||
| from_natural | from_sign_and_abs, from_sign_and_abs_ref |
✓ | ||||
| natural_from_integer | TryFrom<Integer> for Natural |
|||||
| natural_from_integer | SaturatingFrom<Integer>, ConvertibleFrom<Integer> for Natural |
Conversion from a Natural is checked by Azurite’s AzNat.toAzInt, and
from_sign_and_abs by AzInt.mkNorm, which forces the sign positive when the magnitude is zero,
as Malachite does. The conversions back to Natural, which reject or clamp a negative input, are
not yet cross-checked; the absolute value as a Natural (unsigned_abs) is listed under
Signs, units, and parity.
Primitive types
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| from_primitive_int | From<u8>, …, From<isize> |
✓ | ✓ | ✓ | ||
| from_primitive_int | const_from_unsigned, const_from_signed |
|||||
| primitive_int_from_integer | WrappingFrom<Integer> for every primitive integer |
✓ | ✓ | |||
| primitive_int_from_integer | TryFrom<Integer> for every primitive integer |
✓ | ||||
| primitive_int_from_integer | SaturatingFrom, OverflowingFrom, ConvertibleFrom for every primitive integer |
|||||
| from_bool | From<bool> |
|||||
| from_primitive_float | RoundingFrom<f32>, RoundingFrom<f64> |
|||||
| from_primitive_float | TryFrom<f32>, TryFrom<f64>, ConvertibleFrom |
|||||
| primitive_float_from_integer | RoundingFrom<Integer> for f32, f64 |
|||||
| primitive_float_from_integer | TryFrom<Integer>, ConvertibleFrom<Integer> for f32, f64 |
|||||
| is_integer | IsInteger |
|||||
| is_real | IsReal |
|||||
| is_gaussian_integer | IsGaussianInteger |
Conversion from every primitive integer type is checked by Azurite (UInt64.toAzInt,
Int64.toAzInt, and their narrower forms), GMP, and num. Toward the primitives, wrapping_from
(the value modulo \(2^w\), two’s complement for a negative Integer, reinterpreted for signed
types) is checked by Azurite’s toUInt64 and toInt64 families and by GMP, and try_from by GMP.
The float conversions are not yet cross-checked for Integer; the Natural ones are checked by
Azurite through AzFloat, and the same oracle would extend to a sign.
Two’s-complement limbs
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| from_twos_complement_limbs | from_twos_complement_limbs_asc, from_owned_twos_complement_limbs_asc |
|||||
| from_twos_complement_limbs | from_twos_complement_limbs_desc, from_owned_twos_complement_limbs_desc |
|||||
| to_twos_complement_limbs | to_twos_complement_limbs_asc, into_twos_complement_limbs_asc, to_twos_complement_limbs_desc, into_twos_complement_limbs_desc |
|||||
| to_twos_complement_limbs | twos_complement_limbs, TwosComplementLimbIterator::get_limb |
|||||
| to_twos_complement_limbs | twos_complement_limb_count |
An Integer’s limbs are its two’s-complement representation, sign-extended as far as needed. No
oracle checks this interface yet: Azurite has no two’s-complement view of an AzInt, and the
property tests check the conversions against each other, against the Natural limbs for
non-negative values, and by round trips.
Strings
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| to_string | Display, Debug |
✓ | ✓ | ✓ | ||
| to_string | Binary, Octal, LowerHex, UpperHex |
✓ | ✓ | |||
| to_string | ToStringBase |
|||||
| from_string | FromStr |
✓ | ✓ | ✓ | ||
| from_string | FromStringBase |
✓ | ✓ | ✓ | ||
| from_sci_string | FromSciString |
|||||
| to_sci | ToSci |
|||||
| format_integer | format_integer_str, GmpFormatArg |
✓ | ||||
| latex | ToLatex |
|||||
| typst | ToTypst |
|||||
| serde | Serialize, Deserialize |
|||||
| pyo3 | FromPyObject, IntoPyObject |
Decimal output is checked by Azurite’s toString, GMP, and num. Input in every base is checked by
GMP and num, and by Azurite through a sign around the Natural digit rule (an optional -, then
the AzNat parse in Malachite’s rules, digits above 36 included), since AzInt.parse differs from
from_str on "-0" and on base prefixes; the binary, octal, and hexadecimal formatting traits by GMP and num, padding included.
to_string_base, scientific notation (from_sci_string, to_sci), and the formatting traits’
Azurite check through padded demos, all of which are checked by Azurite for Natural, are not yet
run for Integer. The GMP-style format_integer_str is compared with GMP’s own gmp_snprintf,
called directly. LaTeX, Typst, serde, and the Python bindings are not cross-checked.
Logic
From
malachite_nz::integer::logic. The bitwise operations act on the
two’s-complement representation, a negative Integer behaving as if it had infinitely many leading
1 bits.
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| and | BitAnd |
✓ | ✓ | |||
| or | BitOr |
✓ | ✓ | |||
| xor | BitXor |
✓ | ✓ | |||
| not | Not |
✓ | ||||
| bit_access | BitAccess::get_bit |
✓ | ||||
| bit_access | BitAccess::set_bit, clear_bit |
✓ | ||||
| bit_access | BitAccess::assign_bit, flip_bit |
✓ | ||||
| bit_block_access | BitBlockAccess::get_bits |
✓ | ||||
| bit_block_access | BitBlockAccess::assign_bits |
✓ | ||||
| bit_convertible | BitConvertible |
✓ | ||||
| bit_iterable | BitIterable |
|||||
| bit_scan | BitScan |
✓ | ✓ | |||
| checked_count_ones | checked_count_ones |
✓ | ||||
| checked_count_zeros | checked_count_zeros |
✓ | ||||
| checked_hamming_distance | CheckedHammingDistance |
✓ | ✓ | |||
| significant_bits | SignificantBits |
✓ | ✓ | ✓ | ||
| trailing_zeros | trailing_zeros |
✓ | ✓ | |||
| low_mask | LowMask |
✓ |
and, or, xor, not, the single-bit accessors, the bit scans, and the Hamming distance are
checked against GMP, whose bit functions use the same two’s-complement convention, and most of them against references that
work limb by limb or bit by bit. The population counts, which return None where the count is
infinite (checked_count_ones of a negative number, checked_count_zeros of a non-negative one),
and the bit-block and bit-vector conversions are checked against references alone. Azurite checks
significant_bits, trailing_zeros, and low_mask (AzInt.size, trailingZeros, and
lowMask). AzInt has no two’s-complement bit operations at all, so this
section is the largest gap between Azurite and Malachite’s Integer.
Factorization
From malachite_nz::integer::factorization.
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| is_power | IsPower |
✓ | ||||
| is_power | ExpressAsPower |
|||||
| remove_power | RemovePower |
✓ |
is_power, which for a negative Integer asks for an odd power, and remove_power are checked
against GMP. express_as_power, which returns a base and exponent rather than a yes or no, is
covered by property tests alone. Integer has no square test or prime functions; those belong to
Natural.
Exhaustive generation
From malachite_nz::integer::exhaustive.
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| exhaustive | exhaustive_integers |
|||||
| exhaustive | exhaustive_natural_integers, exhaustive_positive_integers, exhaustive_negative_integers |
|||||
| exhaustive | exhaustive_nonzero_integers |
|||||
| exhaustive | integer_increasing_range, integer_increasing_inclusive_range |
|||||
| exhaustive | integer_increasing_range_to_infinity, integer_decreasing_range_to_negative_infinity |
|||||
| exhaustive | exhaustive_integer_range, exhaustive_integer_inclusive_range |
|||||
| exhaustive | exhaustive_integer_range_to_infinity, exhaustive_integer_range_to_negative_infinity |
No exhaustive generator of Integer is cross-checked yet, but most of them are close: Azurite’s
ExhaustiveGenerator instances for AzInt (integersGen, the non-negative, positive, and
negative generators, the increasing and decreasing ranges, and azIntRangeGen and
azIntRangeInclusiveGen) produce the same sequences, each with a proof that every value occurs
exactly once, and only the demos and the oracle modes that compare them are missing.
exhaustive_nonzero_integers and the two half-bounded ranges in order of increasing absolute value
(exhaustive_integer_range_to_infinity and exhaustive_integer_range_to_negative_infinity) have
no Azurite counterpart. Malachite’s own tests compare prefixes with fixed
expected values and check that ranges contain exactly what they should.
Random generation
From malachite_nz::integer::random.
| Operation | Functions | Azurite | FLINT | GMP | num | Reference |
|---|---|---|---|---|---|---|
| random | random_integers, random_natural_integers, random_positive_integers, random_negative_integers, random_nonzero_integers |
|||||
| random | striped_random_integers, striped_random_natural_integers, striped_random_positive_integers, striped_random_negative_integers, striped_random_nonzero_integers |
|||||
| random | uniform_random_integer_range, uniform_random_integer_inclusive_range, random_integer_range, random_integer_inclusive_range, random_integer_range_to_infinity, random_integer_range_to_negative_infinity |
|||||
| random | striped_random_integer_range, striped_random_integer_inclusive_range, striped_random_integer_range_to_infinity, striped_random_integer_range_to_negative_infinity |
|||||
| random | get_uniform_random_integer_from_range, get_random_integer_from_range_to_infinity, and the other get_* functions |
Random generators have no independent oracle in the sense of this page: what they produce depends on Malachite’s own seeded generator, so another library cannot reproduce it. They are tested instead by pinning the first values for fixed seeds and by comparing the distribution of a large sample (its most common values, mean, standard deviation, skewness, and excess kurtosis) with the values the distribution should have, which catches a biased or truncated generator.
What is not yet cross-checked
The rows above with no mark, and the rows with no Azurite mark, sort into three groups by what it would take to give them a verified oracle. Within each group the most widely used functions come first.
Azurite already computes these; the oracle only needs a mode for them. The comparisons with a
Natural and with the primitive integers in the reverse direction (5 < x), from the same
compareAzNat, compareUInt64, and compareInt64; the truncating quotient / and
checked_div, from AzInt.divRound in the Down mode; the exhaustive generators listed above;
and the functions whose Natural versions are already checked, through oracle code that would
only add a sign: the conversions to and from f32 and f64 (through AzFloat.ofAzInt,
AzFloat.toFloat64, and AzRat.round), to_string_base, the formatting traits with a width,
from_sci_string, and to_sci.
A few lines of oracle code around Azurite functions. These need no new Azurite function, but
the oracle would compose existing ones, so the composition itself is unverified code: abs (the
magnitude as an AzInt), square, abs_squared, abs_diff, average and average_round,
the fused operations (add_mul, sub_mul, mul_add_mul, mul_sub_mul), shl_round,
mul_shr_round, round_to_multiple and round_to_multiple_of_power_of_2; the remainders and
ceiling forms of division (div_rem, rem, ceiling_div_mod, ceiling_mod), divisible_by,
eq_mod, balanced_mod, and DivModPrecomputed; rem_power_of_2, ceiling_mod_power_of_2,
eq_mod_power_of_2, and divisible_by_power_of_2 (from AzZModPow2.ofAzInt and
trailingZeros); the roots (AzNat.sqrtRem and rootInt on the magnitude, the sign restored for
odd roots); extended_gcd (Azurite’s egcd on the magnitudes, with the signs of the Bézout
coefficients adjusted, and ≈ for the reason given on the naturals
page); the Jacobi and Legendre symbols (jacobi
of the residue); balanced_crt and multi_balanced_crt (Azurite’s Garner algorithm, then a shift
into the balanced range); the conversions to Natural and to the primitives that reject, clamp, or
flag; the absolute-value comparisons (natAbs and a comparison); the two’s-complement limbs (the
low limb of each floor shift, toUInt64 (z >>> 64i)); the single-bit functions and get_bits
(floor shifts, parity, ofAzInt modulo a power of 2, and adding or subtracting a power of 2); and
Clone.
Azurite would need new functions. These are the operations whose absence from Azurite is the real gap, in rough order of how much of Malachite they would cover:
- The two’s-complement bitwise operations on
AzInt(and,or,xor, andnot), and with them the population counts, the Hamming distance, the bit scans, bit iteration, conversion to and from bit vectors, andassign_bits. As withNatural, this is the largest gap. - The combinatorial functions: the binomial coefficient with a negative argument, and the falling and rising factorials. All are checked against GMP, FLINT, or a reference, but none against a proven implementation.
- The Kronecker symbol, which extends the Jacobi symbol to even and negative denominators.
- Perfect-power detection and decomposition (
is_power,express_as_power) andremove_power. - The exhaustive generators without a counterpart:
exhaustive_nonzero_integersand the half-bounded ranges in order of increasing absolute value.
Outside the scope of an oracle. The constants, Default, Named, Hash, mutate_unsigned_abs,
the unit functions (is_unit, conjugate, canonicalize_unit, canonical_unit_i_pow),
IsInteger, IsReal, IsGaussianInteger, From<bool>, const_from_unsigned and
const_from_signed, the GMP-style format_integer_str, LaTeX and Typst output, serde, the Python
bindings, and the random generators. Most are trivial or are checked by other means; the rest have
no independent implementation to compare with, and are tested by their own unit and property tests,
the random generators by the distribution of large samples.