gcd/辗转相除法的证明
此文仅供蒟蒻参考,dalao请我也不记得是左上角还是右上角了。
前言
这不是小学奥数吗?
数学上来先打表,数论只会gcd。
上面几句话一直打击我学习数论的信心。
不仅只会gcd,连gcd都不会证明,可见我有多菜了。
直到受到某位dalao的指教,我终于证明了gcd。
dalao曰:”数论,数字之理论也。有术曰辗转相除,欲证此术,必先知反对称矣。”
那么问题来了,反对称是什么。
知识储备
下面内容很基础。对于我的证明方法来说,是必须要知道的。
1.整数具有大小(顺序)关系,用≤、≥、<、>、=来表示,其中≤具有反对称性,即:
且 <=>
可以说是非常基础的东西了,但是却是证明gcd的关键方法。
2.符号 的含义:
若 ,则称 为 的约数(或 整除 ),即 的结果为整数(这里注意区分除和除以的区别),记作: ,符号 蕴含条件 。
3.整除的一个性质:
且 =>
这个性质的证明:
由 得 ,由 得 ,则 即 。
4.余数的定义:
对于给定的 ,一定存在唯一的一对 满足:
我们称 为 的商,记作 (有时也记作 表示对实数a向下取整,即取小于等于a的整数中最大的一个), 为 的余数,记作 。
扯了这么多乱七八糟的东西那么现在开始证明gcd。
gcd证明过程
用
表示
的最大公约数,
证明:
由
定义可得,(1)对于任意的
且
,都有
。(2)
且
。
设:
易知:
由储备知识3得:
由储备知识4得:
所以:
由 及
得:
即:
易知:
即:
由储备知识3易得:
因此:
即:
所以:
即:
以上就是gcd核心内容的证明。
上面其实是一个递归的过程,如何判断其何时终止呢?
我们知道除数不能为0,且0和任何的 都有 ,因此当 且 时, ,这就是终止条件。
(据说 无穷大)
编程实现
gcd是很容易编程实现的,明摆着就是一个裸的递归过程,因此用函数递归是最容易实现的。
递归实现:
C++版:
long long gcd(long long n, long long m)
{
if (m == 0) return n;
else return gcd(m, n % m);
}
C++简洁版:
long long gcd(long long n, long long m)
{
return m ? gcd(m, n % m) : n;
}
Pascal版:
function gcd(n, m:int64):int64;
begin
if m = 0 then exit(n)
else exit(gcd(m, n mod m));
end;
当然也有迭代实现(也就是循环实现)的,常数上可能稍微快一些。
迭代实现:
C++版:
long long gcd(long long n, long long m)
{
while (m)
{
n %= m;
swap(n, m);
}
return n;
}
Pascal版:
function gcd(n, m:int64):int64;
var t:int64;
begin
while m <> 0 do
begin
t:= m;
m:= n mod m;
n:= t;
end;
exit(n);
end;
终于把用了这么久的gcd证明出来了。