Euclid’s GCD Algorithm:
int Euclid_gcd_recursive(int a, int b)
{
if (b == 0)
return a;
return Euclid_gcd_recursive(b, a % b);
}
int Euclid_gcd_iterative(int a, int b)
{
int t;
while (b) {
a = b;
b = t % b;
}
return a;
}
Stein’s GCD Algorithm:
int Stein_gcd(int a, int b)
{
int t, c = 1;
if (a < b) {
t = a;
a = b;
b = t;
}
while (b) {
if (a % 2) {
if (b % 2) {
a -= b;
}
else {
b >>= 1;
}
}
else if (b % 2) {
a >>= 1;
}
else {
c <<= 1;
a >>= 1;
b >>= 1;
}
if (a < b) {
t = a;
a = b;
b = t;
}
}
return a * c;
}
Extensions:
or
Example 1: a = 51, b = 21
| 51 = 2 * 21 + 9 | 9 = 51 - 2 * 21 |
| 21 = 2 * 9 + 3 |
3 = 21 - 2 * 9 = 21 - 2 * (51 - 2 * 21) = -2 * 51 + 5 * 21 |
| 9 = 3 * 3 + 0 |
0 = 9 - 3 * 3 = 51 - 2 * 21 - 3 * (-2 * 51 + 5 * 21) = 7 * 51 - 17 * 21 |
Thus x = -2, y = 5 works, and gcd(51, 21) = 3;
u = 7, v = -17 works, and lcm(51, 21) = 51 * 7 = 21 * 17 = 357.
Example 2: a = 101, b = 12
| 101 = 8 * 12 + 5 | 5 = 101 - 8 * 12 |
| 12 = 2 * 5 + 2 |
2 = 12 - 2 * 5 = 12 - 2 * (101 - 8 * 12) = -2 * 101 + 17 * 12 |
| 5 = 2 * 2 + 1 |
1 = 5 - 2 * 2 = 101 - 8 * 12 - 2 * (-2 * 101 + 17 * 12) = 5 * 101 - 42 * 12 |
| 2 = 2 * 1 + 0 |
0 = 2 - 2 * 1 = -2 * 101 + 17 * 12 - 2 * (5 * 101 - 42 * 12) = -12 * 101 + 101 * 12 |
Thus x = 5, y = -42 works, and gcd(101, 12) = 1;
u = -12, v = 101, and lcm(101, 12) = 12 * 101 = 1212.
Thus, we've got an lcm algorithm derived from Euclid's gcd algorithm.
Euclid-based LCM Algorithm:
int lcm(int a, int b)
{
int t;
int u, v;
if (a < b) {
t = a;
a = b;
b = t;
}
u = a;
v = b;
while (b) {
u += a / b * v;
t = u;
u = v;
v = t;
t = a;
a = b;
b = t % b;
}
return v / 2;
}
Variant of Euclid-based LCM Algorithm:
int lcm(int a, int b)
{
int u = a, v = b;
while (a != b) {
if (a > b) {
a -= b;
u += v;
}
else {
b -= a;
v += u;
}
}
return (u + v) / 2;
}
© Wangling. Powered by WordPress using the DePo Skinny Theme.