What is most efficient for GCD?

Question Detail: 

I know that Euclid's algorithm is the best algorithm for get the GCD (great common divisor) for a list the positive integer numbers. But, in the practice, you can write two codes por evaluate the gcd (for my case, i decided use java, but c/c++ may be another option).

I need to get the most efficient code of two possibilities form to programming.

Recursive Mode, you can write...

static long gcd(long a, long b){     a = Math.abs(a); b = Math.abs(b);     return (b==0) ? a : gcd(b, a%b);   } 

And, iterative mode, looks like ...

static long gcd(long a, long b) {   long r, i;   while(b!=0){     r = a % b;     a = b;     b = r;   }   return a; } 

We can do that with the Binary GCD, and the easy code is like that

int gcd(int a, int b) {     while(b) b ^= a ^= b ^= a %= b;     return a; } 
Asked By : jonaprieto
Best Answer from StackOverflow

Question Source : http://cs.stackexchange.com/questions/1447

Answered By : Gilles

Your two algorithms are equivalent (at least for positive integers, what happens with negative integers in the imperative version depends on Java's semantics for % which I don't know by heart). In the recursive version, let $a_i$ and $b_i$ be the argument of the $i$th recursive call: $$\begin{gather*} a_{i+1} = b_i \\ b_{i+1} = a_i \mathbin{\mathrm{mod}} b_i \\ \end{gather*}$$

In the imperative version, let $a'_i$ and $b'_i$ be the values of the variables a and b at the beginning of the $i$th iteration of the loop. $$\begin{gather*} a'_{i+1} = b'_i \\ b'_{i+1} = a'_i \mathbin{\mathrm{mod}} b'_i \\ \end{gather*}$$

Notice a resemblance? Your imperative version and your recursive version are calculating exactly the same values. Furthermore, they both end at the same time, when $a_i=0$ (resp. $a'_i=0$), so they perform the same number of iterations. So algorithmically speaking, there is no difference between the two. Any difference will be a matter of implementation, highly dependent on the compiler, the hardware it runs on, and quite possibly the operating system and what other programs are running concurrently.

The recursive version makes only tail recursive calls. Most compilers for imperative languages do not optimize these, and so it is likely that the code they generate will waste a little time and memory constructing a stack frame at each iteration. With a compiler that optimizes tail calls (compilers for functional languages almost always do), the generated machine code may well be the same for both (assuming you harmonize those calls to abs).

No comments

Powered by Blogger.