Algorithm Analysis
Euclid's Algorithm
Time Complexity
Computational Mathematics
Number Theory

Time complexity of Euclid's Algorithm

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Euclid's algorithm computes the greatest common divisor of two integers by repeatedly replacing the larger number with the remainder of dividing by the smaller one. It is one of the oldest algorithms still in daily use, and its efficiency is much better than many people expect.

The Algorithm

The core recurrence is:

gcd(a, b) = gcd(b, a mod b)

with the base case:

gcd(a, 0) = a

A straightforward implementation in Python looks like this:

python
1def gcd(a, b):
2    while b != 0:
3        a, b = b, a % b
4    return abs(a)
5
6
7print(gcd(48, 18))
8print(gcd(1071, 462))

Each loop iteration reduces the size of the problem.

High-Level Time Complexity

The usual time complexity statement is:

O(log(min(a, b)))

This means the number of division-with-remainder steps grows logarithmically with the size of the smaller input.

That is why Euclid's algorithm remains fast even for large integers. Every remainder step shrinks the problem significantly enough that the loop count stays small.

Why The Complexity Is Logarithmic

The key idea is that the values decrease quickly. In the worst case, the decrease is slowest when the inputs are consecutive Fibonacci numbers.

For example:

  • 'gcd(34, 21)'
  • 'gcd(21, 13)'
  • 'gcd(13, 8)'
  • 'gcd(8, 5)'
  • 'gcd(5, 3)'
  • 'gcd(3, 2)'
  • 'gcd(2, 1)'
  • 'gcd(1, 0)'

This is the longest kind of remainder chain relative to the size of the inputs. Since Fibonacci numbers grow exponentially, the number of steps is logarithmic in the magnitude of the input values.

Demonstrating The Step Count

Here is a version that counts iterations:

python
1def gcd_steps(a, b):
2    steps = 0
3    while b != 0:
4        a, b = b, a % b
5        steps += 1
6    return abs(a), steps
7
8
9pairs = [(48, 18), (1071, 462), (34, 21), (832040, 514229)]
10for a, b in pairs:
11    result, steps = gcd_steps(a, b)
12    print(a, b, result, steps)

You will see that the number of iterations stays modest even when the numbers are large.

Word-Level Versus Bit-Level Analysis

Most introductory discussions count one modulo operation as one constant-time step. Under that model, Euclid's algorithm is O(log(min(a, b))).

If you care about bit complexity, the story is slightly more detailed because division on very large integers is not truly constant time. Then the total cost depends on both:

  • the number of Euclidean iterations
  • the cost of each big-integer remainder operation

For standard algorithm-analysis questions, however, the accepted answer is the logarithmic step count above.

Best Case And Worst Case

The best case happens when one number divides the other immediately.

python
print(gcd_steps(100, 20))

That finishes in one remainder step.

The worst-case structure occurs with consecutive Fibonacci numbers, but even that worst case is still logarithmic. That is the important practical conclusion: there is no hidden quadratic explosion in the number of Euclidean iterations.

Why This Matters

The algorithm's efficiency is one reason it appears everywhere in computational mathematics and cryptography. Tasks such as reducing fractions, checking coprimality, and computing modular inverses all depend on repeated GCD calculations.

Because the complexity is logarithmic, GCD is usually not the bottleneck in those systems.

Common Pitfalls

A common mistake is saying the complexity is O(a) or O(b) because the values get smaller one step at a time. They do get smaller step by step, but the reduction is much faster than linear decay.

Another issue is mixing decimal digit count with numeric magnitude without stating the model. O(log n) in the numeric value corresponds to linear complexity in the number of digits or bits of the input representation.

Some answers also cite Fibonacci numbers without explaining why they matter. The point is not that Euclid's algorithm uses Fibonacci numbers directly. The point is that consecutive Fibonacci inputs generate the longest remainder chain.

Finally, do not confuse the classical Euclidean algorithm with more detailed bit-operation analysis unless the question explicitly asks for low-level arithmetic cost.

Summary

  • Euclid's algorithm computes gcd(a, b) by repeating gcd(b, a mod b).
  • The usual time complexity is O(log(min(a, b))) measured in Euclidean iterations.
  • Consecutive Fibonacci numbers produce the worst-case number of steps.
  • Even the worst case is still logarithmic, which makes the algorithm very efficient.
  • If you analyze bit operations instead of iteration count, the cost model becomes more detailed, but the algorithm remains highly practical.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.