]> www.ginac.de Git - cln.git/blob - src/integer/elem/cl_I_mul.cc
* include/cln/number.h (As): Fix it in namespace by suffixing `_As'
[cln.git] / src / integer / elem / cl_I_mul.cc
1 // binary operator *
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cln/integer.h"
8
9
10 // Implementation.
11
12 #include "cl_I.h"
13 #include "cl_DS.h"
14 #include "cl_low.h"
15
16 namespace cln {
17
18 const cl_I operator* (const cl_I& x, const cl_I& y)
19 {
20   // Methode:
21   // x=0 oder y=0 -> Ergebnis 0
22   // x und y beide Fixnums -> direkt multiplizieren
23   // sonst: zu DS machen, multiplizieren.
24       if (zerop(x))
25         { return 0; }
26       if (zerop(y))
27         { return 0; }
28       if (fixnump(x) && fixnump(y))
29         { var sint32 x_ = FN_to_L(x);
30           var sint32 y_ = FN_to_L(y);
31           // Werte direkt multiplizieren:
32           var uint32 hi;
33           var uint32 lo;
34           mulu32((uint32)x_,(uint32)y_,hi=,lo=); // erst unsigned multiplizieren
35           if (x_ < 0) { hi -= (uint32)y_; } // dann Korrektur für Vorzeichen
36           if (y_ < 0) { hi -= (uint32)x_; } // (vgl. DS_DS_mul_DS)
37           return L2_to_I(hi,lo);
38         }
39       CL_ALLOCA_STACK;
40       var const uintD* xMSDptr;
41       var uintC xlen;
42       var const uintD* xLSDptr;
43       var const uintD* yMSDptr;
44       var uintC ylen;
45       var const uintD* yLSDptr;
46       var uintD* ergMSDptr;
47       var uintC erglen;
48       I_to_NDS_nocopy(x, xMSDptr = , xlen = , xLSDptr = , cl_false,);
49       I_to_NDS_nocopy(y, yMSDptr = , ylen = , yLSDptr = , cl_false,);
50       DS_DS_mul_DS(xMSDptr,xlen,xLSDptr,yMSDptr,ylen,yLSDptr, ergMSDptr=,erglen=,);
51       return DS_to_I(ergMSDptr,erglen);
52 }
53 // Bit complexity (x,y of length N): O(M(N)).
54
55 }  // namespace cln