Algorithm Search⌘K

Proofs: Binary GCD

These are the human proofs of Binary GCD, at full length.

Binary GCD returns gcd(a, b) after at most 1 + lg(ab) passes and O(n^2) bit operations full

This proof shows: correctness, termination, time.worst, bit_operations.worst.

We use the pseudocode BINARY-GCD of the page. The inputs a0,b0a_0, b_0 are any integers, and g=gcd⁡(a0,b0)g = \gcd(a_0, b_0), with gcd⁡(x,0)=∣x∣\gcd(x, 0) = |x| and gcd⁡(0,0)=0\gcd(0, 0) = 0. For x>0x > 0, tz⁡(x)\operatorname{tz}(x) is the exponent of 22 in xx, so x=2tz⁡(x)ux = 2^{\operatorname{tz}(x)} u with uu odd.

Lemma 1 (three gcd rules). Let u,v≥1u, v \ge 1 be integers.

  1. If uu is odd, then gcd⁡(u,2sv)=gcd⁡(u,v)\gcd(u, 2^s v) = \gcd(u, v) for each s≥0s \ge 0.
  2. gcd⁡(u,v)=gcd⁡(u,v−u)\gcd(u, v) = \gcd(u, v - u).
  3. If k=min⁡(tz⁡(u),tz⁡(v))k = \min(\operatorname{tz}(u), \operatorname{tz}(v)), then gcd⁡(u,v)=2kgcd⁡(u/2tz⁡(u),v/2tz⁡(v))\gcd(u, v) = 2^k \gcd(u / 2^{\operatorname{tz}(u)}, v / 2^{\operatorname{tz}(v)}).

Proof. (1) A common divisor of uu and vv divides 2sv2^s v. Conversely, let dd divide uu and 2sv2^s v. Since uu is odd, dd is odd, so gcd⁡(d,2s)=1\gcd(d, 2^s) = 1, and d∣2svd \mid 2^s v gives d∣vd \mid v by Gauss's lemma. So the two pairs have the same common divisors. (2) dd divides uu and vv if and only if it divides uu and v−uv - u. (3) Write u=2su′u = 2^{s} u' and v=2tv′v = 2^{t} v' with u′,v′u', v' odd, s≤ts \le t say, so k=sk = s. Then gcd⁡(u,v)=2sgcd⁡(u′,2t−sv′)\gcd(u, v) = 2^s \gcd(u', 2^{t-s} v'), because gcd⁡(cx,cy)=cgcd⁡(x,y)\gcd(cx, cy) = c \gcd(x, y) for c≥1c \ge 1, and gcd⁡(u′,2t−sv′)=gcd⁡(u′,v′)\gcd(u', 2^{t-s} v') = \gcd(u', v') by rule 1. □\square

Theorem 1 (correctness). BINARY-GCD(a0,b0)(a_0, b_0) stops and returns gg.

Proof. After line L1, a=∣a0∣a = |a_0|, b=∣b0∣b = |b_0|, and gcd⁡(a,b)=g\gcd(a, b) = g. If a=0a = 0, line L2 returns b=gb = g; if b=0b = 0, line L3 returns a=ga = g. Otherwise a,b≥1a, b \ge 1. Line L4 sets k=tz⁡(aorb)k = \operatorname{tz}(a \mathbin{\mathrm{or}} b), which is min⁡(tz⁡(a),tz⁡(b))\min(\operatorname{tz}(a), \operatorname{tz}(b)), since the lowest 11 digit of aorba \mathbin{\mathrm{or}} b is the lower of the lowest 11 digits of aa and bb. Let a1=a/2tz⁡(a)a_1 = a / 2^{\operatorname{tz}(a)} and b1=b/2tz⁡(b)b_1 = b / 2^{\operatorname{tz}(b)}. By Lemma 1 (3), g=2kgcd⁡(a1,b1)=2kgcd⁡(a1,b)g = 2^k \gcd(a_1, b_1) = 2^k \gcd(a_1, b), the last step by rule 1. Line L5 sets a=a1a = a_1. We use this invariant at the start of each pass of the loop L6 to L10:

