FLINT3.7.0-dev
Module · 182 functions

radix.h

#include <flint/radix.h>

This module implements multiprecision natural number and integer arithmetic in a general radix B<βB < \beta, where β=2FLINT_BITS\beta = 2^{\mathtt{FLINT\_BITS}} is the machine word radix. The radix is a power B=beB = b^e of a digit radix b≥2b \ge 2, so that one limb holds ee digits; for decimal arithmetic one normally takes B=1019B = 10^{19} on 64-bit machines (10910^9 on 32-bit machines), the largest power of 10 below β\beta.

Arithmetic in radix BB is somewhat slower than in the radix β\beta, but everything related to the base bb becomes cheap: reduction modulo bnb^n, truncation to nn digits, shifts by digits and conversion to a string in base bb take time O(n)O(n) instead of O(M(n))O(M(n)) or O(M(n)log⁡n)O(M(n) \log n). The two principal applications are decimal arithmetic (b=10b = 10, see the decimal module) and pp-adic arithmetic (b=pb = p a small prime, with Hensel division and pp-adic square roots; see the padic_radix module).

The module provides low-level functions on limb arrays (in the style of mpn_extras), conversion between radix BB and the binary radix β\beta in quasi-linear time, which flint_mpn_get_str uses for decimal output, and a memory-managed signed integer type radix_integer_t with a generic ring (gr) context. The functions are not optimised for bb a power of two, where binary arithmetic should be used. The guide Arithmetic in radix b^e shows how to use the module; Converting between radix B and binary describes the conversions to and from binary.

Guides#

Radix objects#

A radix context, holding the digit radix bb and the limb radix B=beB = b^e as nmod_t values (fields b and B), the exponent exp =e= e, and precomputed data: the powers bkb^k for 0≤k≤e0 \le k \le e, data for division by these powers (n_div_precomp_t), data for division by ee (see radix_div_exp), the 2-adic valuation of bb, inverses of the powers of the odd part of bb, and a function computing digit valuations. A radix_t is passed by reference to every function of the module.

LIMB_RADIX(radix)

The digit radix bb and the limb radix BB of a radix_t, as ulong.

Return ⌊x/e⌋\lfloor x / e \rfloor (and set r=x mod er = x \bmod e), converting a number of digits to a number of limbs without a hardware division. For e>2e > 2 this is one multiplication by a precomputed ⌈2FLINT_BITS−2+ℓ/e⌉\lceil 2^{\mathtt{FLINT\_BITS} - 2 + \ell} / e \rceil, ℓ=⌈log⁡2e⌉\ell = \lceil \log_2 e \rceil, and a shift, exact for x<2FLINT_BITS−2x < 2^{\mathtt{FLINT\_BITS} - 2}; larger xx use n_div_precomp.

void radix_init(radix_t radix, ulong b, unsigned int exp)

Initialises radix with digit radix bb and limb radix B=beB = b^e where ee = exp. Requires b≥2b \ge 2, e<FLINT_BITSe < \mathtt{FLINT\_BITS} and be<βb^e < \beta, and throws an exception otherwise. With e=0e = 0, the largest ee with be<βb^e < \beta is chosen.

void radix_clear(radix_t radix)

Frees the memory used by radix.

Initialise radix with a random digit radix bb (a random prime bb for the second function) and a random exponent, for testing.

Return bb, BB and ee.

Natural numbers#

The low-level functions work on arrays of limbs (ulong), with the same notation as in mpn_extras: (x,n)(x, n) is the natural number ∑i<nxiBi\sum_{i<n} x_i B^i in [0,Bn−1][0, B^n - 1]. Unless stated otherwise:

  • input limbs must be reduced to [0,B−1][0, B - 1], and output limbs are reduced;
  • aliasing between outputs and inputs is allowed only if the aliased operands start at the same address;
  • normalised means that the top limb is nonzero.

Return the number of digits of the limb cc (the least kk with c<bkc < b^k). The underscore version requires c>0c > 0; the other returns 0 for c=0c = 0.

Return the number of digits of (x,n)(x, n). The underscore version requires n>0n > 0 and xn−1≠0x_{n-1} \ne 0; the other allows n=0n = 0 and zero top limbs, which it skips, and returns 0 for zero.

Returns the number of trailing zero digits of the limb c>0c > 0, that is, the largest kk such that bkb^k divides cc.

