User:NevilleDNZ/GeSHi sandbox
This task requires the finding of the greatest common divisor of two integers.
Ada[edit]
with Ada.Text_Io; use Ada.Text_Io;
procedure Gcd_Test is
function Gcd (A, B : Integer) return Integer is
begin
if A = 0 then
return B;
end if;
if B = 0 then
return A;
end if;
if A > B then
return Gcd(B, A mod B);
else
return Gcd(A, B mod A);
end if;
end Gcd;
begin
Put_Line("GCD of 100, 5 is" & Integer'Image(Gcd(100, 5)));
Put_Line("GCD of 5, 100 is" & Integer'Image(Gcd(5, 100)));
Put_Line("GCD of 7, 23 is" & Integer'Image(Gcd(7, 23)));
end Gcd_Test;
Output:
GCD of 100, 5 is 5 GCD of 5, 100 is 5 GCD of 7, 23 is 1
ALGOL 68[edit]
PROC gcd = (INT a, b) INT: (
IF a = 0 THEN
b
ELIF b = 0 THEN
a
ELIF a > b THEN
gcd(b, a MOD b)
ELSE
gcd(a, b MOD a)
FI
);
main : (
INT a = 33, b = 77;
printf(($x"The gcd of"g" and "g" is "gl$,a,b,gcd(a,b)));
INT c = 49865, d = 69811;
printf(($x"The gcd of"g" and "g" is "gl$,c,d,gcd(c,d)))
)
The output is:
The gcd of +33 and +77 is +11 The gcd of +49865 and +69811 is +9973
C[edit]
Iterative Euclid algorithm[edit]
int
gcd_iter(int u, int v) {
int t;
while (v) {
t = u;
u = v;
v = t % v;
}
return u < 0 ? -u : u; /* abs(u) */
}
Recursive Euclid algorithm[edit]
int
gcd(int u, int v) {
if (v)
return gcd(v, u % v);
else
return u < 0 ? -u : u; /* abs(u) */
}
Iterative binary algorithm[edit]
int
gcd_bin(int u, int v) {
int t, k;
u = u < 0 ? -u : u; /* abs(u) */
v = v < 0 ? -v : v;
if (u < v) {
t = u;
u = v;
v = t;
}
if (v == 0)
return u;
k = 1;
while (u & 1 == 0 && v & 1 == 0) { /* u, v - even */
u >>= 1; v >>= 1;
k <<= 1;
}
t = (u & 1) ? -v : u;
while (t) {
while (t & 1 == 0)
t >>= 1;
if (t > 0)
u = t;
else
v = -t;
t = u - v;
}
return u * k;
}
Notes on performance[edit]
gcd_iter(40902, 24140)
takes us about 2.87 usec
gcd_bin(40902, 24140)
takes us about 2.47 usec
gcd(40902, 24140)
takes us about 2.86 usec
Forth[edit]
: gcd ( a b -- n )
begin dup while tuck mod repeat drop ;
Fortran[edit]
Iterative Euclid algorithm[edit]
subro utine gcd_iter(value, u, v)
Cf2py integer intent(out) :: value
int eger value, u, v, t
intrinsic abs, mod
C
dowhile( v.NE.0 )
do while( v.NE.0 )
t = u
u = v
v = mod(t, v)
end do
enddo
value = abs(u)
end subroutine gcd_iter
Iterative binary algorithm[edit]
subroutine gcd_bin(value, u, v)
Cf2py integer intent(out) :: value
integer value, u, v, k, t, abs, mod
intrinsic abs, mod
u = abs(u)
v = abs(v)
if( u.lt.v ) then
t = u
u = v
v = t
endif
if( v.eq.0 ) then
value = u
return
endif
k = 1
do while( (mod(u, 2).eq.0).and.(mod(v, 2).eq.0) )
u = u / 2
v = v / 2
k = k * 2
enddo
if( (mod(u, 2).eq.0) ) then
t = u
else
t = -v
endif
do while( t.ne.0 )
do while( (mod(t, 2).eq.0) )
t = t / 2
enddo
if( t.gt.0 ) then
u = t
else
v = -t
endif
t = u - v
enddo
value = u * k
end subroutine gcd_bin
Notes on performance[edit]
gcd_iter(40902, 24140)
takes us about 2.8 usec
gcd_bin(40902, 24140)
takes us about 2.5 usec
J[edit]
x+.y
Java[edit]
Iterative[edit]
public static long gcd(long a, long b){
long factor= 0;
factor= Math.max(a, b);
for(long loop= factor;loop > 1;loop--){
if(a % loop == 0 && b % loop == 0){
return loop;
}
}
return 1;
}
Recursive[edit]
public static long gcd(long a, long b){
if(a == 0) return b;
if(b == 0) return a;
if(a > b) return gcd(b, a % b);
return gcd(a, b % a);
}
OCaml[edit]
let rec gcd a b =
if a = 0 then b
else if b = 0 then a
else if a > b then gcd b (a mod b)
else gcd a (b mod a)
Perl[edit]
Iterative Euclid algorithm[edit]
sub gcd_iter($$) {
($u, $v) = @_;
while ($v) {
$t = $u;
$u = $v;
$v = $t % $v;
}
return abs($u);
}
Recursive Euclid algorithm[edit]
sub gcd($$) {
($u, $v) = @_;
if ($v) {
return gcd($v, $u % $v);
} else {
return abs($u);
}
}
Iterative binary algorithm[edit]
sub gcd_bin($$) {
($u, $v) = @_;
$u = abs($u);
$v = abs($v);
if ($u < $v) {
$t = $u;
$u = $v;
$v = $t;
}
if ($v == 0) {
return $u;
}
$k = 1;
while ($u & 1 == 0 && $v & 1 == 0) {
$u >>= 1;
$v >>= 1;
$k <<= 1;
}
$t = ($u & 1) ? -$v : $u;
while ($t) {
while ($t & 1 == 0) {
$t >>= 1;
}
if ($t > 0) {
$u = $t;
} else {
$v = -$t;
}
$t = $u - $v;
}
return $u * $k;
}
Notes on performance[edit]
use Benchmark qw(cmpthese);
$u = 40902;
$v = 24140;
(-5, {
'gcd' => sub { gcd($u, $v); },
'gcd_iter' => sub { gcd_iter($u, $v); },
'gcd_bin' => sub { gcd_bin($u, $v); },
});
Output on 'Intel(R) Pentium(R) 4 CPU 1.50GHz' / Linux / Perl 5.8.8:
Rate gcd_bin gcd_iter gcd gcd_bin 321639/s -- -12% -20% gcd_iter 366890/s 14% -- -9% gcd 401149/s 25% 9% --
Python[edit]
Iterative Euclid algorithm[edit]
def gcd_iter(u, v):
while v:
u, v = v, u % v
return abs(u)
Recursive Euclid algorithm[edit]
Interpreter: Python 2.5
def gcd(u, v):
return gcd(v, u % v) if v else abs(u)
<python>
===Tests===
>>> gcd(0,0)
0
>>> gcd(0, 10) == gcd(10, 0) == gcd(-10, 0) == gcd(0, -10) == 10
True
>>> gcd(9, 6) == gcd(6, 9) == gcd(-6, 9) == gcd(9, -6) == gcd(6, -9) == gcd(-9, 6) == 3
True
>>> gcd(8, 45) == gcd(45, 8) == gcd(-45, 8) == gcd(8, -45) == gcd(-8, 45) == gcd(45, -8) == 1
True
>>> gcd(40902, 24140) # check Knuth :)
34
===Iterative binary algorithm===
See [[The Art of Computer Programming]] by Knuth (Vol.2)>
<syntaxhighlight lang=python>
def gcd_bin(u, v):
u, v = abs(u), abs(v) # u >= 0, v >= 0
if u < v:
u, v = v, u # u >= v >= 0
if v == 0:
return u
# u >= v > 0
k = 1
while u & 1 == 0 and v & 1 == 0: # u, v - even
u >>= 1; v >>= 1
k <<= 1
t = -v if u & 1 else u
while t:
while t & 1 == 0:
t >>= 1
if t > 0:
u = t
else:
v = -t
t = u - v
return u * k
Notes on performance[edit]
gcd(40902, 24140)
takes us about 17 usec
gcd_iter(40902, 24140)
takes us about 11 usec
gcd_bin(40902, 24140)
takes us about 41 usec