FLINT3.7.0-dev
Algorithm

Rational reconstruction

Cost
O(log⁡2m)O(\log^2 m) bit operations with the Euclidean algorithm, O(M(log⁡m)log⁡log⁡m)O(M(\log m) \log\log m) with the half-GCD algorithm.

Multimodular and pp-adic algorithms compute in Z/mZ\mathbb{Z}/m\mathbb{Z}, where a rational number n/dn/d with gcd⁡(d,m)=1\gcd(d, m) = 1 is represented by the residue a≡nd−1(modm)a \equiv n d^{-1} \pmod m. When the answer of a computation over Q\mathbb{Q} — the solution of a linear system, the coefficients of a polynomial — has been found modulo a large enough mm, rational reconstruction recovers it from aa. The method goes back to Wang [WGD1982]; see also [CollinsEncarnacion1995], [GG2003, §5.10] and [Sho2009, §4.6].

Throughout, m>2m > 2, 0≤a<m0 \le a < m, and N,D≥1N, D \ge 1 are bounds with 2ND<m2ND < m.

Uniqueness#

Lemma 1. There is at most one fraction n/dn/d with ∣n∣≤N|n| \le N, 0<d≤D0 < d \le D and n≡ad(modm)n \equiv ad \pmod m, up to the representation of the fraction.

Proof. If n1/d1n_1/d_1 and n2/d2n_2/d_2 both satisfy the conditions, then n1d2≡ad1d2≡n2d1(modm)n_1 d_2 \equiv a d_1 d_2 \equiv n_2 d_1 \pmod m, and ∣n1d2−n2d1∣≤2ND<m|n_1 d_2 - n_2 d_1| \le 2ND < m, so n1d2=n2d1n_1 d_2 = n_2 d_1.

The condition 2ND<m2ND < m cannot be weakened much: the number of fractions with ∣n∣≤N|n| \le N and 0<d≤D0 < d \le D in lowest terms is about (12/π2)ND(12/\pi^2) ND, so their residues cannot all be distinct if NDND is much larger than mm. With the balanced choice N=D≈m/2N = D \approx \sqrt{m/2}, about 6/π2≈61%6/\pi^2 \approx 61\% of all residues are reconstructible.

The extended Euclidean algorithm#

Apply the extended Euclidean algorithm to r0=mr_0 = m and r1=ar_1 = a: with the quotients qi=⌊ri−1/ri⌋q_i = \lfloor r_{i-1} / r_i \rfloor,

ri+1=ri−1−qiri,si+1=si−1−qisi,ti+1=ti−1−qiti,r_{i+1} = r_{i-1} - q_i r_i, \qquad s_{i+1} = s_{i-1} - q_i s_i, \qquad t_{i+1} = t_{i-1} - q_i t_i,

starting from (s0,t0)=(1,0)(s_0, t_0) = (1, 0) and (s1,t1)=(0,1)(s_1, t_1) = (0, 1), until rℓ+1=0r_{\ell + 1} = 0. Then ri=sim+tiar_i = s_i m + t_i a, so ri≡tia(modm)r_i \equiv t_i a \pmod m for every ii. We use the following standard facts [GG2003, §3.2, §4.6].

  1. The tit_i alternate in sign and ∣t1∣<∣t2∣<⋯<∣tℓ+1∣|t_1| < |t_2| < \cdots < |t_{\ell+1}| (with ∣t2∣=q1≥1=∣t1∣|t_2| = q_1 \ge 1 = |t_1| the only possible equality).
  2. siti+1−si+1ti=(−1)is_i t_{i+1} - s_{i+1} t_i = (-1)^i, so gcd⁡(si,ti)=1\gcd(s_i, t_i) = 1.
  3. ri∣ti+1∣+ri+1∣ti∣=mr_i |t_{i+1}| + r_{i+1} |t_i| = m for 0≤i≤ℓ0 \le i \le \ell.
  4. The convergents of the continued fraction of a/ma/m are the fractions −si/ti-s_i/t_i, 1≤i≤ℓ+11 \le i \le \ell + 1.

Fact 3 follows from riti+1−ri+1ti=(siti+1−si+1ti)m=±mr_i t_{i+1} - r_{i+1} t_i = (s_i t_{i+1} - s_{i+1} t_i) m = \pm m and the alternating signs of the tit_i.