void radix_rand_limbs(nn_ptr res, flint_rand_t state, slong n, const radix_t radix)
void radix_rand_digits(nn_ptr res, flint_rand_t state, slong n, const radix_t radix)

Set (res,n)(\mathit{res}, n) to a uniformly random integer in [0,Bn−1][0, B^n - 1], respectively (res,⌈n/e⌉)(\mathit{res}, \lceil n/e \rceil) to a uniformly random integer in [0,bn−1][0, b^n - 1].

void radix_randtest_limbs(nn_ptr res, flint_rand_t state, slong n, const radix_t radix)
void radix_randtest_digits(nn_ptr res, flint_rand_t state, slong n, const radix_t radix)

Like radix_rand_limbs and radix_rand_digits, but with a non-uniform distribution producing long runs of limbs equal to 0 or B−1B - 1, for testing.

Addition and shifts#

ulong radix_add(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, const radix_t radix)
ulong radix_sub(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, const radix_t radix)

Set (res,an)(\mathit{res}, \mathit{an}) to a+ba + b, respectively a−ba - b, modulo BanB^{an} and return the carry, respectively the borrow (0 or 1). Requires an≥bn≥1\mathit{an} \ge \mathit{bn} \ge 1.

ulong radix_neg(nn_ptr res, nn_srcptr a, slong an, const radix_t radix)

Sets (res,an)(\mathit{res}, \mathit{an}) to the BB-complement (−a) mod Ban(-a) \bmod B^{an} and returns the borrow (1 if a≠0a \ne 0, 0 otherwise).

ulong radix_lshift_digits(nn_ptr res, nn_srcptr a, slong n, unsigned int e, const radix_t radix)
ulong radix_rshift_digits(nn_ptr res, nn_srcptr a, slong n, unsigned int e, const radix_t radix)

Shift (a,n)(a, n) by kk = e digits, for 1≤k1 \le k less than the limb exponent: the left shift sets (res,n)(\mathit{res}, n) to abk mod Bna b^k \bmod B^n and returns the kk digits shifted out (as the low digits of the returned limb); the right shift sets (res,n)(\mathit{res}, n) to ⌊a/bk⌋\lfloor a / b^k \rfloor and returns the kk digits shifted out as the high digits of the returned limb, that is, (a mod bk)be−k(a \bmod b^k) b^{e - k}. These are faster than radix_mul_1 and radix_divrem_1 with bkb^k. Shifts by whole limbs are pointer offsets.

ulong radix_addlsh(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, unsigned int sh, const radix_t radix)
ulong radix_sublsh(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, unsigned int sh, const radix_t radix)
ulong radix_lshsub(nn_ptr res, nn_srcptr b, slong bn, unsigned int sh, nn_srcptr a, slong an, const radix_t radix)

Fused addition and subtraction with a shift of bb by 1≤sh<e1 \le \mathit{sh} < e digits: set (res,L)(\mathit{res}, L) with L=max⁡(an,bn+1)L = \max(\mathit{an}, \mathit{bn} + 1) to a+b⋅bsha + b \cdot b^{\mathit{sh}}, a−b⋅bsha - b \cdot b^{\mathit{sh}} and b⋅bsh−ab \cdot b^{\mathit{sh}} - a, and return the carry (0 or 1), respectively the borrow, which is 0 since the result must be nonnegative. Requires bn≥1\mathit{bn} \ge 1. res may alias aa but not bb. The shifted operand is never formed in memory.

int radix_cmplsh(nn_srcptr a, slong an, nn_srcptr b, slong bn, unsigned int sh, const radix_t radix)

Returns the sign of a−b⋅bsha - b \cdot b^{\mathit{sh}} for normalised (a,an)(a, \mathit{an}) and (b,bn)(b, \mathit{bn}) and 1≤sh<e1 \le \mathit{sh} < e.

Multiplication#

ulong radix_mul_1(nn_ptr res, nn_srcptr a, slong n, ulong c, const radix_t radix)

Sets (res,n)(\mathit{res}, n) to ac mod Bnac \bmod B^n and returns the carry ⌊ac/Bn⌋\lfloor ac / B^n \rfloor. Requires n≥1n \ge 1 and c<Bc < B.

