Greatest Common Divisor Jordi Cortadella Department of Computer Science
Simplifying fractions greatest common divisor Introduction to Programming© Dept. CS, UPC2
The largest square tile What is the largest square tile that can exactly cover a w h rectangle? w = 60 h=24 44444444 90 tiles of side-length 4 Introduction to Programming© Dept. CS, UPC3
The largest square tile What is the largest square tile that can exactly cover a w h rectangle? w = 60 h=24 66666666 90 tiles of side-length 4 40 tiles of side-length 6 Introduction to Programming© Dept. CS, UPC4
The largest square tile What is the largest square tile that can exactly cover a w h rectangle? w = 60 h=24 90 tiles of side-length 4 40 tiles of side-length 6 10 tiles of side-length 12 Introduction to Programming© Dept. CS, UPC5
The largest square tile What is the largest square tile that can exactly cover a w h rectangle? w = 60 h=24 12 24 = (5 12) (2 12) = (5 2) (12 12) gcd(60, 24) largest tile number of tiles Introduction to Programming© Dept. CS, UPC6
Euclid (300 B.C.) A fragment of Euclid’s Elements Introduction to Programming© Dept. CS, UPC7
Euclidean algorithm for gcd Introduction to Programming© Dept. CS, UPC8
Euclidean algorithm for gcd Introduction to Programming© Dept. CS, UPC
Euclidean algorithm for gcd Properties: gcd(a, a) = a; gcd(a, 0) = a If a b, then gcd(a, b) = gcd(a b, b) Example: ab gcd (114, 42) Introduction to Programming© Dept. CS, UPC10
Euclidean algorithm for gcd // Pre: a > 0, b > 0 // Returns the greatest common divisor of a and b int gcd(int a, int b) { while (a != b) { if (a > b) a = a – b; else b = b – a; } return a; } Introduction to Programming© Dept. CS, UPC11
Euclidean algorithm for gcd iterationab 010,000, ,999, ,999, ,999, …… 64, , , , , , …11… 64, , Introduction to Programming© Dept. CS, UPC12
Faster Euclidean algorithm for gcd Properties: gcd(a, 0) = a If b 0 then gcd(a, b) = gcd(a%b, b) Example ab 10,000, Introduction to Programming© Dept. CS, UPC13
// Pre: a 0, b 0 // Returns the greatest common divisor of a and b int gcd(int a, int b) { while (a != 0 and b != 0) { if (a > b) a = a%b; else b = b%a; } return a + b; } Faster Euclidean algorithm for gcd Termination: a == 0 or b == 0 not Introduction to Programming© Dept. CS, UPC14
ab Faster Euclidean algorithm for gcd // Pre: a 0, b 0 // Returns the greatest common divisor of a and b int gcd(int a, int b) { while (b > 0) { int r = a%b; a = b; b = r; } return a; } yyxx yyx%yx%y > a b Introduction to Programming© Dept. CS, UPC15
Comparing algorithms for gcd int gcd(int a, int b) { while (b > 0) { int r = a%b; a = b; b = r; } return a; } int gcd(int a, int b) { while (a > 0 and b > 0) { if (a > b) a = a%b; else b = b%a; } return a + b; } Every iteration: 3 comparisons 1 mod operation Every iteration: 1 comparison 1 mod operation Introduction to Programming© Dept. CS, UPC16
Efficiency of the Euclidean algorithm How many iterations will Euclid’s algorithm need to calculate gcd(a,b) in the worst case (assume a > b)? – Subtraction version: a iterations (consider gcd( , 1)) – Modulo version: 5 d(b) iterations, where d(b) is the number of digits of b (Gabriel Lamé, 1844) Introduction to Programming© Dept. CS, UPC17
Binary Euclidean algorithm Computers can perform 2 and /2 operations efficiently (217) 10 = ( ) 2 (2172) 10 = (434) 10 = ( ) 2 (217/2) 10 = (108) 10 = ( ) 2 (217%2) 10 = 1 (least significant bit) Introduction to Programming© Dept. CS, UPC18
Binary Euclidean algorithm Assume a b: abgcd(a,b) a0a even 2gcd(a/2, b/2) evenoddgcd(a/2, b) oddevengcd(a,b/2) odd gcd((a-b)/2, b) ab 22 22 33 12 Introduction to Programming© Dept. CS, UPC19
// Pre: a 0, b 0 // Returns the greatest common divisor of a and b int gcd(int a, int b) { int r = 1; // Accumulates common powers of two while (a != 0 and b != 0) { if (a%2 == 0 and b%2 == 0) { a = a/2; b = b/2; r = r2; } else if (a%2 == 0) a = a/2; else if (b%2 == 0) b = b/2; else if (a > b) a = (a - b)/2; else b = (b – a)/2; } return (a + b)r; } Binary Euclidean algorithm Introduction to Programming© Dept. CS, UPC20
// Pre: a 0, b 0 // Returns the greatest common divisor of a and b int gcd(int a, int b) { if (a == 0 or b == 0) return a + b; int r = 1; // Accumulates common powers of two while (a%2 == 0 and b%2 == 0) { a = a/2; b = b/2; r = r2; } while (a != b) { if (a%2 == 0) a = a/2; else if (b%2 == 0) b = b/2; else if (a > b) a = (a - b)/2; else b = (b – a)/2; } return ar; } Binary Euclidean algorithm Introduction to Programming© Dept. CS, UPC21
Summary Euclid’s algorithm is very simple. It is widely used in some applications related to cryptography (e.g., electronic commerce). Euclid’s algorithm efficiently computes the gcd of very large numbers. Question: how would you compute the least common multiple of two numbers efficiently? Introduction to Programming© Dept. CS, UPC22