You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

602 lines
21 KiB

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