ulong radix_mul_two(nn_ptr res, nn_srcptr a, slong an, const radix_t radix)

Sets (res,an)(\mathit{res}, \mathit{an}) to 2a mod Ban2a \bmod B^{an} and returns the carry.

void radix_mul(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, const radix_t radix)
void radix_sqr(nn_ptr res, nn_srcptr a, slong an, const radix_t radix)

Set (res,an+bn)(\mathit{res}, \mathit{an} + \mathit{bn}) to abab, respectively (res,2an)(\mathit{res}, 2\mathit{an}) to a2a^2. Requires an,bn≥1\mathit{an}, \mathit{bn} \ge 1; res must not overlap the inputs. Both are calls to radix_mulmid with the full window (there is no special squaring code yet).

void radix_mulmid(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong lo, slong hi, const radix_t radix)

Windowed product: for an,bn≥1\mathit{an}, \mathit{bn} \ge 1 and 0≤lo<hi≤an+bn0 \le \mathit{lo} < \mathit{hi} \le \mathit{an} + \mathit{bn}, sets (res,hi−lo)(\mathit{res}, \mathit{hi} - \mathit{lo}) to the limbs [lo,hi)[\mathit{lo}, \mathit{hi}) of the product, computed without the carries from the limbs below lo\mathit{lo}. res must not overlap the inputs.

More
void radix_mulmid_classical(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong lo, slong hi, const radix_t radix)
void radix_mulmid_fft_small(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong lo, slong hi, const radix_t radix)
void radix_mulmid_KS(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong lo, slong hi, const radix_t radix)
void radix_mulmid_naive(nn_ptr res, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong lo, slong hi, const radix_t radix)

The algorithms behind radix_mulmid, with its interface: the schoolbook algorithm with delayed reduction of the column sums, efficient when an operand or the window is short; multiplication of the limb sequences as polynomials with the small-prime FFT of fft_small (only available if FLINT is built with it), reconstructing only the coefficients that reach the window and propagating carries in radix BB; Kronecker substitution into one product in the binary radix β\beta (each limb padded to two words); and an unoptimised reference implementation through fmpz_poly.

More

Returns the number of pairs (i,j)(i, j) with 0≤i<an0 \le i < \mathit{an}, 0≤j<bn0 \le j < \mathit{bn} and i+j<ki + j < k, as a double (it may exceed the range of slong on 32-bit machines). It counts the limb products of the classical algorithm and is used for tuning decisions.

The tuning ratio of radix_mulmid. With fft_small it is FLINT_RADIX_MULMID_FFT_SMALL_CUTOFF_RATIO, which every flint-mparam.h must define: 50 on Zen 3 and Zen 4, 60 on Ice Lake and later Intel cores and in the generic files, 80 on Skylake and Broadwell, 85 on arm64 (measured on Apple M4). The measured crossover is the same for balanced full products, Newton middle products and short windows of a long operand; a balanced full product of nn limbs switches to the FFT at n=2⋅n = 2 \cdot ratio, 100 to 170 limbs. Without fft_small the ratio is 175 (Kronecker substitution pads each limb to two words, so the crossover for a balanced full product is at about 350 limbs).

The length of the convolution that radix_mulmid_fft_small computes for the window [lo,hi)[\mathit{lo}, \mathit{hi}), used by radix_mulmid to choose the algorithm: with an′\mathit{an}' and bn′\mathit{bn}' the numbers of limbs of the operands that reach the window, it is min⁡(an′,bn′)+(hi′−lo′)\min(\mathit{an}', \mathit{bn}') + (\mathit{hi}' - \mathit{lo}') if the window (clipped to the product) is shorter than max⁡(an′,bn′)\max(\mathit{an}', \mathit{bn}'), and an′+bn′\mathit{an}' + \mathit{bn}' otherwise; 0 for an empty window.

void _radix_mulhigh_known_low(nn_ptr out, nn_srcptr x, slong xn, nn_srcptr y, slong yn, nn_srcptr kl, slong kl_len, slong klo, slong khi, nn_ptr scratch, const radix_t radix)

