]> www.ginac.de Git - cln.git/blob - src/integer/bitwise/cl_I_logtest.cc
* All Files have been modified for inclusion of namespace cln;
[cln.git] / src / integer / bitwise / cl_I_logtest.cc
1 // logtest().
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
15 namespace cln {
16
17 cl_boolean logtest (const cl_I& x, const cl_I& y)
18 {
19     // Methode:
20     //  Fixnums separat behandeln.
21     //  Sei oBdA x die kürzere der beiden Zahlen (in Digits).
22     //  x echt kürzer und x<0 -> [eines der most signif. intDsize+1 Bits von y ist 1] Ja.
23     //  Beide gleich lang oder x>=0 ->
24     //   Kann mich auf die untersten length(x) Digits beschraenken.
25     //   Mit AND durchlaufen, abbrechen (mit "Ja") falls /=0. Am Ende: Nein.
26       if (fixnump(x))
27         if (fixnump(y))
28           // beides Fixnums
29           { if ((x.word & y.word & cl_combine(0,~(cl_uint)0))==0)
30               return cl_false;
31               else
32               return cl_true;
33           }
34           else
35           // x Fixnum, y Bignum, also ist x echt kürzer
36           { if (FN_L_minusp(x,FN_to_L(x))) return cl_true; // x<0 -> ja.
37             // x>=0. Kombiniere x mit den pFN_maxlength letzten Digits von y.
38            {var const uintD* yLSDptr;
39             var uintL x_ = FN_to_L(x);
40             BN_to_NDS_nocopy(y, ,,yLSDptr=);
41             #if (pFN_maxlength > 1)
42             doconsttimes(pFN_maxlength-1,
43               if (lsprefnext(yLSDptr) & (uintD)x_) return cl_true;
44               x_ = x_ >> intDsize;
45               );
46             #endif
47             if (lsprefnext(yLSDptr) & (uintD)x_) return cl_true;
48             return cl_false;
49           }}
50         else
51         if (fixnump(y))
52           // x Bignum, y Fixnum, analog wie oben, nur x und y vertauscht
53           { if (FN_L_minusp(y,FN_to_L(y))) return cl_true; // y<0 -> ja.
54             // y>=0. Kombiniere y mit den pFN_maxlength letzten Digits von x.
55            {var const uintD* xLSDptr;
56             var uintL y_ = FN_to_L(y);
57             BN_to_NDS_nocopy(x, ,,xLSDptr=);
58             #if (pFN_maxlength > 1)
59             doconsttimes(pFN_maxlength-1,
60               if (lsprefnext(xLSDptr) & (uintD)y_) return cl_true;
61               y_ = y_ >> intDsize;
62               );
63             #endif
64             if (lsprefnext(xLSDptr) & (uintD)y_) return cl_true;
65             return cl_false;
66           }}
67           else
68           // x,y Bignums
69           { var const uintD* xMSDptr;
70             var uintC xlen;
71             var const uintD* yMSDptr;
72             var uintC ylen;
73             BN_to_NDS_nocopy(x, xMSDptr=,xlen=,);
74             BN_to_NDS_nocopy(y, yMSDptr=,ylen=,);
75             // Beachte: xlen>0, ylen>0.
76             if (!(xlen==ylen))
77               // beide verschieden lang
78               { if (xlen<ylen)
79                   { // x ist die echt kürzere DS.
80                     if ((sintD)mspref(xMSDptr,0)<0) // der echt kürzere ist negativ?
81                       return cl_true;
82                     // Der echt kürzere ist positiv.
83                     yMSDptr = yMSDptr mspop (ylen-xlen);
84                   }
85                   else
86                   { // y ist die echt kürzere DS.
87                     if ((sintD)mspref(yMSDptr,0)<0) // der echt kürzere ist negativ?
88                       return cl_true;
89                     // Der echt kürzere ist positiv.
90                     xMSDptr = xMSDptr mspop (xlen-ylen);
91                     xlen = ylen;
92               }   }
93             // Nach gemeinsamen Bits in xMSDptr/xlen/.. und yMSDptr/xlen/..
94             // suchen:
95             return and_test_loop_msp(xMSDptr,yMSDptr,xlen);
96           }
97 }
98
99 }  // namespace cln