]> www.ginac.de Git - cln.git/blob - src/rational/elem/cl_RA_mul.cc
6f0dfab81b6a6da470baf45b3106cdc31b9d94b8
[cln.git] / src / rational / elem / cl_RA_mul.cc
1 // binary operator *
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_rational.h"
8
9
10 // Implementation.
11
12 #include "cl_RA.h"
13 #include "cl_integer.h"
14 #include "cl_I.h"
15
16 const cl_RA operator* (const cl_RA& r, const cl_RA& s)
17 {
18 // Methode (vgl. [Buchberger, Collins, Loos: Computer Algebra, S.201])
19 // r,s beide Integers -> klar.
20 // r=a/b, s=c ->
21 //   Bei c=0 Ergebnis 0.
22 //   g:=ggT(b,c).
23 //   Falls g=1: Ergebnis (a*c)/b (mit b>1, ggT(a*c,b)=1).
24 //   Sonst: b':=b/g, c':=c/g, Ergebnis (a*c')/b' (mit ggT(a*c',b')=1).
25 // r=a, s=c/d analog.
26 // r=a/b, s=c/d ->
27 //   g:=ggT(a,d), h:=ggT(b,c).
28 //   a':=a/g, d':=d/g (nur bei g>1 bedeutet das Rechnung).
29 //   b':=b/h, c':=c/h (nur bei h>1 bedeutet das Rechnung).
30 //   Ergebnis ist = (a'*c')/(b'*d').
31         if (integerp(s)) {
32                 // s Integer
33                 DeclareType(cl_I,s);
34                 if (integerp(r)) {
35                         // beides Integer
36                         DeclareType(cl_I,r);
37                         return r*s;
38                 } else {
39                         DeclareType(cl_RT,r);
40                         var const cl_I& a = numerator(r);
41                         var const cl_I& b = denominator(r);
42                         var const cl_I& c = s;
43                         // r=a/b, s=c, bilde a/b * c.
44                         if (zerop(c))
45                                 { return 0; } // c=0 -> Ergebnis 0
46                         var cl_I g = gcd(b,c);
47                         if (eq(g,1))
48                                 // g=1
49                                 return I_I_to_RT(a*c,b); // (a*c)/b
50                         else
51                                 // g>1
52                                 return I_I_to_RA(a*exquo(c,g),exquopos(b,g)); // (a*(c/g))/(b/g)
53                 }
54         } else {
55                 // s ist Ratio
56                 DeclareType(cl_RT,s);
57                 if (integerp(r)) {
58                         // r Integer
59                         DeclareType(cl_I,r);
60                         var const cl_I& a = r;
61                         var const cl_I& b = numerator(s);
62                         var const cl_I& c = denominator(s);
63                         // r=a, s=b/c, bilde a * b/c.
64                         if (zerop(a))
65                                 { return 0; } // a=0 -> Ergebnis 0
66                         var cl_I g = gcd(a,c);
67                         if (eq(g,1))
68                                 // g=1
69                                 return I_I_to_RT(a*b,c); // (a*b)/c
70                         else
71                                 // g>1
72                                 return I_I_to_RA(exquo(a,g)*b,exquopos(c,g)); // ((a/g)*b)/(c/g)
73                 } else {
74                         // r,s beide Ratios
75                         DeclareType(cl_RT,r);
76                         var const cl_I& a = numerator(r);
77                         var const cl_I& b = denominator(r);
78                         var const cl_I& c = numerator(s);
79                         var const cl_I& d = denominator(s);
80                         var cl_I ap, dp;
81                         {
82                                 var cl_I g = gcd(a,d);
83                                 if (eq(g,1))
84                                         { ap = a; dp = d; }
85                                 else
86                                         { ap = exquo(a,g); dp = exquopos(d,g); }
87                         }
88                         var cl_I cp, bp;
89                         {
90                                 var cl_I h = gcd(b,c);
91                                 if (eq(h,1))
92                                         { cp = c; bp = b; }
93                                 else
94                                         { cp = exquo(c,h); bp = exquopos(b,h); }
95                         }
96                         return I_I_to_RA(ap*cp,bp*dp); // (a'*c')/(b'*d')
97                 }
98         }
99 }