The radix BB analogue of _flint_mpn_mulhigh_known_low: sets (out,khi−klo)(\mathit{out}, \mathit{khi} - \mathit{klo}) to the exact limbs [klo,khi)[\mathit{klo}, \mathit{khi}) of xyxy, given that its low klo\mathit{klo} limbs are (kl,kl_len)(\mathit{kl}, \mathit{kl\_len}) (zero above kl_len), using a windowed product with guard limbs. scratch must have room for khi\mathit{khi} limbs. Used by the Hensel division and pp-adic square roots.

Division#

Division in radix BB follows the structure of the binary case: small divisors are handled directly, large ones by Newton iteration on fixed-point approximations of the reciprocal, and medium sizes by converting to binary and using flint_mpn_tdiv_qr.

ulong radix_divrem_1(nn_ptr res, nn_srcptr a, slong an, ulong d, const radix_t radix)
void radix_divexact_1(nn_ptr res, nn_srcptr a, slong an, ulong d, const radix_t radix)

Set (res,an)(\mathit{res}, \mathit{an}) to ⌊a/d⌋\lfloor a/d \rfloor and return the remainder, for 1≤d<B1 \le d < B; the same assuming that dd divides aa (the result is undefined otherwise); and division by 2.

void radix_inv_approx(nn_ptr q, nn_srcptr a, slong an, slong n, const radix_t radix)

Given (a,an)(a, \mathit{an}) with aan−1≠0a_{an-1} \ne 0, read as a fixed-point number a∈[1/B,1)a \in [1/B, 1) with an\mathit{an} fraction limbs, set (q,n+2)(q, n + 2) to an approximation of 1/a∈(1,B]1/a \in (1, B] with nn fraction limbs and two integral limbs (the top one may be zero). The absolute error is less than 4B−n/a4 B^{-n}/a (relative error less than 4B−n4 B^{-n}). The general version uses Newton iteration from the basecase.

void radix_div_approx(nn_ptr Q, nn_srcptr B, slong Bn, nn_srcptr A, slong An, slong n, const radix_t radix)

Given the divisor (A,An)(A, \mathit{An}) with nonzero top limb, read as a fixed-point number in [1/B,1)[1/B, 1) with An≥1\mathit{An} \ge 1 fraction limbs, and the dividend (B,Bn)(B, \mathit{Bn}), read as a fixed-point number in [0,1)[0, 1) with Bn≥1\mathit{Bn} \ge 1 fraction limbs, set (Q,n+2)(Q, n + 2) to an approximation of the quotient with nn fraction limbs and two integral limbs; the absolute error is less than 4B−n4 B^{-n} divided by the divisor. Note the order of the arguments: the dividend comes first. The invmul version multiplies by an approximate reciprocal; the general version uses Karp–Markstein iteration [KM1997].

void radix_divrem(nn_ptr q, nn_ptr r, nn_srcptr a, slong an, nn_srcptr b, slong bn, const radix_t radix)

Sets (q,an−bn+1)(q, \mathit{an} - \mathit{bn} + 1) to ⌊a/b⌋\lfloor a/b \rfloor and, if rr is not NULL, (r,bn)(r, \mathit{bn}) to the remainder. Requires an≥bn≥1\mathit{an} \ge \mathit{bn} \ge 1 and bbn−1≠0b_{bn-1} \ne 0.

More
void radix_divrem_via_mpn(nn_ptr q, nn_ptr r, nn_srcptr a, slong an, nn_srcptr b, slong bn, const radix_t radix)
void radix_divrem_newton(nn_ptr q, nn_ptr r, nn_srcptr a, slong an, nn_srcptr b, slong bn, const radix_t radix)

The algorithms behind radix_divrem, with its interface: conversion to binary, division by a Newton reciprocal, and Karp–Markstein division (quotient from a half-precision reciprocal and one correction step).

void radix_divrem_preinv(nn_ptr q, nn_ptr r, nn_srcptr a, slong an, nn_srcptr b, slong bn, nn_srcptr binv, slong binvn, const radix_t radix)

radix_divrem with a precomputed inverse of bb given as (binv,binvn+2)(\mathit{binv}, \mathit{binvn} + 2) with binvn\mathit{binvn} fraction limbs, as computed by radix_inv_approx. Requires binvn≥an−bn+1\mathit{binvn} \ge \mathit{an} - \mathit{bn} + 1; a few extra limbs can improve performance. rr may be NULL.

int radix_div(nn_ptr q, nn_srcptr a, slong an, nn_srcptr b, slong bn, const radix_t radix)

