一、两个数的最大公约数和最小公倍数
1.常规求解
求两个数的最小公倍数lcm(int m, int n)可以直接通过,m * n / gcd(m, n)得出
// 求最大公约数 int gcd(int m, int n) { int p = 1; for (int i = 1; i <= m && i <= n; i++) if (!(m % i) && !(n % i)) p = i; return p; }
2.欧几里德算法
// 求最大公约数,欧几里德算法 int gcd(int m, int n) { int p = 1; while ((p = m %n) != 0) { m = n; n = p; } return n; }
3.Stein算法
(参考百度文库http://baike.baidu.com/view/47637.htm#5)
背景:
现在的硬件平台,一般整数最多也就是64位,对于这样的整数,计算两个数之间的模是很简单的。对于字长为32位的平台,计算两个不超过32位的整数的模,只需要一个指令周期,而计算64位以下的整数模,也不过几个周期而已。但是对于更大的素数,这样的计算过程就不得不由用户来设计,为了计算两个超过64位的整数的模,用户也许不得不采用类似于多位数除法手算过程中的试商法,这个过程不但复杂,而且消耗了很多CPU时间。对于现代密码算法,要求计算128位以上的素数的情况比比皆是,设计这样的程序迫切希望能够抛弃除法和取模。
// 求最大公约数,Stein算法 int gcd(int a, int b) { if (a < b) { int temp = a; a = b; b = temp; } if (0 == b) return a; // 如果a和b都是偶数 if (!(a % 2) && !(b % 2)) return 2 * gcd(a / 2, b / 2); // 如果仅有a是偶数 if (!(a % 2)) return gcd(a / 2, b); // 如果仅有b是偶数 if (!(b % 2)) return gcd(a, b / 2); // 如果a和b都是奇数 return gcd((a + b) / 2, (a - b) / 2); }