69,371
社区成员
发帖
与我相关
我的任务
分享
#include <stdio.h>
/* 用欧几里德算法求最大公约数 */
unsigned gcd1(unsigned x,unsigned y){
unsigned temp;
while(y!=0){ /* 辗转相除 */
temp=y;
y=x%y;
x=temp;
}
return x;
}
/* 用更快的位运算求最大公约数,没有用任何的除法运算 */
unsigned gcd2(unsigned x,unsigned y){
unsigned temp;
unsigned power_of_two=0;
if(x==0) return y; /* 有一个为0的特殊情况 */
if(y==0) return x;
/* 求x和y的最大的公共幂因子2**powoftwo(**表示求幂) */
while(((x | y) & 1)==0){ /* 末位为0时,说明是偶数,还有因子2 */
x>>=1; /* 除以2 */
y>>=1;
++power_of_two;
} /* 循环结束时x和y中必一个为奇数 */
while((x & 1)==0) /* 若x仍为偶数,则让x变成奇数 */
x>>=1;
/* 对剩下的x和y,用最大公约数的性质(x,y)=(y,x-y)来求x和y的最大公约数 */
while(y){
/* x为奇数,且y为非0 */
while((y & 1)==0)
y>>=1; /* 让y变成奇数 */
/* 现在剩下的x和y均为奇数 */
temp=y;
if(x>y)
y=x-y;
else
y=y-x;
x=temp;
}
return (x<<power_of_two); /* 返回原先x和y的最大公约数 */
}
/* 求最小公倍数 */
unsigned lcm(unsigned x,unsigned y){
return x*y/gcd2(x,y);
}
int main(){
printf("%u\n",gcd1(16,24));
printf("%u\n",gcd2(16,24));
printf("%u\n",lcm(16,24));
return 0;
}