If bb divides aa, sets (q,an−bn+1)(q, \mathit{an} - \mathit{bn} + 1) to the quotient and returns 1; otherwise returns 0, the contents of qq being undefined.

void radix_divexact(nn_ptr q, nn_srcptr a, slong an, nn_srcptr b, slong bn, const radix_t radix)

Sets (q,an−bn+1)(q, \mathit{an} - \mathit{bn} + 1) to a/ba/b, assuming that the division is exact; the result is undefined otherwise.

int radix_cmp_bn_half(nn_srcptr x, slong n, const radix_t radix)

Returns −1-1, 0 or 1 according to whether (x,n)(x, n) is less than, equal to or greater than ⌊Bn/2⌋\lfloor B^n/2 \rfloor. Requires n≥1n \ge 1. Used for rounding to nearest and for symmetric remainders.

Square roots#

void radix_sqrtrem(nn_ptr s, nn_ptr r, nn_srcptr a, slong an, const radix_t radix)

Sets (s,⌈an/2⌉)(s, \lceil \mathit{an}/2 \rceil) to ⌊a⌋\lfloor \sqrt a \rfloor and, if rr is not NULL, (r,⌈an/2⌉+1)(r, \lceil \mathit{an}/2 \rceil + 1) to the remainder a−s2≤2sa - s^2 \le 2s. Requires an≥1\mathit{an} \ge 1 and aan−1≠0a_{an-1} \ne 0. Inputs shorter than a cutoff depending on the size of BB (43 limbs for B=1019B = 10^{19}) are converted to binary and use flint_mpn_sqrtrem; longer ones use the Newton square root.

int radix_sqrt(nn_ptr s, nn_srcptr a, slong an, const radix_t radix)

Sets (s,⌈an/2⌉)(s, \lceil \mathit{an}/2 \rceil) to ⌊a⌋\lfloor \sqrt a \rfloor and returns 1 if aa is a perfect square and 0 otherwise. Requires an≥1\mathit{an} \ge 1 and aan−1≠0a_{an-1} \ne 0.

void radix_sqrtrem_via_mpn(nn_ptr s, nn_ptr r, nn_srcptr a, slong an, const radix_t radix)

The algorithms behind radix_sqrtrem, with its interface: conversion to binary, and the root from a reciprocal square root by one Karp–Markstein step, with a final correction.

void radix_rsqrt_1_approx(nn_ptr res, ulong a, slong n, const radix_t radix)

Set (res,n)(\mathit{res}, n) to the fraction limbs of an approximation of 1/a1/\sqrt a for 2≤a<B2 \le a < B, with error less than 2B−n2 B^{-n}.

void radix_rsqrt_approx(nn_ptr q, nn_srcptr a, slong an, slong n, const radix_t radix)

Given (a,an)(a, \mathit{an}) read as a fixed-point number a∈[B−2,1)a \in [B^{-2}, 1) with an\mathit{an} fraction limbs (one of the top two limbs nonzero), set (q,n+2)(q, n + 2) to an approximation of 1/a∈(1,B]1/\sqrt a \in (1, B] with nn fraction limbs and two integral limbs, with absolute error less than 4B−n/a4 B^{-n}/\sqrt a. The range of aa is wider than for radix_inv_approx so that inputs with an odd number of limbs can be handled, the scale factor B1/2B^{1/2} not being a limb shift.

void radix_sqrt_approx(nn_ptr q, nn_srcptr a, slong an, slong n, const radix_t radix)

With aa as for radix_rsqrt_approx, set (q,n+2)(q, n + 2) to an approximation of a∈[1/B,1)\sqrt a \in [1/B, 1) with nn fraction limbs and two integral limbs (normally zero, though the value can round up to 1), with absolute error less than 4B−n/a4 B^{-n}/\sqrt a. The error is proportional to 1/a1/\sqrt a rather than to a\sqrt a, because the corrections of the last iteration are multiplied by an approximation of 1/a≤B1/\sqrt a \le B.

Hensel division and pp-adic square roots#

Arithmetic modulo BnB^n, developing results from the least significant limb upwards. For b=pb = p prime this is arithmetic in Zp\mathbb{Z}_p with precision nene digits. mpn_extras has ports of these algorithms to the binary radix (Hensel division and 2-adic square roots).

