FLINT3.7.0-dev

Choosing types

FLINT usually has more than one type for a given mathematical object. The integers modulo n alone can be ulong residues with an nmod_t, fmpz residues with an fmpz_mod_ctx_t, fixed-length limb arrays in an mpn_mod context, or elements of any of these through the generic interface gr. The types differ in the range of parameters they accept, in speed (often by large factors for small inputs), in the functionality that exists for them, and in how they are called. The sections below give the general principles and tables of the types by domain, with their limits.

General principles#

Use the narrowest representation that fits. A type whose elements have a bounded size, such as a word-size residue, needs no memory allocation, no branches on the size of the operands and no pointer chasing, and can be packed into vectors and matrices on which vectorised kernels operate. If the modulus is below 2^{64}, nmod types are several times faster than fmpz_mod types for the same computation; for small non-prime finite fields, Zech logarithms are much faster than polynomial representations. The price is a limit on the parameters, which the tables below give for each type.

Use the type of the module that does what you need. The classic modules (fmpz_poly, nmod_mat, fmpz_mpoly, ...) contain algorithms that exist for one ring only: factorisation of integer polynomials, LLL reduction, Hermite normal forms, multivariate GCDs. Before choosing a representation for speed, check that the module of that type has the operations your program needs.

Decide between exact and approximate arithmetic. Exact types (fmpz, fmpq, residues, finite fields, number fields, qqbar, ca) give exact results whose size may grow. Ball types (arb, acb and the dfloat and decimal balls) give rigorous error bounds at a fixed working precision. Floating-point types (arf, nfloat, the dfloat numbers, double) give approximations without automatic error tracking. See Ball arithmetic and Exact real and complex numbers.

Use the generic interface for rings that have no module of their own and for code that must work over several rings. Polynomials over \mathbb{Z}[i], matrices over a number field, power series over \mathbb{Z}/n\mathbb{Z} for a large n or polynomials whose coefficients are power series have no dedicated type, but are available as gr_poly, gr_mat and so on over the right context. Where a classic module exists, its functions are at least as fast as the generic ones (the generic contexts call them for the critical operations) and usually more complete. The trade-offs are described in Generic programming.

Mind the context. Types whose parameters are not stored in the object (fmpz_mod, fq, padic, the multivariate types, gr) take a context argument, which must outlive the objects. For historical reasons, the nmod_poly and nmod_mat types store their modulus in each object, which is simpler to call but makes objects larger.

Integers#

TypeRepresentsLimitsUse it for
ulong, slong with ulong_extras (n_ functions) and long_extras (z_)machine words0 \le n < 2^{\mathtt{FLINT\_BITS}}, resp. \lvert n \rvert < 2^{\mathtt{FLINT\_BITS} - 1}; overflow wraps silentlyinner loops; number theory on words (n_is_prime, n_factor, n_gcd, n_mulmod_preinv); exponents and moduli
fmpz_t in fmpzan integer of any sizememory; values with \lvert n \rvert < 2^{\mathtt{FLINT\_BITS} - 2} are stored in the word itself, larger ones as GMP integers (The fmpz representation)the default integer type; fast for small values, asymptotically fast multiplication, division and GCD for large ones
nn_ptr limb arrays with mpn_extras and GMP's mpn layernonnegative integers as limb arraysthe caller manages lengths and memoryfixed-size multiprecision kernels and implementing other types; the fastest code for operands of a few limbs
radix_integer_t in radixintegers in a radix such as 10^{19}decimal or base-p digit manipulation and conversion in linear time
fmpzi_t in fmpziGaussian integers \mathbb{Z}[i]memoryEuclidean division, GCD and primality in \mathbb{Z}[i]
fmpq_t in fmpqa rational number in lowest termsmemoryexact rational arithmetic; vectors and matrices in fmpq_vec and fmpq_mat

Integers modulo n#

