Когда оба числа равны нулю, результат не определён — подойдёт сколько угодно большое число. За исключением этого случая, верно следующее наблюдение: если одно из чисел равно нулю, то их равен второму числу.
#Алгоритм нахождения
Алгоритм Евклида находит двух чисел и за , основываясь на следующей несложной формуле:
Здесь предполагается, что .
Докажем корректность этой формулы:
Если делит и , и , то их разность тоже будет делиться на .
Никакой больший делитель числа не может делить число : если , то не может делить , а значит и не делит .
Прямая рекурсивная реализация:
int gcd(int a, int b) {
if (a < b)
swap(a, b);
if (b == 0)
return a;
else
return gcd(b, a - b);
}
Этот алгоритм может работать долго — например, на паре он сделает миллиард итераций.
Идея дальнейшей оптимизации в том, чтобы вычитать из не одно за раз, а столько, чтобы в следующий раз и уже поменялись местами — чтобы новое стало меньше нового . Простой способ этого достичь — просто вычесть из сразу максимально возможное число раз, то есть взять вместо нового остаток от деления на :
Реализация:
int gcd(int a, int b) {
if (b == 0)
return a;
else
return gcd(b, a % b);
}
Чуть более быстрая итеративная форма:
int gcd(int a, int b) {
while (b > 0) {
a %= b;
swap(a, b);
}
return a;
}
В современном C++ есть встроенная библиотечная функция gcd
, которую рекомендуется использовать, не забывая про случай отрицательных чисел и .
Также помимо алгоритма Евклида существует в 2-3 раза более быстрый бинарный GCD.
#Время работы
Можно показать, что каждые две итерации меньшее число уменьшится хотя бы в два раза, а следовательно алгоритм работает за . Эта оценка относится не только к худшему случаю, но и к среднему.

Примечательно, что худшие входные данные для алгоритма — это соседние числа Фибоначчи. На графике они видны как синие точки в пропорциях золотого сечения.
Также иногда полезно знать, что нахождение группы из чисел от до будет работать не за , а за — это несложно доказать по индукции.