Algorithm 1: Rational reconstruction

Input: m>2m > 2, 0≤a<m0 \le a < m, N,D≥1N, D \ge 1 with 2ND<m2ND < m.

Output: the fraction n/dn/d in lowest terms with ∣n∣≤N|n| \le N, 0<d≤D0 < d \le D and n≡ad(modm)n \equiv ad \pmod m, or failure if none exists.

  1. If a≤Na \le N, return a/1a/1. If m−a≤Nm - a \le N, return (a−m)/1(a - m)/1.
  2. Run the extended Euclidean algorithm on (m,a)(m, a), computing only the rir_i and tit_i, up to the first index jj with rj≤Nr_j \le N.
  3. If ∣tj∣≤D|t_j| \le D and gcd⁡(rj,tj)=1\gcd(r_j, t_j) = 1, return sign⁡(tj) rj/∣tj∣\operatorname{sign}(t_j)\, r_j / |t_j|. Otherwise fail.

Theorem 2. Algorithm 1 is correct.

Proof. A returned fraction satisfies the conditions: in step 1 trivially, and in step 3 because rj≡tja(modm)r_j \equiv t_j a \pmod m, rj≤Nr_j \le N, ∣tj∣≤D|t_j| \le D and gcd⁡(rj,tj)=1\gcd(r_j, t_j) = 1. By Lemma 1 it is the only one.

Conversely, suppose that n/dn/d in lowest terms satisfies the conditions and that step 1 does not apply, so a>Na > N and j≥2j \ge 2. Write n=km+dan = km + da. Then gcd⁡(k,d)\gcd(k, d) divides nn and dd, so gcd⁡(k,d)=1\gcd(k, d) = 1, and

∣am−−kd∣=∣n∣dm≤Ndm<12dD≤12d2.\left| \frac{a}{m} - \frac{-k}{d} \right| = \frac{|n|}{dm} \le \frac{N}{dm} < \frac{1}{2d D} \le \frac{1}{2d^2}.

By Legendre's theorem [HarWri2008, Theorem 184], −k/d-k/d is a convergent of a/ma/m, so by fact 4 and fact 2, (k,d)=±(si,ti)(k, d) = \pm (s_i, t_i) for some i≥1i \ge 1, and then n=km+da=±rin = km + da = \pm r_i. Since ri=∣n∣≤Nr_i = |n| \le N, we have i≥ji \ge j. If i>ji > j, then by facts 3 and 1,

m=rj∣tj+1∣+rj+1∣tj∣≤2rj∣tj+1∣≤2N∣ti∣=2Nd≤2ND<m,m = r_j |t_{j+1}| + r_{j+1} |t_j| \le 2 r_j |t_{j+1}| \le 2N |t_i| = 2Nd \le 2ND < m,

a contradiction. Hence i=ji = j, (rj,tj)=±(n,d)(r_j, t_j) = \pm(n, d), and step 3 returns n/dn/d.

The remainders rir_i shrink and the cofactors tit_i grow as the algorithm proceeds, with ri−1∣ti∣≤mr_{i-1} |t_i| \le m; the bound NN decides where the algorithm stops, trading the size of the numerator against the size of the denominator. Monagan's maximal quotient variant [Mon2004] does not fix NN in advance but stops after the largest quotient qiq_i, which succeeds with a modulus only slightly larger than 2∣n∣d2|n|d with high probability; FLINT implements the bounded version, which is a proof when the bounds are known.

Complexity#

The Euclidean algorithm on bb-bit numbers costs O(b2)O(b^2) bit operations. Lehmer's method [Leh1938] simulates several steps with word-size leading parts of ri−1r_{i-1} and rir_i, so that most of the work is done with single-word 2×22 \times 2 matrices. The half-GCD algorithm [Sch1971], [ThullYap1990] computes the quotient sequence up to a given size recursively from the leading halves and costs O(M(b)log⁡b)O(M(b) \log b). The stopping rule rj≤Nr_j \le N is a partial GCD, which the half-GCD algorithm handles naturally: it reduces (m,a)(m, a) to a pair straddling a given size, then continues with Lehmer steps.

Several entries with a common denominator#

