TAOCP-1.2.1_扩充的欧几里得算法
@(algorithm)[TAOCP]
1.算法E(扩充的欧几里得算法)
1.1问题描述:
给定两个正整数m和n,我们计算它们的最大公因子d和两个整数a和b,使得\(am + bn = d\)
1.2 实现步骤:
E1. [初始化] 置\(a' \xleftarrow{} b \xleftarrow{} 1\), \(a \xleftarrow{} b' \xleftarrow{} 0\), \(c \xleftarrow{} m\), \(d \xleftarrow{} n\)
E2. [除] 设q和r分别是c除以d的商和余数。(我们有 \(c = qd + r\), 且 \(0 \leq r \le d\))
E3. [余数为0?] 如果r = 0,算法终止;在此情况下,我们如愿地有 \(am + b n = d\)
E4. [循环] 置\(c \xleftarrow{} d\), \(d \xleftarrow{} r\), \(t \xleftarrow{} a'\), \(a' \xleftarrow{} a\), \(a \xleftarrow{} t\) - \(qa\), \(t \xleftarrow{} b'\), \(b' \xleftarrow{} b\), $b \xleftarrow{} t $ - $ qb$,并返回E2
1.3 C实现
#include<stdio.h>
#include<stdint.h>
int32_t cycles;
int exgcd(int m,int n)
{
uint32_t a, a1, b, b1, c, d;
uint32_t q, r;
uint32_t t;
a1 = b = 1;
a = b1 = 0;
c = m;
d = n;
r = c % d;
q = (c - r) / d;
while (r) {
cycles++;
c = d;
d = r;
t = a1;
a1 = a;
a = t -q * a;
t = b1;
b1 = b;
b = t - q * b;
r = c % d;
q = (c - r) / d;
if (r == 0)
break;
}
return d;
}
int main(void)
{
uint32_t m, n;
uint32_t ret;
printf("Please input 2 positive number(eg: 1769 551):\n");
scanf("%d %d", &m, &n);
ret = exgcd(m, n);
printf("The gcd of %d and %d is: %d, cycles: %d\n", m, n, ret, cycles);
return 0;
}
1.4 运行结果
# make
gcc -Wall -O3 -g e.c -o e
# ./e
Please input 2 positive number(eg: 119 544):
1769 551
The gcd of 1769 and 551 is: 29, cycles: 3