FLINT3.7.0-dev
Module · 48 functions

fmpzi.h

#include <flint/fmpzi.h>

This module implements the ring \mathbb{Z}[i] of Gaussian integers. An element is an fmpzi_t, a pair of fmpz integers holding the real and imaginary parts. Besides the ring operations, the module provides Euclidean division, which makes \mathbb{Z}[i] a Euclidean domain with respect to the norm N(a + bi) = a^2 + b^2, greatest common divisors normalised to a canonical associate, removal of the prime 1 + i, primality testing, and fast multiplication of polynomials with Gaussian integer coefficients. The generic ring gr_ctx_init_fmpzi (in gr.h) is built on these functions and gives polynomials and matrices over \mathbb{Z}[i]. Factorisation is not implemented.

Greatest common divisors of Gaussian integers describes the GCD functions in more detail.

AlgorithmGaussian integersDivision with remainder, the canonical associate, and the four GCD algorithms of fmpzi (Euclidean in exact and floating-point arithmetic, the (1+i)-ary binary algorithm, and a lattice algorithm), together with primality testing and the removal of factors 1+i.

Types#

A Gaussian integer a + bi, with fields a and b of type fmpz. An fmpzi_t is an array of one fmpzi_struct, so it is passed by reference.

Pointers (fmpz *) to the real and imaginary parts of x.

Basic manipulation#

Initialise x to zero, respectively clear it.

Swaps x and y in constant time.

Set x to 0, respectively 1.

void fmpzi_set(fmpzi_t res, const fmpzi_t x)

Sets res to x.

Sets res to a + bi.

void fmpzi_print(const fmpzi_t x)

Prints x to stdout in the form a+b*I (for example 6+3*I or 30-15*I).

Sets res to a random element whose parts are drawn by fmpz_randtest with up to bits bits.

Properties#

int fmpzi_equal(const fmpzi_t x, const fmpzi_t y)

Returns whether x = y.

int fmpzi_is_zero(const fmpzi_t x)
int fmpzi_is_one(const fmpzi_t x)

Return whether x = 0, respectively x = 1.

int fmpzi_is_unit(const fmpzi_t x)

Returns whether x is one of the units \pm 1, \pm i.

Returns k \in \{0, 1, 2, 3\} such that i^k x is the canonical associate of x: the one with positive real part a and imaginary part b in (-a, a] (for x = 0, k = 0).

Sets res to the canonical associate i^k x of x.

Returns the number of bits of the larger in absolute value of the real and imaginary parts, 0 for x = 0.

void fmpzi_norm(fmpz_t res, const fmpzi_t x)

Sets res to the norm N(x) = a^2 + b^2.

Arithmetic#

void fmpzi_conj(fmpzi_t res, const fmpzi_t x)
void fmpzi_neg(fmpzi_t res, const fmpzi_t x)

Set res to the complex conjugate \bar x, respectively to -x.

void fmpzi_add(fmpzi_t res, const fmpzi_t x, const fmpzi_t y)
void fmpzi_sub(fmpzi_t res, const fmpzi_t x, const fmpzi_t y)

Set res to x + y, respectively x - y.

void fmpzi_mul(fmpzi_t res, const fmpzi_t x, const fmpzi_t y)
void fmpzi_sqr(fmpzi_t res, const fmpzi_t x)

Set res to xy, respectively x^2.

More
void fmpzi_pow_ui(fmpzi_t res, const fmpzi_t x, ulong exp)

Sets res to x^{e} with x^0 = 1, by left-to-right binary exponentiation, with a direct formula for purely real or purely imaginary x.

void fmpzi_mul_i(fmpzi_t z, const fmpzi_t x)
void fmpzi_div_i(fmpzi_t z, const fmpzi_t x)

Set z to ix, respectively x/i = -ix.

void fmpzi_mul_i_pow_si(fmpzi_t res, const fmpzi_t z, slong k)

Sets res to i^k z for any integer k.

Division#

void fmpzi_divexact(fmpzi_t q, const fmpzi_t x, const fmpzi_t y)

Sets q to x/y, assuming that the division is exact. Throws if y = 0.

More
void fmpzi_divrem(fmpzi_t q, fmpzi_t r, const fmpzi_t x, const fmpzi_t y)

Sets q and r to the quotient and remainder of x by y: x = qy + r, where q is x/y with both coordinates rounded to the nearest integer, ties rounded upwards. Then N(r) \le N(y)/2, and the pair is uniquely determined. r may be NULL. Throws if y = 0.

void fmpzi_divrem_approx(fmpzi_t q, fmpzi_t r, const fmpzi_t x, const fmpzi_t y)

Sets q and r with x = qy + r and N(r) < N(y), choosing q from a floating-point approximation of x/y when the operands have similar sizes; the choice is implementation-defined. r may be NULL. Throws if y = 0.

