欧几里德:辗转相除的办法。
Stein:奇数偶数分开考虑,没有除法,只有移位,加减。
#include <stdio.h>
#include <sys/time.h>
int gcd1(int a, int b)
{
while (1)
{
a = a % b;
if (a == 0)
return b;
b = b % a;
if (b == 0)
return a;
}
}
int gcd0(int M, int N)
{
int Rem;
while (N > 0)
{
Rem = M % N;
M = N;
N = Rem;
}
return M;
}
int gcd2(int a, int b)
{
if (a < b)
{
a ^= b;
b ^= a;
a ^= b;
}
if (b == 0)
return a;
if ((a & 1) == 0 && (b & 1) == 0)
return 2 * gcd2(a >> 1, b >> 1);
else if ((a & 1) == 0)
return gcd2(a >> 1, b);
else if ((b & 1) == 0)
return gcd2(a, b >> 1);
else
return gcd2((a - b) >> 1, b);
}
int gcd3(int a, int b)
{
if (a < b)
{ //arrange so that a>b
int temp = a;
a = b;
b = temp;
}
if (0 == b) //the base case
return a;
if (a % 2 == 0 && b % 2 == 0) //a and b are even
return 2 * gcd3(a / 2, b / 2);
if (a % 2 == 0) // only a is even
return gcd3(a / 2, b);
if (b % 2 == 0) // only b is even
return gcd3(a, b / 2);
return gcd3((a - b) / 2, b); // a and b are odd
}
#define C 100000
#define D 100
int main()
{
struct timeval starttime, endtime;
// gcd0
gettimeofday(&starttime, 0);
{
int c;
c = C;
int d = D;
int i;
int g;
while (--c)
{
for (i = d; i < 10 * d; i++)
{
g = gcd0(i, i + 1);
}
}
}
gettimeofday(&endtime, 0);
if (endtime.tv_usec < starttime.tv_usec)
{
endtime.tv_sec--;
endtime.tv_usec += 1000000;
}
printf("%ld s %ld us\n",
endtime.tv_sec - starttime.tv_sec,
endtime.tv_usec - starttime.tv_usec);
/// gcd1
gettimeofday(&starttime, 0);
{
int c;
c = C;
int d = D;
int i;
int g;
while (--c)
{
for (i = d; i < 10 * d; i++)
{
g = gcd1(i, i + 1);
}
}
}
gettimeofday(&endtime, 0);
if (endtime.tv_usec < starttime.tv_usec)
{
endtime.tv_sec--;
endtime.tv_usec += 1000000;
}
printf("%ld s %ld us\n",
endtime.tv_sec - starttime.tv_sec,
endtime.tv_usec - starttime.tv_usec);
/// gcd 2
gettimeofday(&starttime, 0);
{
int c;
c = C;
int d = D;
int i;
int g;
while (--c)
{
for (i = d; i < 10 * d; i++)
{
g = gcd2(i, i + 1);
}
}
}
gettimeofday(&endtime, 0);
if (endtime.tv_usec < starttime.tv_usec)
{
endtime.tv_sec--;
endtime.tv_usec += 1000000;
}
printf("%ld s %ld us\n",
endtime.tv_sec - starttime.tv_sec,
endtime.tv_usec - starttime.tv_usec);
//gcd 3
gettimeofday(&starttime, 0);
{
int c;
c = C;
int d = D;
int i;
int g;
while (--c)
{
for (i = d; i < 10 * d; i++)
{
g = gcd3(i, i + 1);
}
}
}
gettimeofday(&endtime, 0);
if (endtime.tv_usec < starttime.tv_usec)
{
endtime.tv_sec--;
endtime.tv_usec += 1000000;
}
printf("%ld s %ld us\n",
endtime.tv_sec - starttime.tv_sec,
endtime.tv_usec - starttime.tv_usec);
return 0;
}
运行:
chen@chen-book1:~$ gcc count.c -o count
chen@chen-book1:~$ ./count
2 s 536068 us
1 s 920305 us
26 s 448318 us
24 s 646252 us
改为:
#define C 100
#define D 100000
则:
chen@chen-book1:~$ ./count
2 s 482367 us
1 s 878122 us
55 s 522424 us
52 s 281608 us
chen@chen-book1:~$
换成cpp版的long long
#include <stdio.h>
#include <sys/time.h>
template <class T>
T gcd1(T a, T b)
{
while (1)
{
a = a % b;
if (a == 0)
return b;
b = b % a;
if (b == 0)
return a;
}
}
template <class T>
T gcd0(T a, T b)
{
int rem;
while (b > 0)
{
rem = a % b;
a = b;
b = rem;
}
return a;
}
template <class T>
T gcd2(T a, T b)
{
if (a < b)
{
a ^= b;
b ^= a;
a ^= b;
}
if (b == 0)
return a;
if ((a & 1) == 0 && (b & 1) == 0)
return 2 * gcd2(a >> 1, b >> 1);
else if ((a & 1) == 0)
return gcd2(a >> 1, b);
else if ((b & 1) == 0)
return gcd2(a, b >> 1);
else
return gcd2((a - b) >> 1, b);
}
template <class T>
T gcd3(T a, T b)
{
if (a < b)
{ //arrange so that a>b
T temp = a;
a = b;
b = temp;
}
if (0 == b) //the base case
return a;
if (a % 2 == 0 && b % 2 == 0) //a and b are even
return 2 * gcd3(a / 2, b / 2);
if (a % 2 == 0) // only a is even
return gcd3(a / 2, b);
if (b % 2 == 0) // only b is even
return gcd3(a, b / 2);
return gcd3((a - b) / 2, b); // a and b are odd
}
#define C 2
#define D 10000*10000*10000LL
#define N 2000
int main()
{
struct timeval starttime, endtime;
// gcd0
gettimeofday(&starttime, 0);
{
int c;
c = C;
long long d = D;
long long i;
long long g;
while (--c)
{
for (i = d; i < d+N; i++)
{
g = gcd0(i, i + 1);
}
}
}
gettimeofday(&endtime, 0);
if (endtime.tv_usec < starttime.tv_usec)
{
endtime.tv_sec--;
endtime.tv_usec += 1000000;
}
printf("%ld s %ld us\n",
endtime.tv_sec - starttime.tv_sec,
endtime.tv_usec - starttime.tv_usec);
/// gcd1
gettimeofday(&starttime, 0);
{
int c;
c = C;
long long d = D;
long long i;
long long g;
while (--c)
{
for (i = d; i < d+N; i++)
{
g = gcd1(i, i + 1);
}
}
}
gettimeofday(&endtime, 0);
if (endtime.tv_usec < starttime.tv_usec)
{
endtime.tv_sec--;
endtime.tv_usec += 1000000;
}
printf("%ld s %ld us\n",
endtime.tv_sec - starttime.tv_sec,
endtime.tv_usec - starttime.tv_usec);
/// gcd 2
gettimeofday(&starttime, 0);
{
int c;
c = C;
long long d = D;
long long i;
long long g;
while (--c)
{
for (i = d; i < N + d; i++)
{
g = gcd2(i, i + 1);
}
}
}
gettimeofday(&endtime, 0);
if (endtime.tv_usec < starttime.tv_usec)
{
endtime.tv_sec--;
endtime.tv_usec += 1000000;
}
printf("%ld s %ld us\n",
endtime.tv_sec - starttime.tv_sec,
endtime.tv_usec - starttime.tv_usec);
//gcd 3
gettimeofday(&starttime, 0);
{
int c;
c = C;
long long d = D;
long long i;
long long g;
while (--c)
{
for (i = d; i < N + d; i++)
{
g = gcd3(i, i + 1);
}
}
}
gettimeofday(&endtime, 0);
if (endtime.tv_usec < starttime.tv_usec)
{
endtime.tv_sec--;
endtime.tv_usec += 1000000;
}
printf("%ld s %ld us\n",
endtime.tv_sec - starttime.tv_sec,
endtime.tv_usec - starttime.tv_usec);
return 0;
}
运行:
chen@chen-book1:~$ g++ count.cpp -o count
chen@chen-book1:~$ ./count
0 s 109 us
0 s 188 us
0 s 3998 us
0 s 4206 us
还是这样。。。。第二种Stein还比不上第一种呢。但是我找不到128位以上的整数啊。