Division with remainder
#include <flint/nmod_poly.h>void _nmod_poly_divrem(nn_ptr Q, nn_ptr R, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, nmod_t mod)sourcevoid nmod_poly_divrem(nmod_poly_t Q, nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B)sourceSet Q and R to the quotient and remainder of A by B, so that A = BQ + R with \deg R < \deg B. The underscore version requires \mathit{lenA} \ge \mathit{lenB} \ge 1 and writes \mathit{lenA} - \mathit{lenB} + 1 coefficients to Q and \mathit{lenB} - 1 to R. R may be the same array as A; otherwise the outputs must not overlap each other or the inputs.
Schoolbook division is used if the quotient has at most 80 coefficients or \mathit{lenB} is small (below 400 for moduli of at most 27 bits and below 80 otherwise, in builds with AVX2; 200 and 80 without), and Newton division otherwise. Without fft_small, divisors of length at least 1024 and moduli of at least 16 bits use divide-and-conquer division for \mathit{lenA} \le 16384.
void nmod_poly_div(nmod_poly_t Q, const nmod_poly_t A, const nmod_poly_t B)sourceSet Q to the quotient of A by B without computing the remainder. The underscore version requires \mathit{lenA} \ge \mathit{lenB} \ge 1, writes \mathit{lenA} - \mathit{lenB} + 1 coefficients and does not allow aliasing.
Schoolbook division is used if \mathit{lenB} \le 15 or the quotient has at most 16 coefficients, and Newton division of the reversed polynomials otherwise: the quotient only depends on the top \mathit{lenQ} coefficients of A and B.
void nmod_poly_rem(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B)sourceSet R to the remainder of A by B. The underscore version requires \mathit{lenA} \ge \mathit{lenB} \ge 1, writes \mathit{lenB} - 1 coefficients and does not allow aliasing. Quotients of length 2, the typical step of the Euclidean algorithm, use a dedicated routine. nmod_poly_rem throws FLINT_DIVZERO for B = 0 even modulo 1.
void _nmod_poly_divexact(nn_ptr Q, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, nmod_t mod)sourcevoid nmod_poly_divexact(nmod_poly_t Q, const nmod_poly_t A, const nmod_poly_t B)sourceSet Q to A / B, assuming that B divides A; otherwise the result is meaningless. The underscore version requires \mathit{lenA} \ge \mathit{lenB} \ge 1, writes \mathit{lenA} - \mathit{lenB} + 1 coefficients and does not allow aliasing.
Since the division is exact, the quotient can be computed from the top coefficients (division of the reversed polynomials) or from the bottom coefficients (power series division), or half from each end. The algorithm is schoolbook division from the top if \mathit{lenB} \le 40 or \mathit{lenQ} \le 20, schoolbook division from both ends if \mathit{lenB} \le 60 or \mathit{lenQ} \le 60, and otherwise Newton division of both halves, each of half the length.
int _nmod_poly_divides(nn_ptr Q, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, nmod_t mod)sourceint nmod_poly_divides(nmod_poly_t Q, const nmod_poly_t A, const nmod_poly_t B)sourceint _nmod_poly_divides_classical(nn_ptr Q, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, nmod_t mod)sourceint nmod_poly_divides_classical(nmod_poly_t Q, const nmod_poly_t A, const nmod_poly_t B)sourceIf B divides A, set Q = A / B and return 1; otherwise set Q = 0 and return 0. The zero polynomial divides only itself. The underscore versions require \mathit{lenA} \ge \mathit{lenB} \ge 1, write \mathit{lenA} - \mathit{lenB} + 1 coefficients and do not allow aliasing.
Both compute the quotient Q with _nmod_poly_div first and then check that BQ agrees with A in the low \mathit{lenB} - 1 coefficients, which is cheaper than computing the remainder. The classical version checks the coefficients one at a time and stops at the first mismatch; _nmod_poly_divides uses it when \mathit{lenA} < 40 and \mathit{lenB} < 20, and otherwise checks the low coefficients in blocks of length \mathit{lenQ} by fast multiplication (or computes the remainder if \mathit{lenA} \ge 2 \mathit{lenB} - 1).
For polynomials A and B \ne 0 whose leading coefficient is invertible modulo n, there are unique Q and R with A = BQ + R and \deg R < \deg B. nmod_poly_divrem computes both; nmod_poly_div and nmod_poly_rem compute one of them, nmod_poly_divexact computes Q when R is known to be zero, and nmod_poly_divides decides whether R = 0. The modulus need not be prime, but if the leading coefficient of B is not a unit, an exception is thrown even when the division would be possible.
Algorithms#
Let \mathit{lenQ} = \deg A - \deg B + 1 be the length of the quotient.
- Schoolbook division computes the quotient coefficients from the top, subtracting a multiple of B for each, with O(\mathit{lenQ} \cdot \mathit{lenB}) operations. FLINT keeps the partial remainder unreduced in one to three words per coefficient and reduces a coefficient only when it becomes the leading one, so the inner loop is a plain multiply-accumulate.
- Newton division uses the identity \operatorname{rev}(Q) = \operatorname{rev}(A) / \operatorname{rev}(B) \bmod x^{\mathit{lenQ}} for the reversed polynomials (see Computing modulo a fixed polynomial): the quotient is a power series quotient, computed by Newton iteration in a constant number of multiplications of length \mathit{lenQ}, and the remainder is A - BQ, of which only the low \mathit{lenB} - 1 coefficients are needed.
nmod_poly_divrem uses schoolbook division when the quotient has at most 80 coefficients or the divisor is short (fewer than 400 coefficients for moduli of at most 27 bits, 80 otherwise, in builds with AVX2), and Newton division otherwise. nmod_poly_div switches to Newton division earlier, when both lengths exceed 15, since it does not need the remainder. nmod_poly_rem handles the case \mathit{lenQ} = 2, the typical step of the Euclidean algorithm, with a dedicated routine. Division by a sparse modulus is fastest with nmod_poly_divrem_newton_n_preinv, which reduces directly when the divisor has at most five nonzero lower terms.
nmod_poly_divexact exploits exactness: the quotient is determined both by the top coefficients of A (division from the top) and by its bottom coefficients (power series division by B, if B(0) is a unit), and for medium and long inputs it computes half of the quotient from each end, which roughly halves the work. nmod_poly_divides computes the quotient with nmod_poly_div and then checks A - BQ only in its low coefficients, stopping at the first nonzero one.
For repeated division by the same B, precompute the inverse of the reversed divisor and use nmod_poly_divrem_newton_n_preinv; see Computing modulo a fixed polynomial.
Examples#
Modulo 13, the program builds A = (x^3 + 2x + 5)(x^2 + 3) + x + 1 and recovers the quotient and remainder, divides exactly, tests divisibility and removes a repeated factor:
#include <flint/flint.h>
#include <flint/nmod_poly.h>
int main(void)
{
nmod_poly_t a, b, c, q, r;
nmod_poly_init(a, 13);
nmod_poly_init(b, 13);
nmod_poly_init(c, 13);
nmod_poly_init(q, 13);
nmod_poly_init(r, 13);
nmod_poly_set_str(c, "4 13 5 2 0 1"); /* x^3 + 2x + 5 */
nmod_poly_set_str(b, "3 13 3 0 1"); /* x^2 + 3 */
nmod_poly_mul(a, c, b);
nmod_poly_add_ui(a, a, 1);
nmod_poly_set_coeff_ui(a, 1, nmod_poly_get_coeff_ui(a, 1) + 1);
nmod_poly_divrem(q, r, a, b);
flint_printf("q = "); nmod_poly_print_pretty(q, "x");
flint_printf(", r = "); nmod_poly_print_pretty(r, "x"); flint_printf("\n");
nmod_poly_sub(a, a, r); /* now b divides a */
nmod_poly_divexact(q, a, b);
flint_printf("divexact: "); nmod_poly_print_pretty(q, "x"); flint_printf("\n");
flint_printf("b | a: %d, ", nmod_poly_divides(q, a, b));
nmod_poly_add_ui(a, a, 1);
flint_printf("b | a + 1: %d\n", nmod_poly_divides(q, a, b));
/* a = b^3 c */
nmod_poly_pow(a, b, 3);
nmod_poly_mul(a, a, c);
flint_printf("multiplicity of b: %wu, cofactor ", nmod_poly_remove(a, b));
nmod_poly_print_pretty(a, "x"); flint_printf("\n");
nmod_poly_clear(a);
nmod_poly_clear(b);
nmod_poly_clear(c);
nmod_poly_clear(q);
nmod_poly_clear(r);
return 0;
}q = x^3+2*x+5, r = x+1 divexact: x^3+2*x+5 b | a: 1, b | a + 1: 0 multiplicity of b: 3, cofactor x^3+2*x+5
Division by a non-monic divisor modulo a composite number works as long as its leading coefficient is a unit. Modulo 15, the program divides by 7x^2 + 1 (7 \cdot 13 \equiv 1) and checks A = BQ + R:
#include <flint/flint.h>
#include <flint/nmod_poly.h>
int main(void)
{
nmod_poly_t a, b, q, r, t;
nmod_poly_init(a, 15);
nmod_poly_init(b, 15);
nmod_poly_init(q, 15);
nmod_poly_init(r, 15);
nmod_poly_init(t, 15);
nmod_poly_set_str(a, "6 15 1 2 3 4 5 6");
nmod_poly_set_str(b, "3 15 1 0 7");
nmod_poly_divrem(q, r, a, b);
flint_printf("q = "); nmod_poly_print_pretty(q, "x");
flint_printf(", r = "); nmod_poly_print_pretty(r, "x"); flint_printf("\n");
nmod_poly_mul(t, b, q);
nmod_poly_add(t, t, r);
flint_printf("b q + r == a: %d\n", nmod_poly_equal(t, a));
nmod_poly_clear(a);
nmod_poly_clear(b);
nmod_poly_clear(q);
nmod_poly_clear(r);
nmod_poly_clear(t);
return 0;
}q = 3*x^3+5*x^2+13*x+4, r = 4*x+12 b q + r == a: 1
Guides#
The FLINT team, “Division with remainder (nmod_poly.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/nmod_poly/divrem.html (generated 2026-10-20).
@misc{flint-doc-nmod-poly-divrem,
author = {{The FLINT team}},
title = {{Division with remainder (nmod\_poly.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/nmod_poly/divrem.html},
note = {Generated 2026-10-20}
}