欧几里得算法求最大公约数(GCD)的数学原理

文章已迁移至:https://ryan4yin.space/posts/mathematics-in-euclidean-gcd/

很早就学过欧几里得算法,但是一直不知道它的原理。几乎每本算法书都会提到它,但是貌似只有数学书上才会见到它的原理。。。

前段时间粗粗看了点数论(《什么是数学》),惊讶于这个原理的奇妙。现在把它通俗地写下来,以免自己忘记。

欧几里得算法是求两个数的最大公约数(Greatest Common Divisor (GCD))的算法,我们首先假设有两个数 ab,其中 a 是不小于 b 的数

ab 除的余数为 r,那么 a 可以写成这样的形式:

a=bq+r

其中 q 是整数(我们不需要去管 q 到底是多少,这和我们的目标无关)。

现在假设 ab 的一个约数为 u,那么 ab 都能被 u 整除,即

a=su

b=tu

st 都是整数(同样的,我们只需要知道存在这样的整数 st 就行)。

这样可以得出

r=abq=su(tu)q=(stq)u

所以 r 也能被 u 整除,一般规律如下

ab 的约数也整除它们的余数 r,所以 ab 的任一约数同时也是 br 的约数。 —— 条件一

反过来可以得出

br 的任一约数同时也是 ab 的约数。 ——条件二

这是因为对 br 每一个约数 v,有

b=kv

r=cv

于是有

a=bq+r=(kv)q+cv=(kq+c)v

由条件一和条件二可知

ab 的约数的集合,全等于 br 的约数的集合。

于是

ab 的最大公约数,就是 br 的最大公约数。

接下来用递推法,

a÷br,现在设

b÷rr1

r÷r1r2

……

rn3÷rn2rn1

rn2÷rn1rn=0


因为 ab,可以看出余数 rn 会越来越小,最终变成 0.

rn10rn=0 时,可知 rn2 可被 rn1 整除(余数为 0 嘛)

此时 rn2rn1 的约数就只有:rn1rn1 的因数,所以他们的最大公约数就是 rn1

所以 rn1 就是 ab 的最大公约数。(若 r=0,则 b 为最大公约数)

这个递推法写成c语言函数是这样的(比推导更简洁...):

unsigned int Gcd(unsigned int M,unsigned int N){
    unsigned int Rem;
    while(N){
        Rem = M % N;
        M = N;
        N = Rem;
    }
    return Rem;
}

可以发现这里没有要求 M>=N,这是因为如果那样,循环会自动交换它们的值。

P.S. 此外,还有最小公倍数(Least Common Multiple (LCM))算法,详见 GCD and LCM calculator

posted @   於清樂  阅读(10908)  评论(1编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示