TypeModulusElementsUse it for
ulong with nmod_t, in nmod1 \le n < 2^{\mathtt{FLINT\_BITS}}reduced residues in one wordthe default whenever n fits in a word; vectors, polynomials and matrices in nmod_vec, nmod_poly, nmod_mat, nmod_mpoly
nmod8, nmod32, nmod_redc, nmod_redc_fast contexts of gr (nmod.h)n \le 255, n < 2^{32}, odd n \ge 3, odd 3 \le n < 2^{\mathtt{FLINT\_BITS} - 2}uint8_t, uint32_t, Montgomery formssaving memory in large generic vectors and matrices; mostly less optimised than nmod
mpn_mod contexts of gr, in mpn_mod2^{\mathtt{FLINT\_BITS}} \le n < 2^{16 \mathtt{FLINT\_BITS}} (2 to 16 limbs)fixed-length limb arrays, no heap memorygeneric polynomials and matrices modulo moduli of 65 to 1024 bits; faster than fmpz_mod there (Using mpn_mod)
fmpz_t with fmpz_mod_ctx_t, in fmpz_modany n \ge 1fmpz residues in [0, n)moduli of any size, with the full classic set of modules fmpz_mod_poly, fmpz_mod_mat, fmpz_mod_mpoly

Operations that divide (polynomial division and GCD, matrix inversion and solving) generally require a prime modulus, or at least invertible pivots and leading coefficients. With the classic types the requirement is a documented precondition, and violating it raises an exception or gives undefined results; the generic gr interface instead returns GR_DOMAIN or GR_UNABLE.

Finite fields#

TypeField \mathbb{F}_q, q = p^dElementsUse it for
fq_zechq < 2^{\mathtt{FLINT\_BITS}}; context tables of 2q + p wordsdiscrete logarithms in one wordsmall fields: multiplication and division are additions of logarithms (Zech logarithms)
fq_nmodp < 2^{\mathtt{FLINT\_BITS}}, any dnmod_poly of length < dextension fields of word-size characteristic
fqany p, any dfmpz_poly of length < dlarge characteristic
fq_defaultanya union of the above, ulong or fmpznot knowing in advance: the representation is chosen when the context is created
nmod, fmpz_mod and mpn_mod with a prime modulusprime fieldsresiduesd = 1: faster than an fq type of degree 1

fq_default_ctx_init chooses fq_zech if d > 1 and d times the bit length of p is at most 16 (so q < 2^{16}), fq_nmod if d > 1 and p < 2^{\mathtt{FLINT\_BITS}}, nmod or fmpz_mod if d = 1, and fq otherwise (fq_default_ctx_init_type forces a choice); see Getting started with finite fields. Each representation has modules for vectors, matrices, polynomials, polynomial factorisation and embeddings (fq_nmod_poly, fq_zech_mat, fq_default_poly_factor, ...), and fq_nmod and fq_zech also multivariate polynomials (fq_nmod_mpoly, fq_zech_mpoly).

Univariate polynomials and power series#

TypeCoefficientsUse it for
nmod_poly\mathbb{Z}/n\mathbb{Z}, n < 2^{\mathtt{FLINT\_BITS}}the fastest dense polynomials: multiplication by Kronecker substitution or the small-prime FFT (Multiplying polynomials); factorisation in nmod_poly_factor
fmpz_poly\mathbb{Z}integer polynomials; factorisation (fmpz_poly_factor), real roots, resultants, cyclotomic and other special polynomials
fmpq_poly\mathbb{Q}rational polynomials, stored as an fmpz_poly numerator with one common denominator, so that the algorithms are those of fmpz_poly
fmpz_mod_poly\mathbb{Z}/n\mathbb{Z}, any npolynomials over residue rings with a multiprecision modulus; factorisation in fmpz_mod_poly_factor
fq_poly, fq_nmod_poly, fq_zech_poly, fq_default_poly\mathbb{F}_qas for the field elements above
arb_poly, acb_polyreal or complex ballsrigorous polynomial arithmetic and roots, and truncated power series: the _series functions are FLINT's automatic differentiation of special functions
padic_poly, ca_poly\mathbb{Q}_p, exact complex numbers
gr_polyany gr ringrings without a dedicated module (\mathbb{Z}[i], number fields, mpn_mod, nfloat, polynomials over polynomials), and generic code
gr_seriesany gr ringpower series as ring elements, either with an error term O(x^n) or exactly in R[x]/(x^n)
fmpz_poly_q\mathbb{Q}(x)univariate rational functions