int radix_invmod_bn(nn_ptr res, nn_srcptr x, slong xn, slong n, const radix_t radix)

If (x,xn)(x, \mathit{xn}) is invertible modulo BnB^n (that is, x0x_0 is coprime to bb), sets (res,n)(\mathit{res}, n) to its inverse and returns 1; otherwise returns 0. Newton iteration on windowed products.

int radix_divmod_bn(nn_ptr q, nn_ptr rem, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong n, const radix_t radix)

Given (b,bn)(b, \mathit{bn}) invertible modulo BB, sets (q,n)(q, n) to the BB-adic (Hensel) quotient with qb≡a(modBn)qb \equiv a \pmod{B^n} and returns 1; returns 0 if bb is not invertible. If rem is not NULL, the remainder (a−qb)/Bn mod Bbn(a - qb)/B^n \bmod B^{bn} is written to (rem,bn)(\mathit{rem}, \mathit{bn}), so that a≡qb+Bnrem(modBn+bn)a \equiv qb + B^n \mathit{rem} \pmod{B^{n + bn}}.

int radix_divmod_bn_1(nn_ptr q, nn_ptr rem, nn_srcptr a, slong an, ulong b, slong n, const radix_t radix)

The algorithms behind radix_divmod_bn, with its interface: a one-limb divisor (with rem of one limb), the blockwise algorithm (one low and one high product per block of bn\mathit{bn} limbs), and the Karp–Markstein form with a half-precision inverse.

int radix_sqrtmod_bn(nn_ptr res, nn_srcptr x, slong xn, slong n, const radix_t radix)
int radix_rsqrtmod_bn(nn_ptr res, nn_srcptr x, slong xn, slong n, const radix_t radix)

For a prime digit radix pp (with e≥3e \ge 3 if p=2p = 2): if (x,xn)(x, \mathit{xn}) is a unit and a square modulo pp (modulo 8 if p=2p = 2), set (res,n)(\mathit{res}, n) to a square root of xx modulo BnB^n, respectively to the inverse of that square root, and return 1; otherwise return 0. The square root returned is the one whose residue modulo pp is the smallest nonnegative one.

Radix conversion#

Conversion between radix BB and the binary radix β\beta in time O(M(n)log⁡n)O(M(n) \log n) by divide and conquer, with multiplications only (no divisions). See Converting between radix B and binary and Radix conversion.

slong radix_get_mpn(nn_ptr res, nn_srcptr a, slong an, const radix_t radix)

Convert (a,an)(a, \mathit{an}) from radix BB to the binary radix, writing the limbs to res and returning the normalised length of the result. Leading zero limbs are not counted and may or may not be written. res must have room for the largest integer with an\mathit{an} limbs in radix BB, plus one extra limb, and must not overlap aa. The basecase is Horner's rule (used below 50 limbs).

Full documentation
slong radix_set_mpn(nn_ptr res, nn_srcptr a, slong an, const radix_t radix)

Convert the binary (a,an)(a, \mathit{an}) to radix BB, writing the limbs to res and returning the normalised length of the result. res must have room for radix_set_mpn_need_alloc(an, radix) limbs and must not overlap aa. The basecase is repeated division by BB (used below 40 limbs). The divide and conquer version caches the most recently used table of powers (per thread), so that repeated conversions of inputs of the same size, as when printing many numbers, do not recompute it.

Full documentation

Returns a number of output limbs that is sufficient for radix_set_mpn with an input of nn limbs.

A table of the powers ck0,ck1,…c^{k_0}, c^{k_1}, \ldots used by the divide and conquer conversions, with k0k_0 the top exponent and ki+1=⌈ki/2⌉k_{i+1} = \lceil k_i/2 \rceil down to 1, together with their lengths and their numbers of trailing zero limbs.

Frees a table of powers.

String conversion#

char * radix_get_str_decimal(char * res, nn_srcptr x, slong n, int negative, const radix_t radix)

Returns the decimal representation of (x,n)(x, n) as a null-terminated string, with a leading minus sign if negative is 1; for n=0n = 0 the string is 0. The top limb must be nonzero (if n>0n > 0). If res is NULL, a new string is allocated with flint_malloc; otherwise res must have room for the result and the terminating null. If b=10b = 10, this takes time O(n)O(n) (each limb is printed with table lookups for pairs of digits); otherwise xx is converted to binary and then to decimal, in time O(M(n)log⁡n)O(M(n) \log n).

