1 // Public integer operations.
6 #include "cln/number.h"
7 #include "cln/integer_class.h"
8 #include "cln/random.h"
12 CL_DEFINE_AS_CONVERSION(cl_I)
15 // Konversion Integer >=0, <2^32 nach uintL.
16 // Wandelt Integer >=0 in Unsigned Longword um.
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);
22 // Konversion Integer >=-2^31, <2^31 nach sintL.
23 // Wandelt Integer in Signed Longword um.
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);
29 // Convert an integer to a C `int' or `unsigned int'.
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); }
35 // Convert an integer to a C `long' or `unsigned long'.
36 #if (long_bitsize==32)
37 inline long cl_I_to_long (const cl_I& x) { return cl_I_to_L(x); }
38 inline unsigned long cl_I_to_ulong (const cl_I& x) { return cl_I_to_UL(x); }
39 #elif (long_bitsize==64)
40 extern uint64 cl_I_to_UQ (const cl_I& obj);
41 extern sint64 cl_I_to_Q (const cl_I& obj);
42 inline long cl_I_to_long (const cl_I& x) { return cl_I_to_Q(x); }
43 inline unsigned long cl_I_to_ulong (const cl_I& x) { return cl_I_to_UQ(x); }
46 #if (intCsize==long_bitsize)
47 inline uintC cl_I_to_UC (const cl_I& x) { return cl_I_to_ulong(x); }
48 inline sintC cl_I_to_C (const cl_I& x) { return cl_I_to_long(x); }
49 #elif (intCsize==int_bitsize)
50 inline uintC cl_I_to_UC (const cl_I& x) { return cl_I_to_uint(x); }
51 inline sintC cl_I_to_C (const cl_I& x) { return cl_I_to_int(x); }
55 // Logische Operationen auf Integers:
57 // (LOGIOR x y), wenn x, y Integers sind.
59 extern const cl_I logior (const cl_I& x, const cl_I& y);
61 // (LOGXOR x y), wenn x, y Integers sind.
63 extern const cl_I logxor (const cl_I& x, const cl_I& y);
65 // (LOGAND x y), wenn x, y Integers sind.
67 extern const cl_I logand (const cl_I& x, const cl_I& y);
69 // (LOGEQV x y), wenn x, y Integers sind.
71 extern const cl_I logeqv (const cl_I& x, const cl_I& y);
73 // (LOGNAND x y), wenn x, y Integers sind.
75 extern const cl_I lognand (const cl_I& x, const cl_I& y);
77 // (LOGNOR x y), wenn x, y Integers sind.
79 extern const cl_I lognor (const cl_I& x, const cl_I& y);
81 // (LOGANDC2 x y), wenn x, y Integers sind.
83 extern const cl_I logandc2 (const cl_I& x, const cl_I& y);
85 // (LOGANDC1 x y), wenn x, y Integers sind.
87 inline const cl_I logandc1 (const cl_I& x, const cl_I& y)
92 // (LOGORC2 x y), wenn x, y Integers sind.
94 extern const cl_I logorc2 (const cl_I& x, const cl_I& y);
96 // (LOGORC1 x y), wenn x, y Integers sind.
98 inline const cl_I logorc1 (const cl_I& x, const cl_I& y)
103 // (LOGNOT x), wenn x ein Integer sind.
105 extern const cl_I lognot (const cl_I& x);
107 // Konstanten für BOOLE:
127 // (BOOLE op x y), wenn x und y Integers und op ein Objekt sind.
129 extern const cl_I boole (cl_boole op, const cl_I& x, const cl_I& y);
131 // Prüft, ob (LOGTEST x y), wo x und y Integers sind.
132 // (LOGTEST x y) = (NOT (ZEROP (LOGAND x y))).
133 // < ergebnis: /=0, falls ja; =0, falls nein.
134 extern cl_boolean logtest (const cl_I& x, const cl_I& y);
136 // Prüft, ob (LOGBITP x y), wo x und y Integers sind.
137 // Ergebnis: /=0, wenn ja; =0, wenn nein.
138 extern cl_boolean logbitp (uintC x, const cl_I& y);
139 extern cl_boolean logbitp (const cl_I& x, const cl_I& y);
141 // Prüft, ob (ODDP x), wo x ein Integer ist.
142 // Ergebnis: /=0, falls ja; =0, falls nein.
143 extern cl_boolean oddp (const cl_I& x);
145 // Prüft, ob (EVENP x), wo x ein Integer ist.
146 // Ergebnis: /=0, falls ja; =0, falls nein.
147 inline cl_boolean evenp (const cl_I& x)
148 { return (cl_boolean) (!oddp(x)); }
150 // (ASH x y), wo x und y Integers sind. Ergebnis Integer.
151 extern const cl_I ash (const cl_I& x, sintC y);
152 extern const cl_I ash (const cl_I& x, const cl_I& y);
154 // (LOGCOUNT x), wo x ein Integer ist. Ergebnis uintL.
155 extern uintC logcount (const cl_I& x);
157 // (INTEGER-LENGTH x), wo x ein Integer ist. Ergebnis uintL.
158 extern uintC integer_length (const cl_I& x);
160 // (ORD2 x) = max{n>=0: 2^n | x }, wo x ein Integer /=0 ist. Ergebnis uintL.
161 extern uintC ord2 (const cl_I& x);
163 // power2p(x) stellt fest, ob ein Integer x>0 eine Zweierpotenz ist.
164 // Ergebnis: n>0, wenn x=2^(n-1), 0 sonst.
165 extern uintC power2p (const cl_I& x);
167 inline const cl_I operator| (const cl_I& x, const cl_I& y)
168 { return logior(x,y); }
169 inline const cl_I operator^ (const cl_I& x, const cl_I& y)
170 { return logxor(x,y); }
171 inline const cl_I operator& (const cl_I& x, const cl_I& y)
172 { return logand(x,y); }
173 inline const cl_I operator~ (const cl_I& x)
174 { return lognot(x); }
175 #ifdef WANT_OBFUSCATING_OPERATORS
176 // This could be optimized to use in-place operations.
177 inline cl_I& operator|= (cl_I& x, const cl_I& y) { return x = x | y; }
178 inline cl_I& operator^= (cl_I& x, const cl_I& y) { return x = x ^ y; }
179 inline cl_I& operator&= (cl_I& x, const cl_I& y) { return x = x & y; }
183 // Addition/Subtraktion von Integers
185 // (1+ x), wo x ein Integer ist. Ergebnis Integer.
186 extern const cl_I plus1 (const cl_I& x);
188 // (1- x), wo x ein Integer ist. Ergebnis Integer.
189 extern const cl_I minus1 (const cl_I& x);
191 // (+ x y), wo x und y Integers sind. Ergebnis Integer.
192 extern const cl_I operator+ (const cl_I& x, const cl_I& y);
193 // Dem C++-Compiler muß man auch das Folgende sagen:
194 inline const cl_I operator+ (const int x, const cl_I& y)
195 { return cl_I(x) + y; }
196 inline const cl_I operator+ (const unsigned int x, const cl_I& y)
197 { return cl_I(x) + y; }
198 inline const cl_I operator+ (const long x, const cl_I& y)
199 { return cl_I(x) + y; }
200 inline const cl_I operator+ (const unsigned long x, const cl_I& y)
201 { return cl_I(x) + y; }
203 inline const cl_I operator+ (const long long x, const cl_I& y)
204 { return cl_I(x) + y; }
205 inline const cl_I operator+ (const unsigned long long x, const cl_I& y)
206 { return cl_I(x) + y; }
208 inline const cl_I operator+ (const cl_I& x, const int y)
209 { return x + cl_I(y); }
210 inline const cl_I operator+ (const cl_I& x, const unsigned int y)
211 { return x + cl_I(y); }
212 inline const cl_I operator+ (const cl_I& x, const long y)
213 { return x + cl_I(y); }
214 inline const cl_I operator+ (const cl_I& x, const unsigned long y)
215 { return x + cl_I(y); }
217 inline const cl_I operator+ (const cl_I& x, const long long y)
218 { return x + cl_I(y); }
219 inline const cl_I operator+ (const cl_I& x, const unsigned long long y)
220 { return x + cl_I(y); }
223 // (- x), wenn x ein Integer ist. Ergebnis Integer.
224 extern const cl_I operator- (const cl_I& x);
226 // (- x y), wo x und y Integers sind. Ergebnis Integer.
227 extern const cl_I operator- (const cl_I& x, const cl_I& y);
228 // Dem C++-Compiler muß man auch das Folgende sagen:
229 inline const cl_I operator- (const int x, const cl_I& y)
230 { return cl_I(x) - y; }
231 inline const cl_I operator- (const unsigned int x, const cl_I& y)
232 { return cl_I(x) - y; }
233 inline const cl_I operator- (const long x, const cl_I& y)
234 { return cl_I(x) - y; }
235 inline const cl_I operator- (const unsigned long x, const cl_I& y)
236 { return cl_I(x) - y; }
238 inline const cl_I operator- (const long long x, const cl_I& y)
239 { return cl_I(x) - y; }
240 inline const cl_I operator- (const unsigned long long x, const cl_I& y)
241 { return cl_I(x) - y; }
243 inline const cl_I operator- (const cl_I& x, const int y)
244 { return x - cl_I(y); }
245 inline const cl_I operator- (const cl_I& x, const unsigned int y)
246 { return x - cl_I(y); }
247 inline const cl_I operator- (const cl_I& x, const long y)
248 { return x - cl_I(y); }
249 inline const cl_I operator- (const cl_I& x, const unsigned long y)
250 { return x - cl_I(y); }
252 inline const cl_I operator- (const cl_I& x, const long long y)
253 { return x - cl_I(y); }
254 inline const cl_I operator- (const cl_I& x, const unsigned long long y)
255 { return x - cl_I(y); }
258 // (abs x), wenn x ein Integer ist. Ergebnis Integer.
259 extern const cl_I abs (const cl_I& x);
262 inline const cl_I operator<< (const cl_I& x, sintC y) // assume 0 <= y < 2^(intCsize-1)
264 inline const cl_I operator<< (const cl_I& x, const cl_I& y) // assume y >= 0
266 inline const cl_I operator>> (const cl_I& x, sintC y) // assume 0 <= y < 2^(intCsize-1)
267 { return ash(x,-y); }
268 inline const cl_I operator>> (const cl_I& x, const cl_I& y) // assume y >= 0
269 { return ash(x,-y); }
272 // Vergleich von Integers
274 // equal(x,y) vergleicht zwei Integers x und y auf Gleichheit.
275 extern cl_boolean equal (const cl_I& x, const cl_I& y);
276 // equal_hashcode(x) liefert einen equal-invarianten Hashcode für x.
277 extern uint32 equal_hashcode (const cl_I& x);
279 // compare(x,y) vergleicht zwei Integers x und y.
280 // Ergebnis: 0 falls x=y, +1 falls x>y, -1 falls x<y.
281 extern cl_signean compare (const cl_I& x, const cl_I& y);
283 inline bool operator== (const cl_I& x, const cl_I& y)
284 { return equal(x,y); }
285 inline bool operator!= (const cl_I& x, const cl_I& y)
286 { return !equal(x,y); }
287 inline bool operator<= (const cl_I& x, const cl_I& y)
288 { return compare(x,y)<=0; }
289 inline bool operator< (const cl_I& x, const cl_I& y)
290 { return compare(x,y)<0; }
291 inline bool operator>= (const cl_I& x, const cl_I& y)
292 { return compare(x,y)>=0; }
293 inline bool operator> (const cl_I& x, const cl_I& y)
294 { return compare(x,y)>0; }
296 // minusp(x) == (< x 0)
297 extern cl_boolean minusp (const cl_I& x);
299 // plusp(x) == (> x 0)
300 extern cl_boolean plusp (const cl_I& x);
302 // zerop(x) stellt fest, ob ein Integer = 0 ist.
303 extern cl_boolean zerop (const cl_I& x);
306 // BYTE-Operationen auf Integers
312 cl_byte (uintC s, uintC p) : size (s), position (p) {}
315 // (LDB byte n), wo n ein Integer ist.
316 extern const cl_I ldb (const cl_I& n, const cl_byte& b);
318 // ldb_test(n,byte) führt (LDB-TEST byte n) aus, wobei n ein Integer ist.
319 // Ergebnis: cl_false wenn nein (also alle fraglichen Bits =0), cl_true wenn ja.
320 extern cl_boolean ldb_test (const cl_I& n, const cl_byte& b);
322 // (MASK-FIELD byte n), wo n ein Integer ist.
323 extern const cl_I mask_field (const cl_I& n, const cl_byte& b);
325 // (DEPOSIT-FIELD newbyte byte n), wo n und newbyte Integers sind.
326 extern const cl_I deposit_field (const cl_I& newbyte, const cl_I& n, const cl_byte& b);
328 // (DPB newbyte byte n), wo n und newbyte Integers sind.
329 extern const cl_I dpb (const cl_I& newbyte, const cl_I& n, const cl_byte& b);
332 // Multiplikation ganzer Zahlen
334 // (* x y), wo x und y Integers sind. Ergebnis Integer.
335 extern const cl_I operator* (const cl_I& x, const cl_I& y);
336 // Dem C++-Compiler muß man auch das Folgende sagen:
337 inline const cl_I operator* (const int x, const cl_I& y)
338 { return cl_I(x) * y; }
339 inline const cl_I operator* (const unsigned int x, const cl_I& y)
340 { return cl_I(x) * y; }
341 inline const cl_I operator* (const long x, const cl_I& y)
342 { return cl_I(x) * y; }
343 inline const cl_I operator* (const unsigned long x, const cl_I& y)
344 { return cl_I(x) * y; }
346 inline const cl_I operator* (const long long x, const cl_I& y)
347 { return cl_I(x) * y; }
348 inline const cl_I operator* (const unsigned long long x, const cl_I& y)
349 { return cl_I(x) * y; }
351 inline const cl_I operator* (const cl_I& x, const int y)
352 { return x * cl_I(y); }
353 inline const cl_I operator* (const cl_I& x, const unsigned int y)
354 { return x * cl_I(y); }
355 inline const cl_I operator* (const cl_I& x, const long y)
356 { return x * cl_I(y); }
357 inline const cl_I operator* (const cl_I& x, const unsigned long y)
358 { return x * cl_I(y); }
360 inline const cl_I operator* (const cl_I& x, const long long y)
361 { return x * cl_I(y); }
362 inline const cl_I operator* (const cl_I& x, const unsigned long long y)
363 { return x * cl_I(y); }
366 // (EXPT x 2), wo x Integer ist.
367 extern const cl_I square (const cl_I& x);
369 // (EXPT x y), wo x Integer, y Integer >0 ist.
370 extern const cl_I expt_pos (const cl_I& x, uintL y);
371 extern const cl_I expt_pos (const cl_I& x, const cl_I& y);
373 // Fakultät (! n), wo n Fixnum >=0 ist. Ergebnis Integer.
374 extern const cl_I factorial (uintL n);
375 //CL_REQUIRE(cl_I_factorial)
377 // Double factorial (!! n), with n Fixnum >=0. Returns integer.
378 extern const cl_I doublefactorial (uintL n);
380 // Binomialkoeffizient (n \choose k) = n! / k! (n-k)!, wo n,k >= 0 sind.
381 extern const cl_I binomial (uintL n, uintL k);
384 // Division ganzer Zahlen
386 // Return type for division operators.
387 // x / y --> (q,r) with x = y*q+r.
393 cl_I_div_t (const cl_I& q, const cl_I& r) : quotient(q), remainder(r) {}
396 // Dividiert zwei Integers x,y >=0 und liefert den Quotienten x/y >=0.
397 // Bei y=0 Error. Die Division muß aufgehen, sonst Error.
399 // > x,y: Integers >=0
400 // < ergebnis: Quotient x/y, ein Integer >=0
401 extern const cl_I exquopos (const cl_I& x, const cl_I& y);
403 // Dividiert zwei Integers x,y und liefert den Quotienten x/y.
404 // Bei y=0 Error. Die Division muß aufgehen, sonst Error.
407 // < ergebnis: Quotient x/y, ein Integer
408 extern const cl_I exquo (const cl_I& x, const cl_I& y);
410 // mod(x,y) = (mod x y), wo x,y Integers sind.
411 extern const cl_I mod (const cl_I& x, const cl_I& y);
413 // rem(x,y) = (rem x y), wo x,y Integers sind.
414 extern const cl_I rem (const cl_I& x, const cl_I& y);
416 // Dividiert zwei Integers x,y und liefert Quotient und Rest
417 // (q,r) := (floor x y)
420 // < q,r: Quotient q, Rest r
421 extern const cl_I_div_t floor2 (const cl_I& x, const cl_I& y);
422 extern const cl_I floor1 (const cl_I& x, const cl_I& y);
424 // Dividiert zwei Integers x,y und liefert Quotient und Rest
425 // (q,r) := (ceiling x y)
428 // < q,r: Quotient q, Rest r
429 extern const cl_I_div_t ceiling2 (const cl_I& x, const cl_I& y);
430 extern const cl_I ceiling1 (const cl_I& x, const cl_I& y);
432 // Dividiert zwei Integers x,y und liefert Quotient und Rest
433 // (q,r) := (truncate x y)
436 // < q,r: Quotient q, Rest r
437 extern const cl_I_div_t truncate2 (const cl_I& x, const cl_I& y);
438 extern const cl_I truncate1 (const cl_I& x, const cl_I& y);
440 // Dividiert zwei Integers x,y und liefert Quotient und Rest
441 // (q,r) := (round x y)
444 // < q,r: Quotient q, Rest r
445 extern const cl_I_div_t round2 (const cl_I& x, const cl_I& y);
446 extern const cl_I round1 (const cl_I& x, const cl_I& y);
449 // ggT und kgV von Integers
451 // Liefert den ggT zweier Integers.
453 // > a,b: zwei Integers
454 // < ergebnis: (gcd a b), ein Integer >=0
455 extern const cl_I gcd (const cl_I& a, const cl_I& b);
456 extern uintV gcd (uintV a, uintV b);
458 // Liefert den ggT zweier Integers samt Beifaktoren.
459 // g = xgcd(a,b,&u,&v)
460 // > a,b: zwei Integers
461 // < u, v, g: Integers mit u*a+v*b = g >= 0
462 extern const cl_I xgcd (const cl_I& a, const cl_I& b, cl_I* u, cl_I* v);
463 // Im Fall A/=0, B/=0 genügt das Ergebnis (g,u,v) den Ungleichungen:
464 // Falls |A| = |B| : g = |A|, u = (signum A), v = 0.
465 // Falls |B| | |A|, |B| < |A| : g = |B|, u = 0, v = (signum B).
466 // Falls |A| | |B|, |A| < |B| : g = |A|, u = (signum A), v = 0.
467 // Sonst: |u| <= |B| / (2*g), |v| <= |A| / (2*g).
468 // In jedem Fall |u| <= |B|/g, |v| < |A|/g.
469 // (Beweis: Im Prinzip macht man ja mehrere Euklid-Schritte auf einmal. Im
470 // letzten Fall - oBdA |A| > |B| - braucht man mindestens zwei Euklid-Schritte,
471 // also gilt im Euklid-Tableau
473 // --------------------------------------------
477 // n-1 -(-1)^n*x[n-1] (-1)^n*y[n-1] z[n-1]
478 // n (-1)^n*x[n] -(-1)^n*y[n] z[n]
479 // n+1 -(-1)^n*x[n+1] (-1)^n*y[n+1] z[n+1] = 0
480 // --------------------------------------------
481 // g = z[n], |u|=x[n], |v|=y[n]
482 // n>=2, z[0] > ... > z[n-1] > z[n] = g, g | z[n-1], also z[n-1] >= 2*g.
483 // Da aber mit (-1)^i*x[i]*|A| - (-1)^i*y[i]*|B| = z[i] für i=0..n+1
484 // und x[i]*y[i+1] - x[i+1]*y[i] = (-1)^i für i=0..n,
485 // x[i]*z[i+1] - x[i+1]*z[i] = (-1)^i*|B| für i=0..n,
486 // y[i]*z[i+1] - y[i+1]*z[i] = -(-1)^i*|A| für i=0..n
487 // auch |A| = y[i+1]*z[i] + y[i]*z[i+1], |B| = x[i+1]*z[i] + x[i]*z[i+1]
488 // für i=0..n (Cramersche Regel), folgt
489 // |A| = y[n]*z[n-1] + y[n-1]*z[n] >= y[n]*2*g + 0 = |v|*2*g,
490 // |B| = x[n]*z[n-1] + x[n-1]*z[n] >= x[n]*2*g + 0 = |u|*2*g.)
492 // Liefert den kgV zweier Integers.
494 // > a,b: zwei Integers
495 // < ergebnis: (lcm a b), ein Integer >=0
496 extern const cl_I lcm (const cl_I& a, const cl_I& b);
499 // Wurzel aus ganzen Zahlen
501 // Zieht die Wurzel (ISQRT x) aus einem Integer.
503 // > x: Integer (sollte >=0 sein)
505 // < ergebnis: cl_true falls x Quadratzahl, cl_false sonst
506 extern cl_boolean isqrt (const cl_I& x, cl_I* w);
507 // Wenn das boolesche Ergebnis uninteressant ist:
508 inline const cl_I isqrt (const cl_I& x) { cl_I w; isqrt(x,&w); return w; }
510 // Stellt fest, ob ein Integer >=0 eine Quadratzahl ist.
512 // > x: ein Integer >=0
513 // < w: Integer (sqrt x) falls x Quadratzahl
514 // < ergebnis: cl_true ..................., cl_false sonst
515 extern cl_boolean sqrtp (const cl_I& x, cl_I* w);
517 // Stellt fest, ob ein Integer >=0 eine n-te Potenz ist.
519 // > x: ein Integer >=0
520 // > n: ein Integer >0
521 // < w: Integer (expt x (/ n)) falls x eine n-te Potenz
522 // < ergebnis: cl_true ........................, cl_false sonst
523 extern cl_boolean rootp (const cl_I& x, uintL n, cl_I* w);
524 extern cl_boolean rootp (const cl_I& x, const cl_I& n, cl_I* w);
527 // max(x,y) liefert (max x y), wo x und y ganze Zahlen sind.
528 extern const cl_I max (const cl_I& x, const cl_I& y);
530 // min(x,y) liefert (min x y), wo x und y ganze Zahlen sind.
531 extern const cl_I min (const cl_I& x, const cl_I& y);
533 // signum(x) liefert (signum x), wo x eine ganze Zahl ist.
534 extern const cl_I signum (const cl_I& x);
537 // Multipliziert ein Integer mit 10 und addiert eine weitere Ziffer.
538 // mul_10_plus_x(y,x)
539 // > y: Integer Y (>=0)
540 // > x: Ziffernwert X (>=0,<10)
541 // < ergebnis: Integer Y*10+X (>=0)
542 extern const cl_I mul_10_plus_x (const cl_I& y, unsigned char x);
545 // 2-adische Inverse.
546 // cl_recip2adic(n,x)
548 // > x: Integer, ungerade
549 // < ergebnis: n-Bit-Zahl y == (x mod 2^n)^-1, d.h. y*x == 1 mod 2^n
550 extern const cl_I cl_recip2adic (uintL n, const cl_I& x);
552 // 2-adische Division.
553 // cl_div2adic(n,x,y)
556 // > y: Integer, ungerade
557 // < ergebnis: n-Bit-Zahl z == (x mod 2^n)/(y mod 2^n), d.h. z*y == x mod 2^n
558 extern const cl_I cl_div2adic (uintL n, const cl_I& x, const cl_I& y);
561 // numerator(r) liefert den Zähler des Integer r.
562 inline const cl_I numerator (const cl_I& r)
564 // denominator(r) liefert den Nenner (> 0) des Integer r.
565 inline const cl_I denominator (const cl_I& r)
566 { (void)r; return 1; }
569 // Konversion zu einem C "float".
570 extern float float_approx (const cl_I& x);
572 // Konversion zu einem C "double".
573 extern double double_approx (const cl_I& x);
576 // random_I(randomstate,n) liefert zu einem Integer n>0 ein zufälliges
577 // Integer x mit 0 <= x < n.
578 // > randomstate: ein Random-State, wird verändert
579 extern const cl_I random_I (random_state& randomstate, const cl_I& n);
581 inline const cl_I random_I (const cl_I& n)
582 { return random_I(default_random_state,n); }
584 // testrandom_I(randomstate) liefert ein zufälliges Integer zum Testen.
585 // > randomstate: ein Random-State, wird verändert
586 extern const cl_I testrandom_I (random_state& randomstate);
588 inline const cl_I testrandom_I ()
589 { return testrandom_I(default_random_state); }
592 #ifdef WANT_OBFUSCATING_OPERATORS
593 // This could be optimized to use in-place operations.
594 inline cl_I& operator+= (cl_I& x, const cl_I& y) { return x = x + y; }
595 inline cl_I& operator+= (cl_I& x, const int y) { return x = x + y; }
596 inline cl_I& operator+= (cl_I& x, const unsigned int y) { return x = x + y; }
597 inline cl_I& operator+= (cl_I& x, const long y) { return x = x + y; }
598 inline cl_I& operator+= (cl_I& x, const unsigned long y) { return x = x + y; }
599 inline cl_I& operator++ /* prefix */ (cl_I& x) { return x = plus1(x); }
600 inline void operator++ /* postfix */ (cl_I& x, int dummy) { (void)dummy; x = plus1(x); }
601 inline cl_I& operator-= (cl_I& x, const cl_I& y) { return x = x - y; }
602 inline cl_I& operator-= (cl_I& x, const int y) { return x = x - y; }
603 inline cl_I& operator-= (cl_I& x, const unsigned int y) { return x = x - y; }
604 inline cl_I& operator-= (cl_I& x, const long y) { return x = x - y; }
605 inline cl_I& operator-= (cl_I& x, const unsigned long y) { return x = x - y; }
606 inline cl_I& operator-- /* prefix */ (cl_I& x) { return x = minus1(x); }
607 inline void operator-- /* postfix */ (cl_I& x, int dummy) { (void)dummy; x = minus1(x); }
608 inline cl_I& operator*= (cl_I& x, const cl_I& y) { return x = x * y; }
609 inline cl_I& operator<<= (cl_I& x, sintC y) // assume 0 <= y < 2^(intCsize-1)
610 { return x = x << y; }
611 inline cl_I& operator<<= (cl_I& x, const cl_I& y) // assume y >= 0
612 { return x = x << y; }
613 inline cl_I& operator>>= (cl_I& x, sintC y) // assume 0 <= y < 2^(intCsize-1)
614 { return x = x >> y; }
615 inline cl_I& operator>>= (cl_I& x, const cl_I& y) // assume y >= 0
616 { return x = x >> y; }
617 #if 0 // Defining operator/ collides with the operator/ (cl_RA, cl_RA).
618 // operator/ should perform exquo(x,y), but people believe in the C semantics.
619 // And it would be wiser to use floor1 and mod instead of truncate1 and rem,
620 // but again, many C compilers implement / and % like this and people believe
622 inline const cl_I operator/ (const cl_I& x, const cl_I& y) { return truncate1(x,y); }
623 inline const cl_I operator% (const cl_I& x, const cl_I& y) { return rem(x,y); }
624 inline cl_I& operator/= (cl_I& x, const cl_I& y) { return x = x / y; }
625 inline cl_I& operator%= (cl_I& x, const cl_I& y) { return x = x % y; }
630 // Runtime typing support.
631 extern cl_class cl_class_fixnum;
632 extern cl_class cl_class_bignum;
633 CL_FORCE_LINK(cl_I_classes_dummy, cl_class_fixnum)
636 // Debugging support.
638 extern int cl_I_debug_module;
639 CL_FORCE_LINK(cl_I_debug_dummy, cl_I_debug_module)
644 #endif /* _CL_INTEGER_H */