Integer division and Newton iteration
- Cost
- Schoolbook ; divide and conquer ; Newton division, exact division and square root , for an -limb divisor and quotient.
Given integers of limbs and of limbs, Euclidean division computes the quotient of limbs and the remainder . Most of the code is in mpn_extras; it replaces GMP's mpn_tdiv_qr throughout FLINT, and the fmpz division functions (Division and rounding conventions) reach it through an mpz-like layer (flint_mpz_tdiv_qr and its relatives) that applies the rounding conventions at the limb level.
Throughout, , is the cost of an -limb multiplication (Multiplying integers), and a divisor is normalised if its top limb is at least , which is achieved by shifting both operands left by the same number of bits.
Schoolbook division#
The schoolbook method (Knuth's Algorithm D [Knu1997, §4.3.1]) produces one quotient limb per step: it estimates the next limb from the top limbs of the current remainder and the divisor, subtracts the product of the estimate and the divisor, and corrects the estimate if the result is negative. The estimate is good because the divisor is normalised.
Lemma 1 (Quotient limb estimate). Let with , let with , and let (so ). Then
satisfies .
Proof. Write . Since , we have , so ; also , hence . For the estimate is exact. Otherwise , and , using . Suppose . Since ,
so . Then , so , a contradiction.
Using the top two limbs of the divisor and three of the remainder (a "3-by-2" division) sharpens the estimate to , and with a precomputed reciprocal of the top two divisor limbs each estimate costs a few multiplications instead of a hardware division, as in Möller and Granlund [GraMol2010] (Division by an invariant word). The method costs limb operations.
In FLINT, divisors of up to FLINT_MPN_DIV_SMALL_BN limbs with short quotients are divided by dedicated functions, one per divisor length, which keep the normalised divisor and the partial remainder in registers and normalise the dividend on the fly; one-limb divisors use GMP's assembly mpn_divrem_1. Larger divisors use a port of GMP's mpn_sbpi1_div_qr (schoolbook with a 3-by-2 inverse) with FLINT's multiplication.
Divide and conquer#
Burnikel and Ziegler [BurZie1998] observed that the schoolbook method works with blocks of limbs in place of limbs: dividing a -block number by a -block number takes two steps, each dividing by blocks, and each of those is a recursive division of the top half followed by one multiplication of half-size blocks.
Proposition 2. Divide-and-conquer division of a -limb by an -limb integer costs , so , and if with .
Proof. Each half step does one recursive division of size and one product (plus an number of corrections, each ), which gives the recurrence. Unrolling, . Since is nondecreasing, , which gives ; if , the terms decrease geometrically with ratio and the sum is .
FLINT uses a port of GMP's mpn_dcpi1_div_qr with its own multiplication from FLINT_MPN_DIV_DC_CUTOFF limbs (on recent x86-64), together with variants that compute only the quotient, or an approximate quotient (at most one too large), which save the corrections of the remainder. When only a quotient about as long as the divisor is needed, a short division in the style of Mulders, which forms only the high halves of the products, is faster still [HZ2011] (High, low and middle products of integers).
Newton iteration#
For large operands, division reduces to multiplication by computing an approximate reciprocal by Newton's method. Viewing as a fixed-point number in , the iteration
converges quadratically to .
Lemma 3. If , then satisfies .
Proof. , so .
Each step doubles the number of correct limbs, and only the last step needs full precision. Since is small, its top half is known to be zero (or all ones), and the product can be replaced by a middle product of half the cost. Summing over the precisions , the reciprocal costs a small constant times .
Karp and Markstein [KM1997] noticed that the last step can produce the quotient directly, so that the reciprocal is only needed to half precision.
Theorem 4 (Karp–Markstein division). Let , and . Then .
Proof. , so .
With accurate to limbs, truncated to limbs, and the correction needing only limbs, the quotient to limbs costs a half-precision reciprocal and a few half-size products. In practice the computed quotient carries one or two guard limbs, and its error, from the truncations, is bounded by a few units of the last guard limb.
FLINT implements this in fixed-point arithmetic (_mp_real_inv_newton and _mp_real_div_newton of mp_real, with some steps of third order, which triple the precision instead of doubling it). _flint_mpn_tdiv_qr calls it when the divisor and the quotient both have at least FLINT_MPN_TDIV_QR_NEWTON_CUTOFF limbs, or the divisor has at least 608 limbs and the quotient at least twice as many. It computes the quotient with two guard limbs; the error is at most 4 units of the first guard limb, so if that limb lies in the integer part is certain and the remainder follows from a low product. Otherwise the quotient is corrected by steps using a full product.
Precomputed inverses and long quotients#
When the quotient is much longer than the divisor, or many dividends are divided by the same divisor, the reciprocal is computed once and used for every block of quotient limbs, as in Barrett's method (Barrett and Lemire reduction):
flint_mpn_preinvncomputes an -limb approximation of the reciprocal of a normalised -limb divisor, andflint_mpn_divrem_preinvndivides by it limbs at a time: each block of the quotient is the high part of the product of the inverse with the top limbs of the remainder, followed by a low product and at most a few corrections.fmpz_fdiv_qr_preinvnexposes it, andfmpz_mod_muluses it for moduli of more than 20 limbs.- For a dividend of at least three times the length of a divisor of hundreds of limbs,
_flint_mpn_tdiv_qrdivides from the top down in blocks of by limbs with one approximate inverse of fraction limbs shared by all blocks (_flint_mpn_tdiv_qr_unbalanced). For divisors of a few dozen limbs and long dividends it uses thepreinvndivision instead, which is up to 40% faster than GMP there.
Exact division#
If is known to divide , the quotient can be computed from the low limbs instead of the high ones, by 2-adic arithmetic. This is Hensel's idea applied to integers, introduced for division by Jebelean [Jeb1993].
Proposition 5. Let be odd and with . Then , so is the residue in of .
Proof. is invertible modulo because it is odd, and determines modulo ; since , it is that residue.
A power of two and whole zero limbs in are removed first (they must divide equally). The quotient of an -limb by an -limb integer has limbs (one fewer if the top limb of is below that of ), and by the proposition it depends only on the low limbs of and , so long operands are truncated before dividing. The quotient is developed from the least significant limb upwards: , then is subtracted and the process continues. Compared with Euclidean division, no quotient limb is ever estimated or corrected, and the unused high limbs are never touched.
The 2-adic inverse needed for large operands is computed by Newton iteration, which converges as in Lemma 3:
Lemma 6. If , then satisfies .
Proof. .
The analogue of Theorem 4 also holds: with , the low half of the quotient is , and the high half is modulo the remaining precision.
_flint_mpn_divexact (behind flint_mpn_divexact and fmpz_divexact) uses, for a truncated divisor of limbs: register-based code for ; ports of GMP's schoolbook and divide-and-conquer Hensel division (mpn_sbpi1_bdiv_q, mpn_dcpi1_bdiv_q, from 40 and 80 limbs) with FLINT's multiplication; and for FLINT_MPN_DIVEXACT_NEWTON_CUTOFF limbs, or a quotient of at least four times the length of a divisor of 531 limbs or more, flint_mpn_bdiv_q, which computes the inverse with flint_mpn_binv (Newton iteration with middle products) and uses Karp–Markstein Hensel division, or block division for short divisors.
The same tools give:
flint_mpn_divisible(behindfmpz_divisible): the 2-adic part, then a cheap trial-division screen modulo small primes for large operands, then the Hensel remainder, which is zero exactly when divides ;flint_mpn_divexact_preinv, which stores the 2-adic inverse of a fixed divisor, used by_fmpz_vec_scalar_divexact_fmpzto divide a whole vector by one large integer;fmpz_invmod_2exp,fmpz_divmod_2exp,fmpz_sqrtmod_2expandfmpz_rsqrtmod_2exp, which expose inversion, division and (inverse) square roots modulo .
Square roots#
The integer square root with remainder is computed by the same techniques.
Divide and conquer. Zimmermann's "Karatsuba square root" [Zim1999] splits a normalised into quarters and computes
followed by one correction (, ) if . Zimmermann proves that the result is correct; the cost is one recursive square root, one division and one squaring of half size, so the method costs when with and in general.
Newton iteration. The iteration converges quadratically to : if , then . As for division, the last step computes the root directly (Karp–Markstein): with , the value is accurate to twice the precision of .
_flint_mpn_sqrtrem uses dedicated code for one to four limbs (a floating-point square root, a Newton correction, and one divide-and- conquer step for three and four limbs), FLINT's divide-and-conquer code (as GMP's mpn_sqrtrem, but with FLINT's division and multiplication) up to FLINT_MPN_SQRTREM_NEWTON_CUTOFF limbs, and the Newton–Karp–Markstein method (_mp_real_sqrt_newton, certified as for division by inspecting a guard limb) above. fmpz_sqrt, fmpz_sqrtrem, fmpz_is_square and fmpz_perfect_sqrt use it (Square roots, n-th roots and perfect powers).
Use in FLINT#
_flint_mpn_tdiv_qr(q, r, a, m, b, n) (behind flint_mpn_tdiv_qr, Euclidean division of limb arrays) chooses, for quotient limbs, with the cutoffs of recent x86-64 processors:
- , or with : register-based schoolbook division (
tdiv_qr_small). - and , or and : Newton (Karp–Markstein) division, or for block division with a shared inverse.
- and , or and : block division with a shared inverse.
- and , or and : division with
flint_mpn_divrem_preinvn. - Otherwise: the ports of GMP's schoolbook and divide-and-conquer division, with FLINT's multiplication.
Functions that need only the quotient (flint_mpn_tdiv_q), only an approximate quotient (flint_mpn_divapprox, used by mp_real division), or a remainder by a precomputed inverse use variants of the same algorithms that skip the work they do not need.
void fmpz_tdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h)void fmpz_divexact(fmpz_t f, const fmpz_t g, const fmpz_t h)int fmpz_divisible(const fmpz_t f, const fmpz_t g)void fmpz_fdiv_qr_preinvn(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h, const fmpz_preinvn_t inv)void fmpz_sqrtrem(fmpz_t f, fmpz_t r, const fmpz_t g)Referenced from#
- Ball arithmetic with limb-granular radii (algorithm)
- Multiplying integers (overview)
- Division and rounding conventions
- fmpz.h (module)
- Square roots, n-th roots and perfect powers
_fmpz_vec_scalar_divexact_fmpz,_fmpz_vec_scalar_divexact_si,_fmpz_vec_scalar_divexact_ui_mp_real_inv_newton_basecase,_mp_real_inv_newton- mpn_extras.h (module)
- Euclidean division of limb arrays
References#
- [Knu1997] Knuth, D. E. The Art of Computer Programming, volume 2: Seminumerical algorithms, 1997
- [GraMol2010] N. Möller and T. Granlund, "Improved division by invariant integers", IEEE Transactions on Computers 60 (2011), 165–175, https://gmplib.org/~tege/division-paper.pdf
- [BurZie1998] C. Burnikel and J. Ziegler. Fast recursive division. Max-Planck-Institut für Informatik, Research Report MPI-I-98-1-022, 1998.
- [HZ2011] D. Harvey and P. Zimmermann, "Short division of long integers" (2011), Proceedings of the 20th Symposium on Computer Arithmetic (ARITH-20), July 25-27, 2011, pages 7-14. https://web.maths.unsw.edu.au/~davidharvey/research/shortdiv.pdf
- [KM1997] A. H. Karp and P. Markstein, "High-precision division and square root", ACM Transactions on Mathematical Software 23:4 (1997), 561–589
- [Jeb1993] T. Jebelean. An algorithm for exact division. Journal of Symbolic Computation 15 (1993), 169–180. https://doi.org/10.1006/jsco.1993.1012
- [Zim1999] P. Zimmermann. Karatsuba square root. INRIA Research Report RR-3805, 1999.
The FLINT team, “Integer division and Newton iteration,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/integers/division.html (generated 2026-11-02).
@misc{flint-doc-algorithms-integers-division,
author = {{The FLINT team}},
title = {{Integer division and Newton iteration}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/algorithms/integers/division.html},
note = {Generated 2026-11-02}
}