(I) aa is odd, b≥1b \ge 1, and 2kgcd⁡(a,b)=g2^k \gcd(a, b) = g.

Initialization. Shown above.

Maintenance. Line L7 makes bb odd; by rule 1, gcd⁡(a,b)\gcd(a, b) does not change. Line L8 swaps if needed, so now a≤ba \le b and both are odd. Line L9 sets b←b−a≥0b \leftarrow b - a \ge 0, and rule 2 keeps the gcd. If b≥1b \ge 1 after line L9, the loop goes on and (I) holds: aa is odd and b≥1b \ge 1.

Exit. The loop exits at line L10 when b−a=0b - a = 0, so a=ba = b and gcd⁡(a,b)=a\gcd(a, b) = a. Then g=2kag = 2^k a, which line L11 returns. Termination follows from Theorem 2. ■\blacksquare

Theorem 2 (number of passes). If a0b0≠0a_0 b_0 \ne 0, the loop runs at most 1+lg⁡(∣a0∣⋅∣b0∣)1 + \lg(|a_0| \cdot |b_0|) times. If the inputs have at most nn binary digits, this is at most 2n+12n + 1.

Proof. For pass ii, let Pi=a⋅bP_i = a \cdot b right after line L8 of that pass. At that moment a≤ba \le b, both odd. If the pass does not exit, line L9 makes b−ab - a, which is even and at least 22, and line L7 of the next pass divides it by at least 22. So the next pass starts its line L8 with the pair aa and (b−a)/2s(b - a)/2^{s}, s≥1s \ge 1, in some order, and

Pi+1≤a⋅b−a2<ab2=Pi2.P_{i+1} \le a \cdot \frac{b - a}{2} < \frac{a b}{2} = \frac{P_i}{2}.

Let the loop run tt passes. Then 1≤Pt<P1/2t−11 \le P_t < P_1 / 2^{t-1} when t≥2t \ge 2, so 2t−1<P12^{t-1} < P_1. Lines L5 and L7 only divide, so P1≤∣a0∣⋅∣b0∣P_1 \le |a_0| \cdot |b_0|. This gives t<1+lg⁡(∣a0∣∣b0∣)t < 1 + \lg(|a_0| |b_0|) for t≥2t \ge 2, and the bound holds for t=1t = 1 too. Since ∣a0∣,∣b0∣<2n|a_0|, |b_0| < 2^n, t≤2n+1t \le 2n + 1. ■\blacksquare

Tightness. On (2n−1,1)(2^n - 1, 1) the loop runs exactly nn times: the pair is (1,2j−1)(1, 2^j - 1), line L9 gives 2j−22^j - 2, and line L7 gives 2j−1−12^{j-1} - 1. So the number of passes is Θ(n)\Theta(n) in the worst case.

Theorem 3 (time and bit operations). On the word RAM with a constant-time count of trailing zeros, BINARY-GCD uses O(n)O(n) word operations. On inputs of at most nn binary digits, it uses O(n2)O(n^2) bit operations.

Proof. Each pass does a constant number of shifts, comparisons, subtractions and trailing zero counts, so the word bound follows from Theorem 2. In the bit model, each of these operations on numbers of at most nn digits costs O(n)O(n) bit operations: a shift by ss places costs O(n)O(n), and tz⁡\operatorname{tz} by a scan from the low end costs O(1+tz⁡(x))O(1 + \operatorname{tz}(x)). Lines L1 to L5 and L11 cost O(n)O(n), and there are O(n)O(n) passes of O(n)O(n) each, so the total is O(n2)O(n^2). If tz⁡\operatorname{tz} is computed by testing one digit at a time, the total count of digits shifted out over the whole run is at most lg⁡∣a0∣+lg⁡∣b0∣≤2n\lg |a_0| + \lg |b_0| \le 2n, since each shift by one place halves a value that stays at least 11; this does not change the bounds. ■\blacksquare

Back to Binary GCD