-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathgcd.c
93 lines (64 loc) · 1.89 KB
/
gcd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/* gcd.c
Compute the greatest common divisor of two integers
by: Steven Skiena
begun: July 10, 2002
*/
/*
Copyright 2003 by Steven S. Skiena; all rights reserved.
Permission is granted for use in non-commerical applications
provided this copyright notice remains intact and unchanged.
This program appears in my book:
"Programming Challenges: The Programming Contest Training Manual"
by Steven Skiena and Miguel Revilla, Springer-Verlag, New York 2003.
See our website www.programming-challenges.com for additional information.
This book can be ordered from Amazon.com at
http://www.amazon.com/exec/obidos/ASIN/0387001638/thealgorithmrepo/
*/
#include <math.h>
#include <stdio.h>
/* integers to compute the GCD of */
long gcd1(long p, long q) {
if (q > p) {
return(gcd1(q, p));
}
if (q == 0) {
return(p);
}
printf(" gcd(%ld,%ld) &=& gcd(%ld \\mod %ld, %ld) = gcd(%ld,%ld) \n",
p, q, p, q, q, q, p % q);
return(gcd1(q, p % q));
}
/* Find the gcd(p,q) and x,y such that p*x + q*y = gcd(p,q) */
long gcd(long p, long q, long *x, long *y) {
long x1, y1; /* previous coefficients */
long g; /* value of gcd(p,q) */
if (q > p) {
return(gcd(q, p, y, x));
}
if (q == 0) {
*x = 1;
*y = 0;
return(p);
}
g = gcd(q, p%q, &x1, &y1);
*x = y1;
*y = (x1 - floor(p/q)*y1);
return(g);
}
int main(void) {
long p, q;
long x, y, g1, g2;
while (scanf("%ld %ld", &p, &q) != EOF) {
g1 = gcd1(p, q);
g2 = gcd(p, q, &x, &y);
printf("gcd of p=%ld and q=%ld = %ld\n", p, q, g1);
printf(" %ld*%ld + %ld*%ld = %ld\n", p, x, q, y, g2);
if (g1 != g2) {
printf("ERROR: GCD\n");
}
if ((p*x + q*y) != g1) {
printf("ERROR: DIOPHONINE SOLUTION WRONG!\n");
}
}
return 0;
}