Lengths and degrees are slong; the practical limit is memory. Most classic polynomial modules have _series functions (inverse, square root, exponential, logarithm, composition and reversion of power series truncated to a length).

Multivariate polynomials#

TypeCoefficientsUse it for
fmpz_mpoly, fmpq_mpoly\mathbb{Z}, \mathbb{Q}sparse polynomial arithmetic, exact division, GCD and factorisation (fmpz_mpoly_factor)
nmod_mpoly, fmpz_mod_mpoly\mathbb{Z}/n\mathbb{Z}the same over residue rings (GCD and factorisation need a prime modulus)
fq_nmod_mpoly, fq_zech_mpoly\mathbb{F}_q, word-size pthe same over finite fields
fmpz_mpoly_q, fmpz_mod_mpoly_qmultivariate rational functions
gr_mpolyany gr ringarithmetic and division over other rings; no GCD or factorisation

All these types store terms sparsely, sorted in a monomial ordering of the context, with exponent vectors packed into fields of bits bits (mpoly.h). Exponents are not bounded: up to FLINT_BITS bits, several fields share a word (at least MPOLY_MIN_BITS = 8 bits per field), and larger exponents take several words per field; the packing is enlarged automatically when a result needs it. fmpq_mpoly stores a rational content times a primitive fmpz_mpoly. For univariate problems, it is generally better to use the univariate types which store polynomials densely.

Matrices#

TypeEntriesUse it for
nmod_mat\mathbb{Z}/n\mathbb{Z}, n < 2^{\mathtt{FLINT\_BITS}}fast linear algebra modulo word-size n, with blocked and vectorised multiplication (Multiplying matrices, Linear algebra modulo n); the base of the multimodular algorithms over \mathbb{Z}
fmpz_mat\mathbb{Z}exact integer linear algebra: multimodular and p-adic solving, determinants, Hermite and Smith normal forms; LLL in fmpz_lll
fmpq_mat\mathbb{Q}rational matrices; nontrivial operations clear denominators and use fmpz_mat
fmpz_mod_mat, fq_mat, fq_nmod_mat, fq_zech_mat, fq_default_matresidues, finite fieldslinear algebra over these rings
arb_mat, acb_matreal or complex ballsrigorous numerical linear algebra, eigenvalues, matrix exponentials
ca_matexact real and complex numbersexact linear algebra over \overline{\mathbb{Q}} and transcendental extensions
nmod_poly_mat, fmpz_poly_mat, padic_mat, bool_matpolynomials, \mathbb{Q}_p, Booleans
gr_matany gr ringother rings (number fields, mpn_mod, nfloat, polynomial rings), approximate floating-point linear algebra, and generic code
d_matdoublea small support module with basic operations only

For approximate (non-rigorous) linear algebra at or above double precision, gr_mat over an nfloat or dfloat context is the fastest choice; for certified results, use arb_mat or acb_mat.

p-adic numbers and number fields#

TypeRepresentsLimitsUse it for
padic\mathbb{Q}_p: p^v u modulo p^Nany prime p; precision N per variablethe classic p-adic type, with polynomials and matrices (padic_poly, padic_mat)
qadicunramified extensions \mathbb{Q}_q of degree dany p, any dFrobenius, norms and traces, Teichmüller lifts
padic_radix\mathbb{Q}_p with propagated error termsword-size pa gr type with digits in radix p^e, faster than padic at high precision (Getting started with padic_radix)
nf_elem with nfnumber fields \mathbb{Q}[x]/(f)f irreducible of degree \ge 1 (not checked)arithmetic, norms and traces; special fixed-size representations for degree 1 and 2

Real and complex numbers#

