# Binary GCD algorithm Visualisation of using the binary GCD algorithm to find the greatest common divisor (GCD) of 36 and 24. Thus, the GCD is 22 × 3 = 12.

The binary GCD algorithm, also known as Stein's algorithm, is an algorithm that computes the greatest common divisor of two nonnegative integers. Stein's algorithm uses simpler arithmetic operations than the conventional Euclidean algorithm; it replaces division with arithmetic shifts, comparisons, and subtraction. Although the algorithm was first published by the Israeli physicist and programmer Josef Stein in 1967, it may have been known in 1st-century China.

## Algorithm

The algorithm reduces the problem of finding the GCD by repeatedly applying these identities:

1. gcd(0, v) = v, because everything divides zero, and v is the largest number that divides v. Similarly, gcd(u, 0) = u. gcd(0, 0) is not typically defined, but it is convenient to set gcd(0, 0) = 0.
2. If u and v are both even, then gcd(uv) = 2·gcd(u/2, v/2), because 2 is a common divisor.
3. If u is even and v is odd, then gcd(uv) = gcd(u/2, v), because 2 is not a common divisor. Similarly, if u is odd and v is even, then gcd(uv) = gcd(uv/2).
4. If u and v are both odd, and u ≥ v, then gcd(uv) = gcd((u − v)/2, v). If both are odd and u < v, then gcd(uv) = gcd((v − u)/2, u). These are combinations of one step of the simple Euclidean algorithm, which uses subtraction at each step, and an application of step 3 above. The division by 2 results in an integer because the difference of two odd numbers is even.
5. Repeat steps 2–4 until u = v, or (one more step) until u = 0. In either case, the GCD is 2kv, where k is the number of common factors of 2 found in step 2.

The algorithm requires O(n2) worst-case time, where n is the number of bits in the larger of the two numbers. Although each step reduces at least one of the operands by at least a factor of 2, the subtract and shift operations take linear time for very large integers (although they're still quite fast in practice, requiring about one operation per word of the representation).

An extended binary GCD, analogous to the extended Euclidean algorithm, is given by Knuth along with pointers to other versions.

## Implementation

### Recursive version in C

Following is a recursive implementation of the algorithm in C. The implementation is similar to the description of the algorithm given above. It uses two arguments u and v. All but one of the recursive calls are tail recursive.

```unsigned int gcd(unsigned int u, unsigned int v)
{
// simple cases (termination)
if (u == v)
return u;

if (u == 0)
return v;

if (v == 0)
return u;

// look for factors of 2
if (~u & 1) // u is even
if (v & 1) // v is odd
return gcd(u >> 1, v);
else // both u and v are even
return gcd(u >> 1, v >> 1) << 1;

if (~v & 1) // u is odd, v is even
return gcd(u, v >> 1);

// reduce larger argument
if (u > v)
return gcd((u - v) >> 1, v);

return gcd((v - u) >> 1, u);
}
```

### Iterative version in C

Following is an implementation of the algorithm in C, taking two (non-negative) integer arguments u and v. It first removes all common factors of 2 using identity 2, then computes the GCD of the remaining numbers using identities 3 and 4, and combines these to form the final answer.

```unsigned int gcd(unsigned int u, unsigned int v)
{
unsigned int shift = 0;

/* GCD(0,v) == v; GCD(u,0) == u, GCD(0,0) == 0 */
if (u == 0) return v;
if (v == 0) return u;

/* Let shift := lg K, where K is the greatest power of 2
dividing both u and v. */
while (((u | v) & 1) == 0) {
shift++;
u >>= 1;
v >>= 1;
}

while ((u & 1) == 0)
u >>= 1;

/* From here on, u is always odd. */
do {
/* remove all factors of 2 in v -- they are not common */
/*   note: v is not zero, so while will terminate */
while ((v & 1) == 0)
v >>= 1;

/* Now u and v are both odd. Swap if necessary so u <= v,
then set v = v - u (which is even). For bignums, the
swapping is just pointer movement, and the subtraction
can be done in-place. */
if (u > v) {
unsigned int t = v; v = u; u = t; // Swap u and v.
}

v -= u; // Here v >= u.
} while (v != 0);

/* restore common factors of 2 */
return u << shift;
}
```

## Efficiency

Akhavi and Vallée proved that, in theory, binary GCD can be about 60% more efficient (in terms of the number of bit operations) on average than the Euclidean algorithm. However, although this algorithm modestly outperforms the traditional Euclidean algorithm in real implementations (see next paragraph), its asymptotic performance is the same, and binary GCD is considerably more complex to code given the widespread availability of a division instruction in all modern microprocessors. (But on some processors the division instruction may be a lot slower than many other machine instructions.)

Real computers operate on more than one bit at a time, and even assembly language implementations of binary GCD have to compete against carefully designed hardware circuits for integer division. Overall, Knuth (1998) reports a 20% gain over Euclidean GCD, on a version of MIX (Knuth's abstract model of a machine architecture) extended with binary shift and test operations.

For arbitrary-precision arithmetic, neither the Euclidean algorithm nor the binary GCD algorithm are fastest, as they both take time that is a quadratic function of the number of input digits. Instead, recursive methods that combine ideas from the binary GCD algorithm with the Schönhage–Strassen algorithm for fast integer multiplication can find GCDs in near-linear time.

## Historical description

An algorithm for computing the GCD of two numbers was described in the ancient Chinese mathematics book The Nine Chapters on the Mathematical Art. The original algorithm was used to reduce a fraction. The description reads:

"If possible halve it; otherwise, take the denominator and the numerator, subtract the lesser from the greater, and do that alternately to make them the same. Reduce by the same number."

This description looks like a normal Euclidean algorithm, but there is ambiguity in the phrase "if possible halve it".[citation needed] The traditional interpretation is that this only applies when 'both' numbers are even, implying the algorithm is just slightly inferior to the Euclidean algorithm (for using subtraction instead of division). But the phrase may mean dividing by 2 should 'either' of the numbers become even, in which case it is the binary GCD algorithm.