Sets res to x / (1 + i)^k for the largest k such that the division is exact, and returns k. For x = 0, sets res to 0 and returns 0.

GCD#

void fmpzi_gcd_euclidean(fmpzi_t res, const fmpzi_t x, const fmpzi_t y)
void fmpzi_gcd_binary(fmpzi_t res, const fmpzi_t x, const fmpzi_t y)
void fmpzi_gcd_shortest(fmpzi_t g, const fmpzi_t x, const fmpzi_t y)
void fmpzi_gcd(fmpzi_t g, const fmpzi_t x, const fmpzi_t y)

Set the output to the greatest common divisor of x and y in canonical form (see fmpzi_canonical_unit_i_pow); the GCD of 0 and 0 is 0. The euclidean version is Euclid's algorithm with fmpzi_divrem, the euclidean_improved version uses approximate quotients and finishes in double-precision arithmetic, the binary version is Weilert's (1+i)-ary algorithm [Wei2000] (which falls back to the Euclidean algorithm above 500 bits), and the shortest version finds the GCD as a shortest vector of the lattice generated by x and y. fmpzi_gcd chooses among them.

Full documentation

Primality testing#

int fmpzi_is_prime(const fmpzi_t n)

Return whether n is a Gaussian prime: a unit times 1 + i, a unit times a rational prime p \equiv 3 \pmod 4, or an element whose norm is a rational prime. fmpzi_is_prime proves primality of the relevant rational integer with fmpz_is_prime, fmpzi_is_probabprime uses the probable prime test fmpz_is_probabprime.

Polynomial multiplication#

These functions do not support aliasing: the output res must not overlap the input polynomials.

int _fmpzi_poly_mulmid_classical_fft_small(fmpzi_struct * res, const fmpzi_struct * poly1, slong len1, const fmpzi_struct * poly2, slong len2, slong nlo, slong nhi)

Computes the coefficients [\mathtt{nlo}, \mathtt{nhi}) of the product of the Gaussian integer polynomials (poly1, len1) and (poly2, len2), with the coefficient arithmetic done pointwise on fft_small transforms: two transforms per coefficient (real and imaginary parts) and four pointwise operations per complex product, the shorter operand's transforms kept and the longer rolling as in _fmpz_poly_mulmid_classical_fft_small. Squaring shares transforms, pairs symmetric terms and computes diagonal squares with three multiplications. The lengths may be given in either order. Returns 1 on success and 0 when the transformed representation is unavailable or unprofitable in which case nothing is written and the caller should fall back to a different routine.

void _fmpzi_poly_mulmid(fmpzi_struct * res, const fmpzi_struct * poly1, slong len1, const fmpzi_struct * poly2, slong len2, slong nlo, slong nhi)

Sets (res, nhi - nlo) to the coefficients at indices [\mathtt{nlo}, \mathtt{nhi}) of the product of the Gaussian integer polynomials (poly1, len1) and (poly2, len2), choosing an algorithm. Assumes that len1 and len2 are positive and that 0 \le nlo < nhi \le len1 + len2 - 1; the lengths may be given in either order, and res must not alias the inputs. This is the multiplication used by the fmpzi generic ring for polynomial multiplication, low products and middle products.

More
void _fmpzi_poly_mulmid_KS(fmpzi_struct * res, const fmpzi_struct * poly1, slong len1, const fmpzi_struct * poly2, slong len2, slong nlo, slong nhi)

Sets (res, nhi - nlo) to the coefficients at indices [\mathtt{nlo}, \mathtt{nhi}) of the product of the Gaussian integer polynomials (poly1, len1) and (poly2, len2), using Kronecker substitution. Assumes that len1 and len2 are positive and that 0 \le nlo < nhi \le len1 + len2 - 1; the lengths may be given in either order, and res must not alias the inputs.

More
void _fmpzi_poly_mulmid_SS(fmpzi_struct * res, const fmpzi_struct * poly1, slong len1, const fmpzi_struct * poly2, slong len2, slong nlo, slong nhi)
void _fmpzi_poly_mulmid_SS_pair(fmpzi_struct * res, const fmpzi_struct * poly1, slong len1, const fmpzi_struct * poly2, slong len2, slong nlo, slong nhi)
void _fmpzi_poly_mulmid_SS_single(fmpzi_struct * res, const fmpzi_struct * poly1, slong len1, const fmpzi_struct * poly2, slong len2, slong nlo, slong nhi)

Sets (res, nhi - nlo) to the coefficients at indices [\mathtt{nlo}, \mathtt{nhi}) of the product of the Gaussian integer polynomials (poly1, len1) and (poly2, len2), using Schoenhage-Strassen convolution. Assumes that len1 and len2 are positive and that 0 \le nlo < nhi \le len1 + len2 - 1; the lengths may be given in either order, and res must not alias the inputs.

More

References#

  • [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
Cite this page

The FLINT team, “fmpzi.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/fmpzi/index.html (generated 2026-10-20).