When a vector or matrix of rationals is reconstructed, the entries often share most of their denominator. Multiplying each residue by the denominator δ\delta of the entries found so far, the next entry is usually an integer δx mod m\delta x \bmod m in the symmetric range ∣⋅∣≤N|\cdot| \le N, recognised without any GCD; only otherwise is the entry reconstructed, with the denominator bound D/δD/\delta, and δ\delta multiplied by the new denominator.

Use in FLINT#

_fmpq_reconstruct_fmpz_2 implements Algorithm 1. After the quick integer tests of step 1, it chooses by the size of mm:

  • for mm of one or two limbs, a Euclidean algorithm in one or two words, with a binary GCD for the final coprimality test;
  • up to 12 limbs, Lehmer's method on stack arrays of limbs;
  • for larger mm, Lehmer's method on fmpz, switching to the half-GCD algorithm _fmpq_hgcd of the continued fraction code (Continued fractions of rational numbers) when mm has at least FMPQ_RECONSTRUCT_HGCD_CUTOFF (500) more limbs than NN, and to plain Euclidean steps when they differ by fewer than 3 limbs.

_fmpq_reconstruct_fmpz_2_naive is the plain algorithm on fmpz, used to check the fast version in tests. fmpq_reconstruct_fmpz uses the balanced bounds N=D=⌊⌊(m−1)/2⌋⌋N = D = \lfloor \sqrt{\lfloor (m-1)/2 \rfloor} \rfloor.

The reconstruction returns rational results in fmpq_mat_set_fmpz_mat_mod_fmpz, fmpz_mat_det_divisor and the Dixon solver fmpz_mat_solve_dixon_den (through _fmpz_mat_reconstruct_matwise), which all use the common denominator technique above, and in fmpq_poly_interpolate_multi_mod and fmpz_poly_roots_fmpq. How the multimodular and pp-adic linear algebra algorithms choose the bounds and decide when to stop is described in multimodular and pp-adic linear algebra.

int fmpq_reconstruct_fmpz(fmpq_t res, const fmpz_t a, const fmpz_t m)
int fmpq_reconstruct_fmpz_2(fmpq_t res, const fmpz_t a, const fmpz_t m, const fmpz_t N, const fmpz_t D)
int fmpq_mod_fmpz(fmpz_t res, const fmpq_t x, const fmpz_t mod)

Referenced from#

References#

  • [WGD1982] P. S. Wang, M. J. T. Guy and J. H. Davenport, "P-adic reconstruction of rational numbers", ACM SIGSAM Bulletin 16:2 (1982), 2–3. https://doi.org/10.1145/1089292.1089293
  • [CollinsEncarnacion1995] G. E. Collins and M. J. Encarnación, "Efficient rational number reconstruction", Journal of Symbolic Computation 20:3 (1995), 287–297. https://doi.org/10.1006/jsco.1995.1051
  • [GG2003] J. von zur Gathen and J. Gerhard, Modern Computer Algebra, second edition, Cambridge University Press (2003)
  • [Sho2009] V. Shoup. A Computational Introduction to Number Theory and Algebra. Second edition, Cambridge University Press, 2009. https://shoup.net/ntb/
  • [HarWri2008] G. H. Hardy and E. M. Wright, An Introduction to the Theory of Numbers, sixth edition, revised by D. R. Heath-Brown and J. H. Silverman, Oxford University Press, 2008.
  • [Mon2004] M. Monagan, "Maximal quotient rational reconstruction: an almost optimal algorithm for rational reconstruction", Proceedings of the 2004 International Symposium on Symbolic and Algebraic Computation (ISSAC 2004), 243–249. https://doi.org/10.1145/1005285.1005321
  • [Leh1938] D. H. Lehmer, "Euclid's algorithm for large numbers", American Mathematical Monthly 45:4 (1938), 227–233.
  • [Sch1971] A. Schönhage, "Schnelle Berechnung von Kettenbruchentwicklungen", Acta Informatica 1 (1971), 139–144
  • [ThullYap1990] Thull, K. and Yap, C. : A Unified Approach to HGCD Algorithms for Polynomials and Integers, (1990)
Cite this page

The FLINT team, “Rational reconstruction,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/number-theory/rational-reconstruction.html (generated 2026-11-02).