Purpose: Compute the Greatest Common Divisor (GCD) of two integers, in O(log(min(a, b))) time.
Algorithm
- Given two integers
aandb(assumea β₯ b β₯ 0). - If
bis 0, the GCD isaβ stop. - Otherwise, replace
(a, b)with(b, a mod b). - Repeat until
bbecomes 0.
Code
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}Paradigm
Decrease and Conquer. Each step reduces the problem to a strictly smaller instance (a mod b is always smaller than b), shrinking toward the trivial base case b = 0 without needing to split into independent subproblems.
Complexity
- Time: O(log(min(a, b)))
- Space: O(1)
Proof of Correctness
Claim: gcd(a, b) = gcd(b, a mod b).
Proof: Let r = a mod b, so a = qb + r for some integer q. Any common divisor d of a and b must also divide a - qb = r, so d is a common divisor of b and r. Conversely, any common divisor d of b and r must also divide qb + r = a, so d is a common divisor of a and b. Since a and b have exactly the same set of common divisors as b and r, they share the same greatest common divisor: gcd(a, b) = gcd(b, r).
Termination: Since r = a mod b always satisfies 0 β€ r < b, the second element of the pair strictly decreases every step (as long as itβs not already 0), so the sequence of b values is strictly decreasing and bounded below by 0 β it must reach 0 in finitely many steps. When b = 0, gcd(a, 0) = a trivially (every number divides 0, so the greatest common divisor of a and 0 is a itself).
Why O(log(min(a,b))) steps suffice: This follows from a classical result (related to the Fibonacci sequence being the worst case): it can be shown that a mod b < a / 2 whenever b β€ a/2, and when b > a/2, a mod b = a - b < a/2 directly β either way, after two steps the larger number at least halves. So the number of steps is O(log(min(a,b))). β
Variants / Use Cases
- Extended Euclidean Algorithm β additionally finds integers
x, ysuch thatax + by = gcd(a,b), used for modular inverses - Binary GCD algorithm (Steinβs algorithm) β avoids division/modulo, using only subtraction and bit shifts, useful on hardware where division is slow
- LCM computation β
lcm(a,b) = a / gcd(a,b) * b, built directly on this algorithm - Simplifying fractions β dividing numerator and denominator by their GCD
- RSA and cryptographic key generation β GCD checks are used to verify coprimality of chosen numbers