首先说一下,欧几里得算法:求两个数的最大公约数
教材的写法是:
1 //输入要求a>=b>=0 2 unsigned euclid(unsigned a,unsigned b){ 3 if(b==0) return a; 4 return euclid(b,a%b); 5 }
当然也可以改成非递归的迭代版本:
1 int Gcd(int a, int b) 2 { 3 while(b != 0) 4 { 5 int r = b; 6 b = a % b; 7 a = r; 8 } 9 return a; 10 }
上个世纪60年代研究人员对这个古老的算法进行了改进,称为二进制欧几里得算法:
基于的原理是:
- 若 N 和 M 是偶数,gcd(N, M) = 2 gcd(N/2, M/2) ,
- 若 N 是偶数而 M 是奇数,那么 gcd(N, M) = gcd(N/2, M) ,
- 若 N 和 M 都是奇数,那么 (由于 N-M 是偶数) |N-M| < max(N,M) 。用 |N-M| 替换两者中的较大者
该算法称为 二进制 因为,与原来的不同,它不使用通常的除法而只使用除以2的。由于计算机数字总是用二进制系统表示,你不会对有一种特殊的 机器指令 以高效的方式实现 除以 2而感到惊讶。这称为 右移位,其中最右一位被舍弃,其他的位向右移动一位,而最左一位被设为0。另一个顺手拈来的操作是按位与 & 。对任意整数 N 来说,N & 1 是 1 或 0 。当且仅当 N 是奇数时它为 1 。按位与也在硬件中实现,例如,作为 机器指令
递归版本:


1 unsigned int gcd(unsigned int u, unsigned int v) 2 { 3 // simple cases (termination) 4 if (u == v) return u; 5 if (u == 0) return v; 6 if (v == 0) return u; 7 8 // look for factors of 2 9 if (~u & 1) // u is even 10 { 11 if (v & 1) return gcd(u >> 1, v); // u is even,v is odd 12