Gaussian integers
- Cost
- Euclidean GCD of -bit inputs: division steps, bit operations; lattice GCD: dominated by a continued fraction expansion, quasi-linear with a half-GCD for large inputs; primality: one primality test of the norm or of a rational prime.
The ring of Gaussian integers is a Euclidean domain with respect to the norm , and hence a unique factorisation domain. Its units are , and is the unique prime above 2, with . Standard references are [Coh1996, §1.2] for Euclidean rings and [Wei2000] for the binary algorithm.
Division with remainder#
Proposition 1. For with , let and . Then .
Proof. Each of the real and imaginary parts of lies in , so , and .
fmpzi_divrem computes this quotient exactly: with , it takes the floor quotients of the real and imaginary parts of by , which costs one complex multiplication and two divisions. Ties are rounded upwards in each coordinate, which makes the remainder unique. When has at least three bits fewer than (in the larger of its parts), and the quotient is zero without computation.
fmpzi_divrem_approx only guarantees , which is all the Euclidean algorithm needs. When the bit sizes of and differ by less than 45, it computes the quotient from double-precision approximations of and (scaled by a common power of 2 if they are large). Each coordinate of the computed quotient then differs from the corresponding coordinate of by at most with a tiny , so . Otherwise it calls fmpzi_divrem.
Canonical associates#
Every nonzero has exactly one associate with real part positive and imaginary part in : the four associates are the rotations of by multiples of , and exactly one of them lies in the sector . fmpzi_canonical_unit_i_pow returns the exponent from two comparisons, and fmpzi_canonicalise_unit applies it. The GCD functions return the canonical associate, so that the GCD is unique; for example , while , and are its other associates.
Greatest common divisors#
Euclidean algorithm#
By Proposition 1 each step of at least halves the norm, so for inputs of bits there are at most about steps, and the total cost is bit operations as for integers. fmpzi_gcd_euclidean uses fmpzi_divrem. fmpzi_gcd_euclidean_improved uses fmpzi_divrem_approx, and as soon as all four parts are below in absolute value it finishes in double-precision arithmetic: the approximate quotient may differ from the rounded one, but the remainder is computed exactly in doubles because all intermediate values stay below , and any quotient with gives a correct Euclidean sequence.
The (1+i)-ary algorithm#
Weilert's analogue of the binary GCD [Wei2000] replaces divisions by additions and divisions by . Since , any two elements not divisible by satisfy , so all four of and are divisible by . fmpzi_gcd_binary first removes the factors from both inputs, remembering the smaller multiplicity, and then repeatedly replaces the larger of (by norm) by the one of , of smallest norm, divided by the largest power of . The four norms sum to , so the smallest is at most , and the division by at least halves it; Weilert shows that the algorithm has quadratic bit complexity, like the binary GCD for integers [Wei2000]. The implementation estimates the norms in double precision and falls back to fmpzi_gcd_euclidean when an input has more than 500 bits.
The lattice algorithm#
The ideal generated by and is a lattice in , generated over by (as vectors of real and imaginary parts). Its Hermite normal form is with , and is, up to a unit, a shortest nonzero vector of the lattice: every element is with . fmpzi_gcd_shortest, due to D. Schultz, computes the Hermite form by integer GCDs of the coordinates and then the shortest vector of the two-dimensional lattice in the norm from the continued fraction expansion of an interval around , computed by the quasi-linear ball continued fraction routine _fmpq_ball_get_cfrac of fmpq. A special case handles purely real or purely imaginary , where a vector has the same norm as .
Choice of algorithm#
fmpzi_gcd returns the canonical associate of the other input if one is zero. If all parts are below in absolute value it uses the double-precision Euclidean algorithm directly. If either input has both parts of one word, or either input has at most 30000 bits, it uses fmpzi_gcd_euclidean_improved. Otherwise it uses fmpzi_gcd_shortest, first reducing the larger input modulo the smaller with one approximate division if their sizes differ by more than a factor 1.5.
The prime 1 + i#
For , let (with ). Then with not divisible by 2, and is divisible by , exactly once, if and only if both parts of are odd. Since , the multiplicity of in is or . fmpzi_remove_one_plus_i computes it from the 2-adic valuations of the parts, divides by with shifts, multiplies by , and divides by once more using if needed.
Primality#
The Gaussian primes are, up to units, , the rational primes , and the elements with a rational prime [Coh1996, §1.2]. Hence is prime if and only if either and the nonzero part is with prime and , or and is prime. fmpzi_is_prime applies this criterion with fmpz_is_prime, which proves primality, and fmpzi_is_probabprime with fmpz_is_probabprime. FLINT does not provide factorisation in , which reduces to factoring the norm and, for each prime dividing it, finding with .
Use in FLINT#
- Division:
fmpzi_divrem,fmpzi_divrem_approx,fmpzi_divexact. - Normalisation:
fmpzi_canonical_unit_i_pow,fmpzi_canonicalise_unit. - GCD:
fmpzi_gcd_euclidean,fmpzi_gcd_euclidean_improved,fmpzi_gcd_binary,fmpzi_gcd_shortest,fmpzi_gcd; the last is the GCD of the generic ringgr_ctx_init_fmpzi. fmpzi_remove_one_plus_i,fmpzi_is_prime,fmpzi_is_probabprime.- Multiplication:
fmpzi_mulandfmpzi_sqruse the complex multiplicationflint_mpn_mul_complexwhen all parts are multiword; polynomial products use_fmpzi_poly_mulmid.
Referenced from#
- Primes and number theory (overview)
- Greatest common divisors of Gaussian integers
- fmpzi.h (module)
References#
- [Coh1996] Cohen, Henri : A course in computational algebraic number theory, Springer, 1996
- [Wei2000] A. Weilert, "(1+i)-ary GCD computation in Z[i] as an analogue to the binary GCD algorithm", Journal of Symbolic Computation 30.5 (2000): 605-617, https://doi.org/10.1006/jsco.2000.0422
The FLINT team, “Gaussian integers,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/number-theory/gaussian-integers.html (generated 2026-11-02).
@misc{flint-doc-algorithms-number-theory-gaussian-integers,
author = {{The FLINT team}},
title = {{Gaussian integers}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/algorithms/number-theory/gaussian-integers.html},
note = {Generated 2026-11-02}
}