char * radix_get_str_sum(char * res, nn_srcptr x, slong n, int negative, int ascending, const radix_t radix)

Returns (x,n)(x, n) written as a sum over its limbs. For example, 12345678 in radix 10310^3 is printed as 12 * 10^6 + 345 * 10^3 + 678 with negative and ascending both 0, and as -(678 + 345 * 10^3 + 12 * 10^6) with both 1. Memory as for radix_get_str_decimal.

Integers#

A signed integer in radix BB, in a format similar to mpz_t: the fields are d (pointer to the limbs), alloc (the number of allocated limbs) and size, whose absolute value is the normalised number of limbs and whose sign is the sign of the integer. The radix is not stored and must be passed to every function.

void gr_ctx_init_radix_integer(gr_ctx_t ctx, ulong b, unsigned int exp)

Initialises ctx as the generic ring of integers in radix beb^e (with e=0e = 0 selecting the largest admissible exponent), whose elements are radix_integer_t. The context owns its radix_t.

Initialise to zero and free an integer, and make sure that it has room for nlimbs limbs, returning the pointer to its limbs (which the caller may then fill, setting size accordingly).

Returns whether all limbs of xx are reduced modulo BB and the top limb is nonzero. Operations on a non-normalised integer have undefined behaviour.

void radix_integer_set_fmpz(radix_integer_t res, const fmpz_t x, const radix_t radix)
void radix_integer_get_fmpz(fmpz_t res, const radix_integer_t x, const radix_t radix)

Assignment and conversion; radix_integer_set_fmpz and radix_integer_get_fmpz use the radix conversion functions.

void radix_integer_rand_limbs(radix_integer_t res, flint_rand_t state, slong max_limbs, const radix_t radix)
void radix_integer_randtest_limbs(radix_integer_t res, flint_rand_t state, slong max_limbs, const radix_t radix)

Set res to a random signed integer of at most max_limbs limbs, with a uniform respectively a test distribution of the limbs.

int radix_integer_is_one(const radix_integer_t x, const radix_t radix)
int radix_integer_equal(const radix_integer_t x, const radix_integer_t y, const radix_t radix)
int radix_integer_cmp(const radix_integer_t x, const radix_integer_t y, const radix_t radix)
int radix_integer_cmpabs(const radix_integer_t x, const radix_integer_t y, const radix_t radix)
int radix_integer_sgn(const radix_integer_t x, const radix_t radix)

Predicates and comparisons; cmp and cmpabs return the sign of x−yx - y and ∣x∣−∣y∣|x| - |y|.

The number of limbs, respectively digits, of ∣x∣|x|; the ssize versions return it negated if xx is negative.

Return the limb, respectively the digit, of ∣x∣|x| at the given nonnegative position (zero beyond the top).

void radix_integer_set_limb(radix_integer_t res, const radix_integer_t x, slong index, ulong c, const radix_t radix)
void radix_integer_set_digit(radix_integer_t res, const radix_integer_t x, slong index, ulong c, const radix_t radix)

Set res to xx with the limb (digit) at the nonnegative position index of ∣x∣|x| replaced by c<Bc < B (c<bc < b). The sign of xx is kept; if xx is zero and cc nonzero, the result is positive.

Negation, absolute value, sum, difference and product.

Set res to xBnx B^n (xbnx b^n), respectively to x/Bnx / B^n (x/bnx / b^n) truncated towards zero, for n≥0n \ge 0.

Set res to x+ybvx + y b^v, respectively x−ybvx - y b^v, for any digit shift v≥0v \ge 0, without forming the shifted operand: the shift is split into whole limbs (a pointer offset) and v mod ev \bmod e digits (the fused radix_addlsh family). Any aliasing is allowed.

Return the largest nn such that BnB^n (respectively bnb^n) divides xx, that is, the number of trailing zero limbs (digits); 0 for x=0x = 0.

Reductions modulo BnB^n (respectively bnb^n): trunc reduces ∣x∣|x| and keeps the sign of xx; mod returns the representative in [0,Bn−1][0, B^n - 1] ([0,bn−1][0, b^n - 1]); smod returns the symmetric representative, in [−⌊Bn/2⌋,⌊Bn/2⌋][-\lfloor B^n/2 \rfloor, \lfloor B^n/2 \rfloor] for odd BB and in [−Bn/2,Bn/2−1][-B^n/2, B^n/2 - 1] for even BB. These take time O(n)O(n) plus the time to copy.

