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.

604 lines
21 KiB

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