// binary operator * // General includes. #include "cl_sysdep.h" // Specification. #include "cln/rational.h" // Implementation. #include "cl_RA.h" #include "cln/integer.h" #include "cl_I.h" namespace cln { const cl_RA operator* (const cl_RA& r, const cl_RA& s) { // Methode (vgl. [Buchberger, Collins, Loos: Computer Algebra, S.201]) // r,s beide Integers -> klar. // r=a/b, s=c -> // Bei c=0 Ergebnis 0. // g:=ggT(b,c). // Falls g=1: Ergebnis (a*c)/b (mit b>1, ggT(a*c,b)=1). // Sonst: b':=b/g, c':=c/g, Ergebnis (a*c')/b' (mit ggT(a*c',b')=1). // r=a, s=c/d analog. // r=a/b, s=c/d -> // g:=ggT(a,d), h:=ggT(b,c). // a':=a/g, d':=d/g (nur bei g>1 bedeutet das Rechnung). // b':=b/h, c':=c/h (nur bei h>1 bedeutet das Rechnung). // Ergebnis ist = (a'*c')/(b'*d'). if (integerp(s)) { // s Integer DeclareType(cl_I,s); if (integerp(r)) { // beides Integer DeclareType(cl_I,r); return r*s; } else { DeclareType(cl_RT,r); var const cl_I& a = numerator(r); var const cl_I& b = denominator(r); var const cl_I& c = s; // r=a/b, s=c, bilde a/b * c. if (zerop(c)) { return 0; } // c=0 -> Ergebnis 0 var cl_I g = gcd(b,c); if (eq(g,1)) // g=1 return I_I_to_RT(a*c,b); // (a*c)/b else // g>1 return I_I_to_RA(a*exquo(c,g),exquopos(b,g)); // (a*(c/g))/(b/g) } } else { // s ist Ratio DeclareType(cl_RT,s); if (integerp(r)) { // r Integer DeclareType(cl_I,r); var const cl_I& a = r; var const cl_I& b = numerator(s); var const cl_I& c = denominator(s); // r=a, s=b/c, bilde a * b/c. if (zerop(a)) { return 0; } // a=0 -> Ergebnis 0 var cl_I g = gcd(a,c); if (eq(g,1)) // g=1 return I_I_to_RT(a*b,c); // (a*b)/c else // g>1 return I_I_to_RA(exquo(a,g)*b,exquopos(c,g)); // ((a/g)*b)/(c/g) } else { // r,s beide Ratios DeclareType(cl_RT,r); var const cl_I& a = numerator(r); var const cl_I& b = denominator(r); var const cl_I& c = numerator(s); var const cl_I& d = denominator(s); var cl_I ap, dp; { var cl_I g = gcd(a,d); if (eq(g,1)) { ap = a; dp = d; } else { ap = exquo(a,g); dp = exquopos(d,g); } } var cl_I cp, bp; { var cl_I h = gcd(b,c); if (eq(h,1)) { cp = c; bp = b; } else { cp = exquo(c,h); bp = exquopos(b,h); } } return I_I_to_RA(ap*cp,bp*dp); // (a'*c')/(b'*d') } } } } // namespace cln