Sets res to xyxy with the absolute value reduced modulo BnB^n, using a low product.

Inverse, quotient a/ba/b, inverse square root and square root modulo BnB^n, by radix_invmod_bn, radix_divmod_bn, radix_rsqrtmod_bn and radix_sqrtmod_bn applied to the absolute values; the sign of the inputs is carried over to the result. Return 1 on success and 0 if the operand is not invertible (respectively not a square).

If bb divides aa, radix_integer_div sets qq to a/ba/b and returns 1; otherwise it sets qq to zero and returns 0. radix_integer_divexact sets qq to a/ba/b assuming that the division is exact (the result is undefined otherwise).

Division with remainder a=qb+ra = qb + r, where the quotient is rounded towards zero (tdiv), towards −∞-\infty (fdiv) or towards +∞+\infty (cdiv), as in GMP's mpz functions. bb must be nonzero.

xx is invertible in Z\mathbb{Z} if and only if x=±1x = \pm 1. radix_integer_inv sets res to 1/x=x1/x = x and returns 1 in that case and returns 0 otherwise.

radix_integer_sqrt sets ss to ⌊x⌋\lfloor \sqrt x \rfloor and returns 1 if xx is a perfect square and 0 otherwise; for negative xx it returns 0 without modifying ss. radix_integer_sqrtrem sets ss and the remainder r=x−s2r = x - s^2, and throws an exception for negative xx. radix_integer_is_square returns whether xx is a perfect square (0 for negative xx).

Division by an invariant word#

The following inline functions divide words by a fixed word d≥1d \ge 1 with a precomputed multiplier, by the method of Granlund and Montgomery [GraMon1994] in the variant of Robison [Rob2005] that needs no multiplier wider than a word. They are used for the digit shifts of this module, where dd is a power of bb.

Precomputed data for division by dd: the exponent ℓ=⌊log⁡2d⌋\ell = \lfloor \log_2 d \rfloor (field e), a multiplier m and a flag c. If dd is a power of two, m=0m = 0. Otherwise, with q=⌊2ℓ+FLINT_BITS/d⌋q = \lfloor 2^{\ell + \mathtt{FLINT\_BITS}}/d \rfloor, either m=q+1m = q + 1 and c=0c = 0 (the round-up method, when it is exact for all words) or m=qm = q and c=1c = 1 (the round-down method with an increment).

A pair of words (fields a and b).

Computes the data for division by d≥1d \ge 1.

Return ⌊x/d⌋\lfloor x/d \rfloor for any word xx: n_div_precomp selects the method from pre, and the other functions are the individual methods for callers that know the case: x≫ℓx \gg \ell for a power of two (m=0m = 0), ⌊xm/2FLINT_BITS⌋≫ℓ\lfloor xm / 2^{\mathtt{FLINT\_BITS}} \rfloor \gg \ell for c=0c = 0, and ⌊(x+1)m/2FLINT_BITS⌋≫ℓ\lfloor (x + 1) m / 2^{\mathtt{FLINT\_BITS}} \rfloor \gg \ell for c=1c = 1, where x+1x + 1 saturates at β−1\beta - 1. The bounded versions require x≠β−1x \ne \beta - 1 and skip the saturation.

The remainder x mod dx \bmod d, and the quotient with the remainder stored in *r, with the same variants as the quotient functions.

Returns x+1x + 1, or xx if x=β−1x = \beta - 1 (saturating increment).

References#

  • [KM1997] A. H. Karp and P. Markstein, "High-precision division and square root", ACM Transactions on Mathematical Software 23:4 (1997), 561–589
  • [GraMon1994] Törbjorn Granlund and Peter L. Montgomery : Division by Invariant Integers using Multiplication https://gmplib.org/~tege/divcnst-pldi94.pdf
  • [Rob2005] A. D. Robison. N-bit unsigned division via N-bit multiply-add. Proceedings of the 17th IEEE Symposium on Computer Arithmetic (ARITH-17), 2005, 131–139.
Cite this page

The FLINT team, “radix.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/radix/index.html (generated 2026-11-02).