]> www.ginac.de Git - cln.git/blob - include/cln/integer.h
* include/cln/integer.h (cl_I_to_E, cl_I_to_UE): New functions.
[cln.git] / include / cln / integer.h
1 // Public integer operations.
2
3 #ifndef _CL_INTEGER_H
4 #define _CL_INTEGER_H
5
6 #include "cln/number.h"
7 #include "cln/integer_class.h"
8 #include "cln/random.h"
9
10 namespace cln {
11
12 CL_DEFINE_AS_CONVERSION(cl_I)
13
14
15 // Konversion Integer >=0, <2^32 nach uintL.
16 // Wandelt Integer >=0 in Unsigned Longword um.
17 // cl_I_to_UL(obj)
18 // > obj: Integer, sollte >=0, <2^32 sein
19 // < ergebnis: der Wert des Integer als 32-Bit-Zahl.
20   extern uint32 cl_I_to_UL (const cl_I& obj);
21
22 // Konversion Integer >=-2^31, <2^31 nach sintL.
23 // Wandelt Integer in Signed Longword um.
24 // cl_I_to_L(obj)
25 // > obj: Integer, sollte >=-2^31, <2^31 sein
26 // < ergebnis: der Wert des Integer als 32-Bit-Zahl.
27   extern sint32 cl_I_to_L (const cl_I& obj);
28
29 // Convert an integer to a C `int' or `unsigned int'.
30 #if (int_bitsize==32)
31   inline int          cl_I_to_int  (const cl_I& x) { return cl_I_to_L(x);  }
32   inline unsigned int cl_I_to_uint (const cl_I& x) { return cl_I_to_UL(x); }
33 #endif
34
35 // Convert an integer to a 64-bit 'quad' type.
36 #ifdef intQsize
37  extern uint64 cl_I_to_UQ (const cl_I& obj);
38  extern sint64 cl_I_to_Q (const cl_I& obj);
39 #endif
40
41 // Convert an integer to a C `long' or `unsigned long'.
42 #if (long_bitsize==32)
43   inline long          cl_I_to_long  (const cl_I& x) { return cl_I_to_L(x);  }
44   inline unsigned long cl_I_to_ulong (const cl_I& x) { return cl_I_to_UL(x); }
45 #elif (long_bitsize==64)
46   inline long          cl_I_to_long  (const cl_I& x) { return cl_I_to_Q(x);  }
47   inline unsigned long cl_I_to_ulong (const cl_I& x) { return cl_I_to_UQ(x); }
48 #endif
49
50 // Convert an integer to a counter type.
51 #if (intCsize==long_bitsize)
52   inline uintC cl_I_to_UC (const cl_I& x) { return cl_I_to_ulong(x); }
53   inline sintC cl_I_to_C  (const cl_I& x) { return cl_I_to_long(x);  }
54 #elif (intCsize==int_bitsize)
55   inline uintC cl_I_to_UC (const cl_I& x) { return cl_I_to_uint(x); }
56   inline sintC cl_I_to_C  (const cl_I& x) { return cl_I_to_int(x);  }
57 #endif
58
59 // Convert an integer to an exponent type.
60 #if (intEsize==intLsize)
61   inline uintE cl_I_to_UE (const cl_I& x) { return cl_I_to_UL(x); }
62   inline sintE cl_I_to_E  (const cl_I& x) { return cl_I_to_L(x);  }
63 #elif (intEsize==intQsize)
64   inline uintE cl_I_to_UE (const cl_I& x) { return cl_I_to_UQ(x); }
65   inline sintE cl_I_to_E  (const cl_I& x) { return cl_I_to_Q(x);  }
66 #endif
67
68
69 // Logische Operationen auf Integers:
70
71 // (LOGIOR x y), wenn x, y Integers sind.
72 // Ergebnis Integer.
73 extern const cl_I logior (const cl_I& x, const cl_I& y);
74
75 // (LOGXOR x y), wenn x, y Integers sind.
76 // Ergebnis Integer.
77 extern const cl_I logxor (const cl_I& x, const cl_I& y);
78
79 // (LOGAND x y), wenn x, y Integers sind.
80 // Ergebnis Integer.
81 extern const cl_I logand (const cl_I& x, const cl_I& y);
82
83 // (LOGEQV x y), wenn x, y Integers sind.
84 // Ergebnis Integer.
85 extern const cl_I logeqv (const cl_I& x, const cl_I& y);
86
87 // (LOGNAND x y), wenn x, y Integers sind.
88 // Ergebnis Integer.
89 extern const cl_I lognand (const cl_I& x, const cl_I& y);
90
91 // (LOGNOR x y), wenn x, y Integers sind.
92 // Ergebnis Integer.
93 extern const cl_I lognor (const cl_I& x, const cl_I& y);
94
95 // (LOGANDC2 x y), wenn x, y Integers sind.
96 // Ergebnis Integer.
97 extern const cl_I logandc2 (const cl_I& x, const cl_I& y);
98
99 // (LOGANDC1 x y), wenn x, y Integers sind.
100 // Ergebnis Integer.
101 inline const cl_I logandc1 (const cl_I& x, const cl_I& y)
102 {
103         return logandc2(y,x);
104 }
105
106 // (LOGORC2 x y), wenn x, y Integers sind.
107 // Ergebnis Integer.
108 extern const cl_I logorc2 (const cl_I& x, const cl_I& y);
109
110 // (LOGORC1 x y), wenn x, y Integers sind.
111 // Ergebnis Integer.
112 inline const cl_I logorc1 (const cl_I& x, const cl_I& y)
113 {
114         return logorc2(y,x);
115 }
116
117 // (LOGNOT x), wenn x ein Integer sind.
118 // Ergebnis Integer.
119 extern const cl_I lognot (const cl_I& x);
120
121 // Konstanten für BOOLE:
122 typedef enum {
123         boole_clr,
124         boole_set,
125         boole_1,
126         boole_2,
127         boole_c1,
128         boole_c2,
129         boole_and,
130         boole_ior,
131         boole_xor,
132         boole_eqv,
133         boole_nand,
134         boole_nor,
135         boole_andc1,
136         boole_andc2,
137         boole_orc1,
138         boole_orc2
139 } cl_boole;
140
141 // (BOOLE op x y), wenn x und y Integers und op ein Objekt sind.
142 // Ergebnis Integer.
143 extern const cl_I boole (cl_boole op, const cl_I& x, const cl_I& y);
144
145 // Prüft, ob (LOGTEST x y), wo x und y Integers sind.
146 // (LOGTEST x y) = (NOT (ZEROP (LOGAND x y))).
147 // < ergebnis: /=0, falls ja; =0, falls nein.
148 extern cl_boolean logtest (const cl_I& x, const cl_I& y);
149
150 // Prüft, ob (LOGBITP x y), wo x und y Integers sind.
151 // Ergebnis: /=0, wenn ja; =0, wenn nein.
152 extern cl_boolean logbitp (uintC x, const cl_I& y);
153 extern cl_boolean logbitp (const cl_I& x, const cl_I& y);
154
155 // Prüft, ob (ODDP x), wo x ein Integer ist.
156 // Ergebnis: /=0, falls ja; =0, falls nein.
157 extern cl_boolean oddp (const cl_I& x);
158
159 // Prüft, ob (EVENP x), wo x ein Integer ist.
160 // Ergebnis: /=0, falls ja; =0, falls nein.
161 inline cl_boolean evenp (const cl_I& x)
162         { return (cl_boolean) (!oddp(x)); }
163
164 // (ASH x y), wo x und y Integers sind. Ergebnis Integer.
165 extern const cl_I ash (const cl_I& x, sintC y);
166 extern const cl_I ash (const cl_I& x, const cl_I& y);
167
168 // (LOGCOUNT x), wo x ein Integer ist. Ergebnis uintL.
169 extern uintC logcount (const cl_I& x);
170
171 // (INTEGER-LENGTH x), wo x ein Integer ist. Ergebnis uintL.
172 extern uintC integer_length (const cl_I& x);
173
174 // (ORD2 x) = max{n>=0: 2^n | x }, wo x ein Integer /=0 ist. Ergebnis uintL.
175 extern uintC ord2 (const cl_I& x);
176
177 // power2p(x) stellt fest, ob ein Integer x>0 eine Zweierpotenz ist.
178 // Ergebnis: n>0, wenn x=2^(n-1), 0 sonst.
179 extern uintC power2p (const cl_I& x);
180
181 inline const cl_I operator| (const cl_I& x, const cl_I& y)
182         { return logior(x,y); }
183 inline const cl_I operator^ (const cl_I& x, const cl_I& y)
184         { return logxor(x,y); }
185 inline const cl_I operator& (const cl_I& x, const cl_I& y)
186         { return logand(x,y); }
187 inline const cl_I operator~ (const cl_I& x)
188         { return lognot(x); }
189 #ifdef WANT_OBFUSCATING_OPERATORS
190 // This could be optimized to use in-place operations.
191 inline cl_I& operator|= (cl_I& x, const cl_I& y) { return x = x | y; }
192 inline cl_I& operator^= (cl_I& x, const cl_I& y) { return x = x ^ y; }
193 inline cl_I& operator&= (cl_I& x, const cl_I& y) { return x = x & y; }
194 #endif
195
196
197 // Addition/Subtraktion von Integers
198
199 // (1+ x), wo x ein Integer ist. Ergebnis Integer.
200 extern const cl_I plus1 (const cl_I& x);
201
202 // (1- x), wo x ein Integer ist. Ergebnis Integer.
203 extern const cl_I minus1 (const cl_I& x);
204
205 // (+ x y), wo x und y Integers sind. Ergebnis Integer.
206 extern const cl_I operator+ (const cl_I& x, const cl_I& y);
207 // Dem C++-Compiler muß man auch das Folgende sagen:
208 inline const cl_I operator+ (const int x, const cl_I& y)
209         { return cl_I(x) + y; }
210 inline const cl_I operator+ (const unsigned int x, const cl_I& y)
211         { return cl_I(x) + y; }
212 inline const cl_I operator+ (const long x, const cl_I& y)
213         { return cl_I(x) + y; }
214 inline const cl_I operator+ (const unsigned long x, const cl_I& y)
215         { return cl_I(x) + y; }
216 #ifdef HAVE_LONGLONG
217 inline const cl_I operator+ (const long long x, const cl_I& y)
218         { return cl_I(x) + y; }
219 inline const cl_I operator+ (const unsigned long long x, const cl_I& y)
220         { return cl_I(x) + y; }
221 #endif
222 inline const cl_I operator+ (const cl_I& x, const int y)
223         { return x + cl_I(y); }
224 inline const cl_I operator+ (const cl_I& x, const unsigned int y)
225         { return x + cl_I(y); }
226 inline const cl_I operator+ (const cl_I& x, const long y)
227         { return x + cl_I(y); }
228 inline const cl_I operator+ (const cl_I& x, const unsigned long y)
229         { return x + cl_I(y); }
230 #ifdef HAVE_LONGLONG
231 inline const cl_I operator+ (const cl_I& x, const long long y)
232         { return x + cl_I(y); }
233 inline const cl_I operator+ (const cl_I& x, const unsigned long long y)
234         { return x + cl_I(y); }
235 #endif
236
237 // (- x), wenn x ein Integer ist. Ergebnis Integer.
238 extern const cl_I operator- (const cl_I& x);
239
240 // (- x y), wo x und y Integers sind. Ergebnis Integer.
241 extern const cl_I operator- (const cl_I& x, const cl_I& y);
242 // Dem C++-Compiler muß man auch das Folgende sagen:
243 inline const cl_I operator- (const int x, const cl_I& y)
244         { return cl_I(x) - y; }
245 inline const cl_I operator- (const unsigned int x, const cl_I& y)
246         { return cl_I(x) - y; }
247 inline const cl_I operator- (const long x, const cl_I& y)
248         { return cl_I(x) - y; }
249 inline const cl_I operator- (const unsigned long x, const cl_I& y)
250         { return cl_I(x) - y; }
251 #ifdef HAVE_LONGLONG
252 inline const cl_I operator- (const long long x, const cl_I& y)
253         { return cl_I(x) - y; }
254 inline const cl_I operator- (const unsigned long long x, const cl_I& y)
255         { return cl_I(x) - y; }
256 #endif
257 inline const cl_I operator- (const cl_I& x, const int y)
258         { return x - cl_I(y); }
259 inline const cl_I operator- (const cl_I& x, const unsigned int y)
260         { return x - cl_I(y); }
261 inline const cl_I operator- (const cl_I& x, const long y)
262         { return x - cl_I(y); }
263 inline const cl_I operator- (const cl_I& x, const unsigned long y)
264         { return x - cl_I(y); }
265 #ifdef HAVE_LONGLONG
266 inline const cl_I operator- (const cl_I& x, const long long y)
267         { return x - cl_I(y); }
268 inline const cl_I operator- (const cl_I& x, const unsigned long long y)
269         { return x - cl_I(y); }
270 #endif
271
272 // (abs x), wenn x ein Integer ist. Ergebnis Integer.
273 extern const cl_I abs (const cl_I& x);
274
275 // Shifts.
276 inline const cl_I operator<< (const cl_I& x, sintC y) // assume 0 <= y < 2^(intCsize-1)
277         { return ash(x,y); }
278 inline const cl_I operator<< (const cl_I& x, const cl_I& y) // assume y >= 0
279         { return ash(x,y); }
280 inline const cl_I operator>> (const cl_I& x, sintC y) // assume 0 <= y < 2^(intCsize-1)
281         { return ash(x,-y); }
282 inline const cl_I operator>> (const cl_I& x, const cl_I& y) // assume y >= 0
283         { return ash(x,-y); }
284
285
286 // Vergleich von Integers
287
288 // equal(x,y) vergleicht zwei Integers x und y auf Gleichheit.
289 extern cl_boolean equal (const cl_I& x, const cl_I& y);
290 // equal_hashcode(x) liefert einen equal-invarianten Hashcode für x.
291 extern uint32 equal_hashcode (const cl_I& x);
292
293 // compare(x,y) vergleicht zwei Integers x und y.
294 // Ergebnis: 0 falls x=y, +1 falls x>y, -1 falls x<y.
295 extern cl_signean compare (const cl_I& x, const cl_I& y);
296
297 inline bool operator== (const cl_I& x, const cl_I& y)
298         { return equal(x,y); }
299 inline bool operator!= (const cl_I& x, const cl_I& y)
300         { return !equal(x,y); }
301 inline bool operator<= (const cl_I& x, const cl_I& y)
302         { return compare(x,y)<=0; }
303 inline bool operator< (const cl_I& x, const cl_I& y)
304         { return compare(x,y)<0; }
305 inline bool operator>= (const cl_I& x, const cl_I& y)
306         { return compare(x,y)>=0; }
307 inline bool operator> (const cl_I& x, const cl_I& y)
308         { return compare(x,y)>0; }
309
310 // minusp(x) == (< x 0)
311 extern cl_boolean minusp (const cl_I& x);
312
313 // plusp(x) == (> x 0)
314 extern cl_boolean plusp (const cl_I& x);
315
316 // zerop(x) stellt fest, ob ein Integer = 0 ist.
317 extern cl_boolean zerop (const cl_I& x);
318
319
320 // BYTE-Operationen auf Integers
321
322 struct cl_byte {
323         uintC size;
324         uintC position;
325 // Konstruktor:
326         cl_byte (uintC s, uintC p) : size (s), position (p) {}
327 };
328
329 // (LDB byte n), wo n ein Integer ist.
330 extern const cl_I ldb (const cl_I& n, const cl_byte& b);
331
332 // ldb_test(n,byte) führt (LDB-TEST byte n) aus, wobei n ein Integer ist.
333 // Ergebnis: cl_false wenn nein (also alle fraglichen Bits =0), cl_true wenn ja.
334 extern cl_boolean ldb_test (const cl_I& n, const cl_byte& b);
335
336 // (MASK-FIELD byte n), wo n ein Integer ist.
337 extern const cl_I mask_field (const cl_I& n, const cl_byte& b);
338
339 // (DEPOSIT-FIELD newbyte byte n), wo n und newbyte Integers sind.
340 extern const cl_I deposit_field (const cl_I& newbyte, const cl_I& n, const cl_byte& b);
341
342 // (DPB newbyte byte n), wo n und newbyte Integers sind.
343 extern const cl_I dpb (const cl_I& newbyte, const cl_I& n, const cl_byte& b);
344
345
346 // Multiplikation ganzer Zahlen
347
348 // (* x y), wo x und y Integers sind. Ergebnis Integer.
349 extern const cl_I operator* (const cl_I& x, const cl_I& y);
350 // Dem C++-Compiler muß man auch das Folgende sagen:
351 inline const cl_I operator* (const int x, const cl_I& y)
352         { return cl_I(x) * y; }
353 inline const cl_I operator* (const unsigned int x, const cl_I& y)
354         { return cl_I(x) * y; }
355 inline const cl_I operator* (const long x, const cl_I& y)
356         { return cl_I(x) * y; }
357 inline const cl_I operator* (const unsigned long x, const cl_I& y)
358         { return cl_I(x) * y; }
359 #ifdef HAVE_LONGLONG
360 inline const cl_I operator* (const long long x, const cl_I& y)
361         { return cl_I(x) * y; }
362 inline const cl_I operator* (const unsigned long long x, const cl_I& y)
363         { return cl_I(x) * y; }
364 #endif
365 inline const cl_I operator* (const cl_I& x, const int y)
366         { return x * cl_I(y); }
367 inline const cl_I operator* (const cl_I& x, const unsigned int y)
368         { return x * cl_I(y); }
369 inline const cl_I operator* (const cl_I& x, const long y)
370         { return x * cl_I(y); }
371 inline const cl_I operator* (const cl_I& x, const unsigned long y)
372         { return x * cl_I(y); }
373 #ifdef HAVE_LONGLONG
374 inline const cl_I operator* (const cl_I& x, const long long y)
375         { return x * cl_I(y); }
376 inline const cl_I operator* (const cl_I& x, const unsigned long long y)
377         { return x * cl_I(y); }
378 #endif
379
380 // (EXPT x 2), wo x Integer ist.
381 extern const cl_I square (const cl_I& x);
382
383 // (EXPT x y), wo x Integer, y Integer >0 ist.
384 extern const cl_I expt_pos (const cl_I& x, uintL y);
385 extern const cl_I expt_pos (const cl_I& x, const cl_I& y);
386
387 // Fakultät (! n), wo n Fixnum >=0 ist. Ergebnis Integer.
388 extern const cl_I factorial (uintL n);
389 //CL_REQUIRE(cl_I_factorial)
390
391 // Double factorial (!! n), with n Fixnum >=0.  Returns integer.
392 extern const cl_I doublefactorial (uintL n);
393
394 // Binomialkoeffizient (n \choose k) = n! / k! (n-k)!, wo n,k >= 0 sind.
395 extern const cl_I binomial (uintL n, uintL k);
396
397
398 // Division ganzer Zahlen
399
400 // Return type for division operators.
401 // x / y  --> (q,r) with x = y*q+r.
402 struct cl_I_div_t {
403         cl_I quotient;
404         cl_I remainder;
405 // Constructor.
406         cl_I_div_t () {}
407         cl_I_div_t (const cl_I& q, const cl_I& r) : quotient(q), remainder(r) {}
408 };
409
410 // Dividiert zwei Integers x,y >=0 und liefert den Quotienten x/y >=0.
411 // Bei y=0 Error. Die Division muß aufgehen, sonst Error.
412 // exquopos(x,y)
413 // > x,y: Integers >=0
414 // < ergebnis: Quotient x/y, ein Integer >=0
415   extern const cl_I exquopos (const cl_I& x, const cl_I& y);
416
417 // Dividiert zwei Integers x,y und liefert den Quotienten x/y.
418 // Bei y=0 Error. Die Division muß aufgehen, sonst Error.
419 // exquo(x,y)
420 // > x,y: Integers
421 // < ergebnis: Quotient x/y, ein Integer
422   extern const cl_I exquo (const cl_I& x, const cl_I& y);
423
424 // mod(x,y) = (mod x y), wo x,y Integers sind.
425   extern const cl_I mod (const cl_I& x, const cl_I& y);
426
427 // rem(x,y) = (rem x y), wo x,y Integers sind.
428   extern const cl_I rem (const cl_I& x, const cl_I& y);
429
430 // Dividiert zwei Integers x,y und liefert Quotient und Rest
431 // (q,r) := (floor x y)
432 // floor2(x,y)
433 // > x,y: Integers
434 // < q,r: Quotient q, Rest r
435   extern const cl_I_div_t floor2 (const cl_I& x, const cl_I& y);
436   extern const cl_I floor1 (const cl_I& x, const cl_I& y);
437
438 // Dividiert zwei Integers x,y und liefert Quotient und Rest
439 // (q,r) := (ceiling x y)
440 // ceiling2(x,y)
441 // > x,y: Integers
442 // < q,r: Quotient q, Rest r
443   extern const cl_I_div_t ceiling2 (const cl_I& x, const cl_I& y);
444   extern const cl_I ceiling1 (const cl_I& x, const cl_I& y);
445
446 // Dividiert zwei Integers x,y und liefert Quotient und Rest
447 // (q,r) := (truncate x y)
448 // truncate2(x,y)
449 // > x,y: Integers
450 // < q,r: Quotient q, Rest r
451   extern const cl_I_div_t truncate2 (const cl_I& x, const cl_I& y);
452   extern const cl_I truncate1 (const cl_I& x, const cl_I& y);
453
454 // Dividiert zwei Integers x,y und liefert Quotient und Rest
455 // (q,r) := (round x y)
456 // round2(x,y)
457 // > x,y: Integers
458 // < q,r: Quotient q, Rest r
459   extern const cl_I_div_t round2 (const cl_I& x, const cl_I& y);
460   extern const cl_I round1 (const cl_I& x, const cl_I& y);
461
462
463 // ggT und kgV von Integers
464
465 // Liefert den ggT zweier Integers.
466 // gcd(a,b)
467 // > a,b: zwei Integers
468 // < ergebnis: (gcd a b), ein Integer >=0
469   extern const cl_I gcd (const cl_I& a, const cl_I& b);
470   extern uintV gcd (uintV a, uintV b);
471
472 // Liefert den ggT zweier Integers samt Beifaktoren.
473 // g = xgcd(a,b,&u,&v)
474 // > a,b: zwei Integers
475 // < u, v, g: Integers mit u*a+v*b = g >= 0
476   extern const cl_I xgcd (const cl_I& a, const cl_I& b, cl_I* u, cl_I* v);
477 // Im Fall A/=0, B/=0 genügt das Ergebnis (g,u,v) den Ungleichungen:
478 //   Falls |A| = |B| : g = |A|, u = (signum A), v = 0.
479 //   Falls |B| | |A|, |B| < |A| : g = |B|, u = 0, v = (signum B).
480 //   Falls |A| | |B|, |A| < |B| : g = |A|, u = (signum A), v = 0.
481 //   Sonst: |u| <= |B| / (2*g), |v| <= |A| / (2*g).
482 //   In jedem Fall |u| <= |B|/g, |v| < |A|/g.
483 // (Beweis: Im Prinzip macht man ja mehrere Euklid-Schritte auf einmal. Im
484 // letzten Fall - oBdA |A| > |B| - braucht man mindestens zwei Euklid-Schritte,
485 // also gilt im Euklid-Tableau
486 //                 i         |A|            |B|         Erg.
487 //                --------------------------------------------
488 //                 0          1              0          |A|
489 //                 1          0              1          |B|
490 //                ...        ...            ...         ...
491 //                n-1  -(-1)^n*x[n-1]  (-1)^n*y[n-1]   z[n-1]
492 //                 n    (-1)^n*x[n]    -(-1)^n*y[n]     z[n]
493 //                n+1  -(-1)^n*x[n+1]  (-1)^n*y[n+1]   z[n+1] = 0
494 //                --------------------------------------------
495 //                       g = z[n], |u|=x[n], |v|=y[n]
496 // n>=2, z[0] > ... > z[n-1] > z[n] = g, g | z[n-1], also z[n-1] >= 2*g.
497 // Da aber mit  (-1)^i*x[i]*|A| - (-1)^i*y[i]*|B| = z[i]  für i=0..n+1
498 // und            x[i]*y[i+1] - x[i+1]*y[i] = (-1)^i  für i=0..n,
499 //                x[i]*z[i+1] - x[i+1]*z[i] = (-1)^i*|B|  für i=0..n,
500 //                y[i]*z[i+1] - y[i+1]*z[i] = -(-1)^i*|A|  für i=0..n
501 // auch |A| = y[i+1]*z[i] + y[i]*z[i+1], |B| = x[i+1]*z[i] + x[i]*z[i+1]
502 // für i=0..n (Cramersche Regel), folgt
503 // |A| = y[n]*z[n-1] + y[n-1]*z[n] >= y[n]*2*g + 0 = |v|*2*g,
504 // |B| = x[n]*z[n-1] + x[n-1]*z[n] >= x[n]*2*g + 0 = |u|*2*g.)
505
506 // Liefert den kgV zweier Integers.
507 // lcm(a,b)
508 // > a,b: zwei Integers
509 // < ergebnis: (lcm a b), ein Integer >=0
510   extern const cl_I lcm (const cl_I& a, const cl_I& b);
511
512
513 // Wurzel aus ganzen Zahlen
514
515 // Zieht die Wurzel (ISQRT x) aus einem Integer.
516 // isqrt(x,&w)
517 // > x: Integer (sollte >=0 sein)
518 // < w: (isqrt x)
519 // < ergebnis: cl_true falls x Quadratzahl, cl_false sonst
520   extern cl_boolean isqrt (const cl_I& x, cl_I* w);
521 // Wenn das boolesche Ergebnis uninteressant ist:
522   inline const cl_I isqrt (const cl_I& x) { cl_I w; isqrt(x,&w); return w; }
523
524 // Stellt fest, ob ein Integer >=0 eine Quadratzahl ist.
525 // sqrtp(x,&w)
526 // > x: ein Integer >=0
527 // < w: Integer (sqrt x) falls x Quadratzahl
528 // < ergebnis: cl_true   ..................., cl_false sonst
529   extern cl_boolean sqrtp (const cl_I& x, cl_I* w);
530
531 // Stellt fest, ob ein Integer >=0 eine n-te Potenz ist.
532 // rootp(x,n,&w)
533 // > x: ein Integer >=0
534 // > n: ein Integer >0
535 // < w: Integer (expt x (/ n)) falls x eine n-te Potenz
536 // < ergebnis: cl_true         ........................, cl_false sonst
537   extern cl_boolean rootp (const cl_I& x, uintL n, cl_I* w);
538   extern cl_boolean rootp (const cl_I& x, const cl_I& n, cl_I* w);
539
540
541 // max(x,y) liefert (max x y), wo x und y ganze Zahlen sind.
542 extern const cl_I max (const cl_I& x, const cl_I& y);
543
544 // min(x,y) liefert (min x y), wo x und y ganze Zahlen sind.
545 extern const cl_I min (const cl_I& x, const cl_I& y);
546
547 // signum(x) liefert (signum x), wo x eine ganze Zahl ist.
548 extern const cl_I signum (const cl_I& x);
549
550
551 // Multipliziert ein Integer mit 10 und addiert eine weitere Ziffer.
552 // mul_10_plus_x(y,x)
553 // > y: Integer Y (>=0)
554 // > x: Ziffernwert X (>=0,<10)
555 // < ergebnis: Integer Y*10+X (>=0)
556 extern const cl_I mul_10_plus_x (const cl_I& y, unsigned char x);
557
558
559 // 2-adische Inverse.
560 // cl_recip2adic(n,x)
561 // > n: >0
562 // > x: Integer, ungerade
563 // < ergebnis: n-Bit-Zahl y == (x mod 2^n)^-1, d.h. y*x == 1 mod 2^n
564 extern const cl_I cl_recip2adic (uintL n, const cl_I& x);
565
566 // 2-adische Division.
567 // cl_div2adic(n,x,y)
568 // > n: >0
569 // > x: Integer
570 // > y: Integer, ungerade
571 // < ergebnis: n-Bit-Zahl z == (x mod 2^n)/(y mod 2^n), d.h. z*y == x mod 2^n
572 extern const cl_I cl_div2adic (uintL n, const cl_I& x, const cl_I& y);
573
574
575 // numerator(r) liefert den Zähler des Integer r.
576 inline const cl_I numerator (const cl_I& r)
577         { return r; }
578 // denominator(r) liefert den Nenner (> 0) des Integer r.
579 inline const cl_I denominator (const cl_I& r)
580         { (void)r; return 1; }
581
582
583 // Konversion zu einem C "float".
584 extern float float_approx (const cl_I& x);
585
586 // Konversion zu einem C "double".
587 extern double double_approx (const cl_I& x);
588
589
590 // random_I(randomstate,n) liefert zu einem Integer n>0 ein zufälliges
591 // Integer x mit 0 <= x < n.
592 // > randomstate: ein Random-State, wird verändert
593 extern const cl_I random_I (random_state& randomstate, const cl_I& n);
594
595 inline const cl_I random_I (const cl_I& n)
596         { return random_I(default_random_state,n); }
597
598 // testrandom_I(randomstate) liefert ein zufälliges Integer zum Testen.
599 // > randomstate: ein Random-State, wird verändert
600 extern const cl_I testrandom_I (random_state& randomstate);
601
602 inline const cl_I testrandom_I ()
603         { return testrandom_I(default_random_state); }
604
605
606 #ifdef WANT_OBFUSCATING_OPERATORS
607 // This could be optimized to use in-place operations.
608 inline cl_I& operator+= (cl_I& x, const cl_I& y) { return x = x + y; }
609 inline cl_I& operator+= (cl_I& x, const int y) { return x = x + y; }
610 inline cl_I& operator+= (cl_I& x, const unsigned int y) { return x = x + y; }
611 inline cl_I& operator+= (cl_I& x, const long y) { return x = x + y; }
612 inline cl_I& operator+= (cl_I& x, const unsigned long y) { return x = x + y; }
613 inline cl_I& operator++ /* prefix */ (cl_I& x) { return x = plus1(x); }
614 inline void operator++ /* postfix */ (cl_I& x, int dummy) { (void)dummy; x = plus1(x); }
615 inline cl_I& operator-= (cl_I& x, const cl_I& y) { return x = x - y; }
616 inline cl_I& operator-= (cl_I& x, const int y) { return x = x - y; }
617 inline cl_I& operator-= (cl_I& x, const unsigned int y) { return x = x - y; }
618 inline cl_I& operator-= (cl_I& x, const long y) { return x = x - y; }
619 inline cl_I& operator-= (cl_I& x, const unsigned long y) { return x = x - y; }
620 inline cl_I& operator-- /* prefix */ (cl_I& x) { return x = minus1(x); }
621 inline void operator-- /* postfix */ (cl_I& x, int dummy) { (void)dummy; x = minus1(x); }
622 inline cl_I& operator*= (cl_I& x, const cl_I& y) { return x = x * y; }
623 inline cl_I& operator<<= (cl_I& x, sintC y) // assume 0 <= y < 2^(intCsize-1)
624         { return x = x << y; }
625 inline cl_I& operator<<= (cl_I& x, const cl_I& y) // assume y >= 0
626         { return x = x << y; }
627 inline cl_I& operator>>= (cl_I& x, sintC y) // assume 0 <= y < 2^(intCsize-1)
628         { return x = x >> y; }
629 inline cl_I& operator>>= (cl_I& x, const cl_I& y) // assume y >= 0
630         { return x = x >> y; }
631 #if 0 // Defining operator/ collides with the operator/ (cl_RA, cl_RA).
632 // operator/ should perform exquo(x,y), but people believe in the C semantics.
633 // And it would be wiser to use floor1 and mod instead of truncate1 and rem,
634 // but again, many C compilers implement / and % like this and people believe
635 // in it.
636 inline const cl_I operator/ (const cl_I& x, const cl_I& y) { return truncate1(x,y); }
637 inline const cl_I operator% (const cl_I& x, const cl_I& y) { return rem(x,y); }
638 inline cl_I& operator/= (cl_I& x, const cl_I& y) { return x = x / y; }
639 inline cl_I& operator%= (cl_I& x, const cl_I& y) { return x = x % y; }
640 #endif
641 #endif
642
643
644 // Runtime typing support.
645 extern cl_class cl_class_fixnum;
646 extern cl_class cl_class_bignum;
647 CL_FORCE_LINK(cl_I_classes_dummy, cl_class_fixnum)
648
649
650 // Debugging support.
651 #ifdef CL_DEBUG
652 extern int cl_I_debug_module;
653 CL_FORCE_LINK(cl_I_debug_dummy, cl_I_debug_module)
654 #endif
655
656 }  // namespace cln
657
658 #endif /* _CL_INTEGER_H */