TypeRepresentsPrecision and rangeUse it for
arb, acbballs [m \pm r] with an arf midpoint and a mag radiusany precision in bits, unbounded exponentsrigorous numerics and special functions (the default; see Ball arithmetic)
arf, mag, acfbinary floating-point numbers; radii with a 30-bit mantissaarf: any precision, unbounded exponents, mantissas of up to two limbs stored inlinemidpoints and radii of balls; approximate computation with correctly rounded basic operations
nfloatfloating-point numbers of a fixed number of words, real or complex1 to 66 words (64 to 4224 bits on 64-bit machines); exponents below about 2^{61} in magnitudefast approximate linear algebra and root finding through gr_mat and gr_poly (Getting started with nfloat)
dfloatsums of N = 1, \ldots, 4 doubles, and balls of them, real or complexabout 53N bits; the exponent range of doublefast approximate or rigorous arithmetic up to about 200 bits; requires correctly rounded fma (dfloat_is_supported)
decimaldecimal floating-point numbers and ballsany number of decimal digits, seven rounding modesresults specified in decimal digits; cheap conversion to and from decimal strings
mp_realballs and fixed-point numbers in the radix 2^{\mathtt{FLINT\_BITS}}limb granularitya low-level backend for ball arithmetic at high precision
double with double_extras, d_vec, d_mat, and di_t in double_intervalIEEE doubles; intervals with double endpoints53 bitscheap estimates and cheap rigorous bounds
arb_fpwrapspecial functions of double argumentsresults accurate to double precisioncalling FLINT's special functions from floating-point code

The ball types are the only real and complex types whose results are guaranteed in all cases (the dfloat and decimal balls are rigorous as well, but cover less functionality). The floating-point types are for approximate computations, typically followed by a rigorous verification, and are not rings in the sense of gr (Inexact elements and truth values).

Exact real and complex numbers#

Ball arithmetic can prove that two numbers differ, by computing them accurately enough that their balls are disjoint, but never that they are equal: a ball that contains zero is compatible with a tiny nonzero number. Computations that need equality (is a pivot zero, does an expression reproduce a known constant) can use FLINT's exact real and complex numbers, which represent numbers symbolically, so that arithmetic is exact and numerical values are available to any precision. This part of FLINT was developed as the library Calcium [Joh2021calcium].

TypeRepresentsUse it for
qqbaralgebraic numbers, stored canonically by a minimal polynomial and an isolating ballindividual algebraic numbers of moderate degree; every predicate is decided (Using qqbar)
caelements of fields \mathbb{Q}(a_1, \ldots, a_n) generated by algebraic and transcendental numbers (\mathbb{Q}(\sqrt 2, \pi), ...), constructed automatically; also infinities and Undefinedexact computation with algebraic and elementary transcendental numbers, with vectors, polynomials and matrices in ca_vec, ca_poly, ca_mat (Using ca)
fexprsymbolic expressions such as Add(Sqrt(2), Pi)constructing numbers from formulas, printing them as text or LaTeX; not a number type (Building and printing expressions)

The predicates of ca return T_TRUE, T_FALSE or T_UNKNOWN (Triple-valued logic): equality of algebraic numbers is decided within configurable limits, and equality involving transcendental numbers in many but not all cases, since it is not known to be decidable in general. A program must handle T_UNKNOWN (Dealing with T_UNKNOWN, What is decided in practice). qqbar decides every predicate, but its minimal polynomials can grow quickly; computations whose degrees explode, such as sums of many square roots, can be cheaper with ca, which keeps them in a field with several generators. For numbers in \mathbb{Q} or in one fixed number field, fmpq and nf_elem are much faster.

Exact numbers are far too slow to replace floating-point or ball arithmetic in numerical computations. A mostly numerical computation should use balls, and fall back on exact numbers only where an exact comparison is needed; exact numbers are also useful for testing numerical code. The contexts gr_ctx_init_real_qqbar, gr_ctx_init_complex_qqbar, gr_ctx_init_real_ca, gr_ctx_init_complex_ca and related ones make these numbers available to the generic polynomial and matrix algorithms (Number fields and algebraic numbers, Real and complex numbers). Choosing a representation for exact numbers compares the representations in detail, and Exact computation has worked examples.

Generic rings#

The generic interface gr makes all the ring types above, and rings built from them, available through one set of functions over a context gr_ctx_t (gr_domains). Use it for rings without a module of their own, for the types that exist only as generic rings (mpn_mod, nfloat, dfloat, decimal, padic_radix), and for code that must work over several rings. Getting started with generic rings is the tutorial, and Generic programming discusses what generic code costs.

References#

Cite this page

The FLINT team, “Choosing types,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/guide/types/choosing.html (generated 2026-10-20).