Modular Inverse
Find a^-1 mod m — the number that multiplies a to 1 — via Fermat's little theorem when m is prime or the extended Euclidean algorithm for any coprime m.
Overview
The modular inverse of a modulo m is the residue x with a · x ≡ 1 (mod m). It exists iff gcd(a, m) = 1, and it is what "division" means in Modular Arithmetic: b / a ≡ b · a^-1. Example: 3 · 4 = 12 ≡ 1 (mod 11), so 3^-1 ≡ 4 (mod 11), and 5 / 3 ≡ 5 · 4 = 20 ≡ 9 (mod 11).
Two methods. Fermat (prime m only): by Fermat's little theorem a^(m-1) ≡ 1, so a^-1 ≡ a^(m-2), one call to Fast Exponentiation in O(log m). Extended Euclid (any m coprime to a): solve a·x + m·y = 1 with GCD (Euclidean Algorithm); then x mod m is the inverse. Euler's generalization a^(φ(m)-1) also works for composite m but needs φ(m), which requires factoring.
For many inverses at once, precompute: inverse factorials via invfact[n] = fact[n]^-1 and invfact[i-1] = invfact[i] · i (one exponentiation total), or all inverses 1..n via the recurrence inv[i] = -(m / i) · inv[m mod i] mod m in O(n) — the tools behind Combinatorics nCr tables.
Intuition
A mental model before the formal terms.
On a 7-hour clock, stepping by 3 hours repeatedly visits 3, 6, 2, 5, 1, 4, 0 — every hour, because 3 and 7 share no factor. The inverse of 3 is the number of steps to land on 1: five steps (3 · 5 = 15 ≡ 1). Multiplying by 5 "undoes" multiplying by 3. With step 2 on a 6-hour clock you only ever visit 2, 4, 0 and never reach 1 — no inverse, because gcd(2, 6) = 2.
How it works
- Check
gcd(a, m) == 1; otherwise no inverse exists and the problem must be restructured. - Fermat (prime
m):inv = powMod(a, m - 2, m). - Extended Euclid:
(g, x, y) = extGcd(a, m); ifg == 1,inv = ((x % m) + m) % m. - Batch inverses
1..nmod primep:inv[1] = 1; fori ≥ 2:inv[i] = (p - (p / i) · inv[p % i] % p) % p. - Inverse factorials: compute
fact[0..n], theninvfact[n] = powMod(fact[n], p - 2), and walk downinvfact[i - 1] = invfact[i] · i % p.
Why it works
Bezout: gcd(a, m) = 1 gives integers x, y with a·x + m·y = 1; reducing mod m kills the m·y term, leaving a·x ≡ 1. Conversely if a·x ≡ 1 then a·x - 1 is a multiple of m, so any common divisor of a and m divides 1.
Fermat: for prime p and p ∤ a, the map k ↦ a·k permutes the nonzero residues, so the product of all nonzero residues equals a^(p-1) times itself, giving a^(p-1) ≡ 1. Multiplying both sides by a^-1 yields a^(p-2) ≡ a^-1.
Batch recurrence: write p = q·i + r with q = p / i, r = p mod i. Then q·i + r ≡ 0, so i ≡ -r · q^-1, hence i^-1 ≡ -q · r^-1 and r < i is already known.
Recognition
How to tell a problem wants this.
- A formula with division (
n! / (k!(n-k)!), averages, probabilities asp/q) must be reported modulo a prime. - "Modulo
10^9 + 7" combined with binomial coefficients, harmonic-like sums, or geometric series formulas. - Solving linear congruences
a·x ≡ b (mod m)or reconstructing values in the Chinese Remainder Theorem.
Interactive visualization
Play, step, change the input. ← → and space work too.
Showing the closely related Fast Exponentiation visualization.
| e | e (binary) | e & 1 | base | result |
|---|---|---|---|---|
| 13 | 1101 | · | 3 | 1 |
1result = 1; base = base mod M2while e > 0:3 if e & 1: result = result · base mod M # this bit is set4 base = base · base mod M5 e = e >> 16return resultPseudocode
1inverse_fermat(a, p): return power(a, p - 2, p) // p prime2inverse_euclid(a, m):3 (g, x, y) = ext_gcd(a, m)4 if g != 1: no inverse5 return (x mod m + m) mod m6all_inverses(n, p):7 inv[1] = 18 for i in 2..n: inv[i] = (p - (p / i) * inv[p mod i] mod p) mod pImplementations
1from typing import Optional2 3# The modular inverse of a is the x with a*x = 1 (mod m). It exists iff4# gcd(a, m) == 1. Two routes: extended Euclid (any m) and Fermat (prime m).5 6 71 · Extended Euclid returns (g, x, y) with a*x + b*y == g == gcd(a, b)8def ext_gcd(a: int, b: int) -> tuple[int, int, int]:9 old_r, r = a, b10 old_s, s = 1, 011 old_t, t = 0, 112 while r != 0:13 q = old_r // r14 old_r, r = r, old_r - q * r15 old_s, s = s, old_s - q * s16 old_t, t = t, old_t - q * t17 return old_r, old_s, old_t18 19 202 · Inverse for any modulus: the Bezout coefficient x, normalised21def inverse(a: int, m: int) -> Optional[int]:22 g, x, _ = ext_gcd(a % m, m)23 if g != 1:24 return None # no inverse when gcd(a, m) != 125 return x % m26 27 283 · Prime modulus shortcut: Fermat gives a^(m-1) = 1, so a^(m-2) is a^-129def inverse_fermat(a: int, prime: int) -> int:30 return pow(a, prime - 2, prime) # built-in three-argument pow31 32 334 · All inverses 1..n at once, in O(n) rather than n separate O(log m) calls34def inverse_table(n: int, prime: int) -> list[int]:35 inv = [1] * (n + 1)36 for i in range(2, n + 1):37 # inv[i] = -(prime // i) * inv[prime % i] mod prime38 inv[i] = (prime - prime // i) * inv[prime % i] % prime39 return inv40 41 425 · Division becomes multiplication by the inverse43def div_mod(a: int, b: int, prime: int) -> int:44 return a * pow(b, -1, prime) % prime # pow with -1 is the inverse (3.8+)- The simultaneous tuple assignment
old_r, r = r, old_r - q * ris the cleanest expression of the Euclidean recurrence in any of the four languages — the right-hand side is fully evaluated before any binding changes. x % mneeds no normalisation dance: Python%returns a non-negative result for a positive modulus even whenxis negative.pow(a, prime - 2, prime)is the built-in three-argument modular exponentiation, implemented in C.pow(b, -1, prime)is the direct modular inverse, available since Python 3.8, and it raisesValueErrorwhen the inverse does not exist — better than returning a sentinel.inverse_tableuses the O(n) recurrence, which matters when a combinatorics problem needs every inverse up to 10^6.
The built-in pow(b, -1, m) is C-implemented and beats a hand-written extended Euclid in Python despite the worse constant in theory.
pow(base, -1, mod)(Python 3.8+) is the modular inverse and raisesValueErrorwhengcd(base, mod) != 1— the clearest failure contract of the four languages.math.gcdis built in; there is no standard extended version, soext_gcdstill has to be written for Bezout coefficients.//floors, soold_r // ris correct for non-negative operands and differs from C/JS truncation for negatives — Euclid only ever sees non-negatives here.- Tuple assignment evaluates the entire right-hand side first, which is what makes the simultaneous update safe without temporaries.
- Hand-writing extended Euclid when
pow(b, -1, m)exists, is shorter, faster, and reports failure properly. - Catching nothing around
pow(b, -1, m)and letting theValueErrorescape when the modulus is composite. - Writing the Euclid updates as separate statements, which uses the already-updated value and produces wrong coefficients.
- Only Python has a built-in modular inverse (
pow(b, -1, m), 3.8+), and it is the only one that signals non-existence by raising rather than by a sentinel or an option type. - Simultaneous assignment: Python tuple assignment and JS/TS array destructuring both express the Euclidean update in one line; C++ needs
std::tieplusstd::make_tupleto get the same effect. - Negative normalisation is needed in C++ and JS/TS (where
%follows the dividend) and is free in Python (where it follows the divisor) — the Bezout coefficient is frequently negative, so this is not a corner case. - Signalling "no inverse": C++
std::optional, TypeScriptbigint | null, Python a raisedValueError, and JavaScript a barenull— four different contracts for the same mathematical fact.
Complexity
Fermat: O(log p) multiplications. Extended Euclid: O(log m) steps with smaller constants. Batch inverses of 1..n: O(n) total.
Compare growth rates in the Complexity Explorer →When to use — and when not to
- Fermat when the modulus is a known prime (
10^9 + 7,998244353) — shortest code, onepowModcall. - Extended Euclid when the modulus is composite or unknown to be prime, or when you also need to verify that the inverse exists.
- Precomputed inverse factorials or batch inverses when a problem needs
O(n)or more divisions.
- When
gcd(a, m) ≠ 1— no inverse exists. Cancel common factors symbolically, or use the CRT to split the modulus. - When
mis prime butais a multiple ofm—a ≡ 0has no inverse; Fermat silently returns 0. - When exact rational output is required — modular "fractions" are residues, not numbers you can compare.
Alternatives
Common mistakes
- Using Fermat with a composite modulus (
10^9,2^32) — the result is garbage with no error. - Forgetting to normalize the Euclid coefficient:
xcan be negative; return((x % m) + m) % m. - Exponent typo:
a^(p-1)(which is 1) instead ofa^(p-2). - JavaScript: computing
b * inv % pwith plain numbers — the product exceeds2^53; useBigInt. - Recomputing
powModinside a loop forndivisions when precomputed inverse factorials would make eachO(1).
Interview patterns
- Binomial coefficients mod
pvia factorial and inverse-factorial tables — see Combinatorics. - Expected value / probability answers "as
p · q^-1 mod 10^9 + 7". - Geometric series
Σ r^i = (r^n - 1) / (r - 1)modpusing the inverse ofr - 1. - Linear congruence
a·x ≡ b (mod m): divide byg = gcd(a, m)ifg | b, then multiply by the inverse ofa/gmodm/g.