gcd.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
partial class PID_GCD
partial class PID_GCD is
evenly_divides(o:SAME):BOOL is
-- self|o. True if self evenly divides `o'.
return mod(o).is_zero;
end;
gcd(o:SAME):SAME is
a:SAME:=self; b:SAME:=o;
loop
if b.is_zero then return a; end;
a:=a%b;
if a.is_zero then return b; end;
b:=b%a;
end;
end;
lcm(o:SAME):SAME is
return (self*o)/gcd(o);
end;
extended_gcd(o:SAME,out f1: SAME, out f2:SAME):SAME is
-- gcd = self*f1 + o*f2
a:SAME:=self; b:SAME:=o; q:SAME;
x:SAME:=one; y:SAME:=zero; u:SAME:=zero; v:SAME:=one;
loop
if b.is_zero then f1:=x; f2:=y; return a; end;
a.divmod(b,out q, out a); x:=x-q*u; y:=y-q*v;
if a.is_zero then f1:=u; f2:=v; return b; end;
b.divmod(a,out q, out b); u:=u-q*x; v:=v-q*y;
end;
end;
gcd(a:ARRAY{SAME}):SAME is
-- multi GCD. return GCD of elements of a[].
g:SAME:=zero; loop g:=a.elt!.gcd(g); end; return g;
end;
extended_gcd(a:ARRAY{SAME},out factor:ARRAY{SAME}):SAME is
-- multi GCD. return GCD g. g = a . factor
factor:=#(a.size);
f1,f2:SAME;
g:SAME:=zero;
loop i::=a.ind!;
g:=a[i].extended_gcd(g,out f1,out f2);
if i.is_pos then
loop j::=0.upto!(i-1); factor[j]:=factor[j]*f2; end;
end;
factor[i]:=f1;
end;
return g;
end;
end;