blob: 0cdc84d4c1e4d2fe3772606ebea690eec3fae0b6 [file] [log] [blame]
Guido van Rossumb6775db1994-08-01 11:34:53 +00001
Guido van Rossum5f59d601992-12-14 16:59:51 +00002/* MPZ module */
3
4/* This module provides an interface to an alternate Multi-Precision
5 library, GNU MP in this case */
6
7/* XXX note: everywhere where mpz_size is called,
8 sizeof (limb) == sizeof (long) has been assumed. */
9
10
11/* MPZ objects */
12
Barry Warsaw3bdf7461996-12-09 23:16:31 +000013#include "Python.h"
Guido van Rossuma597dde1995-01-10 20:56:29 +000014
Guido van Rossumb6775db1994-08-01 11:34:53 +000015#include <sys/types.h> /* For size_t */
Guido van Rossum5f59d601992-12-14 16:59:51 +000016
17/*
18** These are the cpp-flags used in this file...
19**
20**
21** MPZ_MDIV_BUG works around the mpz_m{div,mod,...} routines.
22** This bug has been fixed in a later release of
23** GMP.
24**
25** MPZ_GET_STR_BUG mpz_get_str corrupts memory, seems to be fixed
26** in a later release
27**
28** MPZ_DEBUG generates a bunch of diagnostic messages
29**
30** MPZ_SPARE_MALLOC if set, results in extra code that tries to
31** minimize the creation of extra objects.
32**
33** MPZ_TEST_DIV extra diagnostic output on stderr, when division
34** routines are involved
35**
36** MPZ_LIB_DOES_CHECKING if set, assumes that mpz library doesn't call
37** alloca with arg < 0 (when casted to a signed
38** integral type).
39**
40** MPZ_CONVERSIONS_AS_METHODS if set, presents the conversions as
41** methods. e.g., `mpz(5).long() == 5L'
42** Later, Guido provided an interface to the
43** standard functions. So this flag has no been
44** cleared, and `long(mpz(5)) == 5L'
45**
46** MP_TEST_ALLOC If set, you would discover why MPZ_GET_STR_BUG
47** is needed
48**
49** MAKEDUMMYINT Must be set if dynamic linking will be used
50*/
51
52
53/*
54** IMHO, mpz_m{div,mod,divmod}() do the wrong things when the denominator < 0
Guido van Rossum272841c1996-08-19 23:06:45 +000055** This has been fixed with gmp release 2.0
Guido van Rossum5f59d601992-12-14 16:59:51 +000056*/
57/*#define MPZ_MDIV_BUG fixed the (for me) nexessary parts in libgmp.a */
58/*
59** IMO, mpz_get_str() assumes a bit too large target space, if he doesn't
60** allocate it himself
61*/
Guido van Rossum5f59d601992-12-14 16:59:51 +000062
63#include "gmp.h"
Guido van Rossume7ef74d2000-02-24 15:26:30 +000064
Guido van Rossum6f332502002-03-01 21:31:27 +000065#if __GNU_MP__ + 0 >= 2
Guido van Rossum272841c1996-08-19 23:06:45 +000066#define GMP2
Andrew M. Kuchlingb6f6e952000-02-25 22:23:31 +000067#define BITS_PER_MP_LIMB mp_bits_per_limb
Guido van Rossum272841c1996-08-19 23:06:45 +000068#else
69#define MPZ_GET_STR_BUG
Andrew M. Kuchlingb6f6e952000-02-25 22:23:31 +000070#include "gmp-mparam.h"
Guido van Rossum272841c1996-08-19 23:06:45 +000071#endif
72
Guido van Rossum5f59d601992-12-14 16:59:51 +000073typedef struct {
Barry Warsaw3bdf7461996-12-09 23:16:31 +000074 PyObject_HEAD
Guido van Rossum5f59d601992-12-14 16:59:51 +000075 MP_INT mpz; /* the actual number */
76} mpzobject;
77
Barry Warsaw3bdf7461996-12-09 23:16:31 +000078staticforward PyTypeObject MPZtype;
Guido van Rossum5f59d601992-12-14 16:59:51 +000079
80#define is_mpzobject(v) ((v)->ob_type == &MPZtype)
81
82static const char initialiser_name[] = "mpz";
83
84/* #define MPZ_DEBUG */
85
86static mpzobject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000087newmpzobject(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +000088{
89 mpzobject *mpzp;
90
91
92#ifdef MPZ_DEBUG
93 fputs( "mpz_object() called...\n", stderr );
94#endif /* def MPZ_DEBUG */
Guido van Rossumb18618d2000-05-03 23:44:39 +000095 mpzp = PyObject_New(mpzobject, &MPZtype);
Guido van Rossum5f59d601992-12-14 16:59:51 +000096 if (mpzp == NULL)
97 return NULL;
98
99 mpz_init(&mpzp->mpz); /* actual initialisation */
100 return mpzp;
101} /* newmpzobject() */
102
103#ifdef MPZ_GET_STR_BUG
Guido van Rossum5f59d601992-12-14 16:59:51 +0000104#include "longlong.h"
105#endif /* def MPZ_GET_STR_BUG */
106
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000107static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000108mpz_format(PyObject *objp, int base, unsigned char withname)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000109{
110 mpzobject *mpzp = (mpzobject *)objp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000111 PyStringObject *strobjp;
Guido van Rossum2650a422000-06-28 21:29:47 +0000112 size_t i;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000113 int cmpres;
114 int taglong;
115 char *cp;
116 char prefix[5], *tcp;
117
118
119 tcp = &prefix[0];
120
121 if (mpzp == NULL || !is_mpzobject(mpzp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000122 PyErr_BadInternalCall();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000123 return NULL;
124 }
125
126 assert(base >= 2 && base <= 36);
127
128 if (withname)
129 i = strlen(initialiser_name) + 2; /* e.g. 'mpz(' + ')' */
130 else
131 i = 0;
132
133 if ((cmpres = mpz_cmp_si(&mpzp->mpz, 0L)) == 0)
134 base = 10; /* '0' in every base, right */
135 else if (cmpres < 0) {
136 *tcp++ = '-';
137 i += 1; /* space to hold '-' */
138 }
139
140#ifdef MPZ_DEBUG
141 fprintf(stderr, "mpz_format: mpz_sizeinbase %d\n",
142 (int)mpz_sizeinbase(&mpzp->mpz, base));
143#endif /* def MPZ_DEBUG */
144#ifdef MPZ_GET_STR_BUG
Guido van Rossum272841c1996-08-19 23:06:45 +0000145#ifdef GMP2
146 i += ((size_t) abs(mpzp->mpz._mp_size) * BITS_PER_MP_LIMB
147 * __mp_bases[base].chars_per_bit_exactly) + 1;
148#else
Guido van Rossum5f59d601992-12-14 16:59:51 +0000149 i += ((size_t) abs(mpzp->mpz.size) * BITS_PER_MP_LIMB
150 * __mp_bases[base].chars_per_bit_exactly) + 1;
Guido van Rossum272841c1996-08-19 23:06:45 +0000151#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +0000152#else /* def MPZ_GET_STR_BUG */
153 i += (int)mpz_sizeinbase(&mpzp->mpz, base);
154#endif /* def MPZ_GET_STR_BUG else */
155
156 if (base == 16) {
157 *tcp++ = '0';
158 *tcp++ = 'x';
159 i += 2; /* space to hold '0x' */
160 }
161 else if (base == 8) {
162 *tcp++ = '0';
163 i += 1; /* space to hold the extra '0' */
164 }
165 else if (base > 10) {
166 *tcp++ = '0' + base / 10;
167 *tcp++ = '0' + base % 10;
168 *tcp++ = '#';
169 i += 3; /* space to hold e.g. '12#' */
170 }
171 else if (base < 10) {
172 *tcp++ = '0' + base;
173 *tcp++ = '#';
174 i += 2; /* space to hold e.g. '6#' */
175 }
176
177 /*
178 ** the following code looks if we need a 'L' attached to the number
179 ** it will also attach an 'L' to the value -0x80000000
180 */
181 taglong = 0;
182 if (mpz_size(&mpzp->mpz) > 1
183 || (long)mpz_get_ui(&mpzp->mpz) < 0L) {
184 taglong = 1;
185 i += 1; /* space to hold 'L' */
186 }
187
188#ifdef MPZ_DEBUG
189 fprintf(stderr, "mpz_format: requesting string size %d\n", i);
190#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000191 if ((strobjp =
192 (PyStringObject *)PyString_FromStringAndSize((char *)0, i))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000193 == NULL)
194 return NULL;
195
196 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000197 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000198 if (withname) {
199 strcpy(cp, initialiser_name);
200 cp += strlen(initialiser_name);
201 *cp++ = '('; /*')'*/
202 }
203
204 /* copy the already prepared prefix; e.g. sign and base indicator */
205 *tcp = '\0';
206 strcpy(cp, prefix);
207 cp += tcp - prefix;
208
209 /* since' we have the sign already, let the lib think it's a positive
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000210 number */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000211 if (cmpres < 0)
212 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
213 (void)mpz_get_str(cp, base, &mpzp->mpz);
214 if (cmpres < 0)
215 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
216#ifdef MPZ_DEBUG
217 fprintf(stderr, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
218 base, cp);
219#endif /* def MPZ_DEBUG */
220 cp += strlen(cp);
221
222 if (taglong)
223 *cp++ = 'L';
224 if (withname)
225 *cp++ = /*'('*/ ')';
226
227 *cp = '\0';
228
229#ifdef MPZ_DEBUG
230 fprintf(stderr,
Fred Drakea44d3532000-06-30 15:01:00 +0000231 "mpz_format: cp (str end) %p, begin %p, diff %d, i %d\n",
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000232 cp, PyString_AS_STRING(strobjp),
233 cp - PyString_AS_STRING(strobjp), i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000234#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000235 assert(cp - PyString_AS_STRING(strobjp) <= i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000236
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000237 if (cp - PyString_AS_STRING(strobjp) != i) {
238 strobjp->ob_size -= i - (cp - PyString_AS_STRING(strobjp));
Guido van Rossum5f59d601992-12-14 16:59:51 +0000239 }
240
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000241 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000242} /* mpz_format() */
243
244/* MPZ methods */
245
246static void
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000247mpz_dealloc(mpzobject *mpzp)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000248{
249#ifdef MPZ_DEBUG
250 fputs( "mpz_dealloc() called...\n", stderr );
251#endif /* def MPZ_DEBUG */
252 mpz_clear(&mpzp->mpz);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000253 PyObject_Del(mpzp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000254} /* mpz_dealloc() */
255
Guido van Rossum5f59d601992-12-14 16:59:51 +0000256
257/* pointers to frequently used values 0, 1 and -1 */
258static mpzobject *mpz_value_zero, *mpz_value_one, *mpz_value_mone;
259
260static int
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000261mpz_compare(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000262{
263 int cmpres;
264
265
266 /* guido sez it's better to return -1, 0 or 1 */
267 return (cmpres = mpz_cmp( &a->mpz, &b->mpz )) == 0 ? 0
268 : cmpres > 0 ? 1 : -1;
269} /* mpz_compare() */
270
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000271static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000272mpz_addition(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000273{
274 mpzobject *z;
275
276
277#ifdef MPZ_SPARE_MALLOC
278 if (mpz_cmp_ui(&a->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000279 Py_INCREF(b);
280 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000281 }
282
283 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000284 Py_INCREF(a);
285 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000286 }
287#endif /* def MPZ_SPARE_MALLOC */
288
289 if ((z = newmpzobject()) == NULL)
290 return NULL;
291
292 mpz_add(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000293 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000294} /* mpz_addition() */
295
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000296static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000297mpz_substract(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000298{
299 mpzobject *z;
300
301
302#ifdef MPZ_SPARE_MALLOC
303 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000304 Py_INCREF(a);
305 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000306 }
307#endif /* MPZ_SPARE_MALLOC */
308
309 if ((z = newmpzobject()) == NULL)
310 return NULL;
311
312 mpz_sub(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000313 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000314} /* mpz_substract() */
315
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000316static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000317mpz_multiply(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000318{
319#ifdef MPZ_SPARE_MALLOC
320 int cmpres;
321#endif /* def MPZ_SPARE_MALLOC */
322 mpzobject *z;
323
324
325#ifdef MPZ_SPARE_MALLOC
326 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000327 Py_INCREF(mpz_value_zero);
328 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000329 }
330 if (cmpres > 0 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000331 Py_INCREF(b);
332 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000333 }
334
335 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long_int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000336 Py_INCREF(mpz_value_zero);
337 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000338 }
339 if (cmpres > 0 && mpz_cmp_ui(&b->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000340 Py_INCREF(a);
341 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000342 }
343#endif /* MPZ_SPARE_MALLOC */
344
345 if ((z = newmpzobject()) == NULL)
346 return NULL;
347
348 mpz_mul( &z->mpz, &a->mpz, &b->mpz );
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000349 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000350
351} /* mpz_multiply() */
352
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000353static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000354mpz_divide(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000355{
356#ifdef MPZ_SPARE_MALLOC
357 int cmpres;
358#endif /* def MPZ_SPARE_MALLOC */
359 mpzobject *z;
360
361
362 if ((
363#ifdef MPZ_SPARE_MALLOC
364 cmpres =
365#endif /* def MPZ_SPARE_MALLOC */
366 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000367 PyErr_SetString(PyExc_ZeroDivisionError, "mpz./ by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000368 return NULL;
369 }
370#ifdef MPZ_SPARE_MALLOC
371 if (cmpres > 0 && mpz_cmp_ui(&b->mpz(unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000372 Py_INCREF(a);
373 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000374 }
375#endif /* def MPZ_SPARE_MALLOC */
376
377 if ((z = newmpzobject()) == NULL)
378 return NULL;
379
380#ifdef MPZ_TEST_DIV
381 fputs("mpz_divide: div result", stderr);
382 mpz_div(&z->mpz, &a->mpz, &b->mpz);
383 mpz_out_str(stderr, 10, &z->mpz);
384 putc('\n', stderr);
385#endif /* def MPZ_TEST_DIV */
386#ifdef MPZ_MDIV_BUG
387 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
388 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)) {
389 /*
390 ** numerator has other sign than denominator: we have
391 ** to look at the remainder for a correction, since mpz_mdiv
392 ** also calls mpz_divmod, I can as well do it myself
393 */
394 MP_INT tmpmpz;
395
396
397 mpz_init(&tmpmpz);
398 mpz_divmod(&z->mpz, &tmpmpz, &a->mpz, &b->mpz);
399
400 if (mpz_cmp_ui(&tmpmpz, (unsigned long int)0) != 0)
401 mpz_sub_ui(&z->mpz, &z->mpz, (unsigned long int)1);
402
403 mpz_clear(&tmpmpz);
404 }
405 else
406 mpz_div(&z->mpz, &a->mpz, &b->mpz);
407 /* the ``naive'' implementation does it right for operands
408 having the same sign */
409
410#else /* def MPZ_MDIV_BUG */
411 mpz_mdiv(&z->mpz, &a->mpz, &b->mpz);
412#endif /* def MPZ_MDIV_BUG else */
413#ifdef MPZ_TEST_DIV
414 fputs("mpz_divide: mdiv result", stderr);
415 mpz_out_str(stderr, 10, &z->mpz);
416 putc('\n', stderr);
417#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000418 return (PyObject *)z;
Fred Drakec17b3cf2001-02-12 16:48:13 +0000419
Guido van Rossum5f59d601992-12-14 16:59:51 +0000420} /* mpz_divide() */
421
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000422static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000423mpz_remainder(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000424{
425#ifdef MPZ_SPARE_MALLOC
426 int cmpres;
427#endif /* def MPZ_SPARE_MALLOC */
428 mpzobject *z;
429
Fred Drakec17b3cf2001-02-12 16:48:13 +0000430
Guido van Rossum5f59d601992-12-14 16:59:51 +0000431 if ((
432#ifdef MPZ_SPARE_MALLOC
433 cmpres =
434#endif /* def MPZ_SPARE_MALLOC */
435 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000436 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.% by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000437 return NULL;
438 }
439#ifdef MPZ_SPARE_MALLOC
440 if (cmpres > 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000441 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)2)) == 0)
442 {
443 Py_INCREF(mpz_value_one);
444 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000445 }
446 if (cmpres < 0) {
447 /* b must be 1 now */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000448 Py_INCREF(mpz_value_zero);
449 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000450 }
451 }
452#endif /* def MPZ_SPARE_MALLOC */
453
454 if ((z = newmpzobject()) == NULL)
455 return NULL;
456
457#ifdef MPZ_TEST_DIV
458 fputs("mpz_remain: mod result", stderr);
459 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
460 mpz_out_str(stderr, 10, &z->mpz);
461 putc('\n', stderr);
462#endif /* def MPZ_TEST_DIV */
463#ifdef MPZ_MDIV_BUG
464
465 /* the ``naive'' implementation does it right for operands
466 having the same sign */
467 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
468
469 /* assumption: z, a and b all point to different locations */
470 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
471 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
472 && mpz_cmp_ui(&z->mpz, (unsigned long int)0) != 0)
473 mpz_add(&z->mpz, &z->mpz, &b->mpz);
474 /*
475 ** numerator has other sign than denominator: we have
476 ** to look at the remainder for a correction, since mpz_mdiv
477 ** also calls mpz_divmod, I can as well do it myself
478 */
479#else /* def MPZ_MDIV_BUG */
480 mpz_mmod(&z->mpz, &a->mpz, &b->mpz);
481#endif /* def MPZ_MDIV_BUG else */
482#ifdef MPZ_TEST_DIV
483 fputs("mpz_remain: mmod result", stderr);
484 mpz_out_str(stderr, 10, &z->mpz);
485 putc('\n', stderr);
486#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000487 return (PyObject *)z;
Fred Drakec17b3cf2001-02-12 16:48:13 +0000488
Guido van Rossum5f59d601992-12-14 16:59:51 +0000489} /* mpz_remainder() */
490
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000491static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000492mpz_div_and_mod(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000493{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000494 PyObject *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000495 mpzobject *x = NULL, *y = NULL;
496
497
498 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000499 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.divmod by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000500 return NULL;
501 }
502
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000503 if ((z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +0000504 || (x = newmpzobject()) == NULL
505 || (y = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000506 Py_XDECREF(z);
507 Py_XDECREF(x);
508 Py_XDECREF(y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000509 return NULL;
510 }
511
512#ifdef MPZ_TEST_DIV
513 fputs("mpz_divmod: dm result", stderr);
514 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
515 mpz_out_str(stderr, 10, &x->mpz);
516 putc('\n', stderr);
517 mpz_out_str(stderr, 10, &y->mpz);
518 putc('\n', stderr);
519#endif /* def MPZ_TEST_DIV */
520#ifdef MPZ_MDIV_BUG
521 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
522 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
523 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
524 && mpz_cmp_ui(&y->mpz, (unsigned long int)0) != 0) {
525 /*
526 ** numerator has other sign than denominator: we have
527 ** to look at the remainder for a correction.
528 */
529 mpz_add(&y->mpz, &y->mpz, &b->mpz);
530 mpz_sub_ui(&x->mpz, &x->mpz, (unsigned long int)1);
531 }
532#else /* def MPZ_MDIV_BUG */
533 mpz_mdivmod( &x->mpz, &y->mpz, &a->mpz, &b->mpz );
534#endif /* def MPZ_MDIV_BUG else */
535#ifdef MPZ_TEST_DIV
536 fputs("mpz_divmod: mdm result", stderr);
537 mpz_out_str(stderr, 10, &x->mpz);
538 putc('\n', stderr);
539 mpz_out_str(stderr, 10, &y->mpz);
540 putc('\n', stderr);
541#endif /* def MPZ_TEST_DIV */
542
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000543 (void)PyTuple_SetItem(z, 0, (PyObject *)x);
544 (void)PyTuple_SetItem(z, 1, (PyObject *)y);
Fred Drakec17b3cf2001-02-12 16:48:13 +0000545
Guido van Rossum5f59d601992-12-14 16:59:51 +0000546 return z;
547} /* mpz_div_and_mod() */
548
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000549static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000550mpz_power(mpzobject *a, mpzobject *b, mpzobject *m)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000551{
552 mpzobject *z;
553 int cmpres;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000554
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000555 if ((PyObject *)m != Py_None) {
556 mpzobject *z2;
557 Py_INCREF(Py_None);
558 z=(mpzobject *)mpz_power(a, b, (mpzobject *)Py_None);
559 Py_DECREF(Py_None);
560 if (z==NULL) return((PyObject *)z);
561 z2=(mpzobject *)mpz_remainder(z, m);
562 Py_DECREF(z);
563 return((PyObject *)z2);
564 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000565
566 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
567 /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
568
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000569 Py_INCREF(mpz_value_one);
570 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000571 }
Fred Drakec17b3cf2001-02-12 16:48:13 +0000572
Guido van Rossum5f59d601992-12-14 16:59:51 +0000573 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000574 PyErr_SetString(PyExc_ValueError,
575 "mpz.pow to negative exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000576 return NULL;
577 }
578
579 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
580 /* the base is 0 */
581
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000582 Py_INCREF(mpz_value_zero);
583 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000584 }
585 else if (cmpres > 0
586 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
587 /* the base is 1 */
588
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000589 Py_INCREF(mpz_value_one);
590 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000591 }
592 else if (cmpres < 0
593 && mpz_cmp_si(&a->mpz, (long int)-1) == 0) {
594
595 MP_INT tmpmpz;
596 /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
597 /* XXX this code needs to be optimized: what's better?
598 mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
599 for *un*obvious reasons */
600
601 /* is the exponent even? */
602 mpz_init(&tmpmpz);
603
604 /* look to the remainder after a division by (1 << 1) */
605 mpz_mod_2exp(&tmpmpz, &b->mpz, (unsigned long int)1);
606
607 if (mpz_cmp_ui(&tmpmpz, (unsigned int)0) == 0) {
608 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000609 Py_INCREF(mpz_value_one);
610 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000611 }
612 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000613 Py_INCREF(mpz_value_mone);
614 return (PyObject *)mpz_value_mone;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000615 }
616
617#ifdef MPZ_LIB_DOES_CHECKING
618 /* check if it's doable: sizeof(exp) > sizeof(long) &&
619 abs(base) > 1 ?? --> No Way */
620 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000621 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000622#else /* def MPZ_LIB_DOES_CHECKING */
623 /* wet finger method */
624 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000625 PyErr_SetString(PyExc_ValueError,
626 "mpz.pow outrageous exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000627 return NULL;
628 }
629#endif /* def MPZ_LIB_DOES_CHECKING else */
630
631 if ((z = newmpzobject()) == NULL)
632 return NULL;
Fred Drakec17b3cf2001-02-12 16:48:13 +0000633
Guido van Rossum5f59d601992-12-14 16:59:51 +0000634 mpz_pow_ui(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Fred Drakec17b3cf2001-02-12 16:48:13 +0000635
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000636 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000637} /* mpz_power() */
638
639
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000640static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000641mpz_negative(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000642{
643 mpzobject *z;
644
Fred Drakec17b3cf2001-02-12 16:48:13 +0000645
Guido van Rossum5f59d601992-12-14 16:59:51 +0000646#ifdef MPZ_SPARE_MALLOC
647 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) == 0) {
648 /* -0 == 0 */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000649 Py_INCREF(v);
650 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000651 }
652#endif /* def MPZ_SPARE_MALLOC */
653
654 if ((z = newmpzobject()) == NULL)
655 return NULL;
656
657 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000658 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000659} /* mpz_negative() */
660
661
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000662static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000663mpz_positive(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000664{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000665 Py_INCREF(v);
666 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000667} /* mpz_positive() */
668
669
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000670static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000671mpz_absolute(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000672{
673 mpzobject *z;
674
Fred Drakec17b3cf2001-02-12 16:48:13 +0000675
Guido van Rossum5f59d601992-12-14 16:59:51 +0000676 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000677 Py_INCREF(v);
678 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000679 }
680
681 if ((z = newmpzobject()) == NULL)
682 return NULL;
683
684 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000685 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000686} /* mpz_absolute() */
687
688static int
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000689mpz_nonzero(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000690{
691 return mpz_cmp_ui(&v->mpz, (unsigned long int)0) != 0;
692} /* mpz_nonzero() */
693
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000694static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000695py_mpz_invert(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000696{
697 mpzobject *z;
698
699
700 /* I think mpz_com does exactly what needed */
701 if ((z = newmpzobject()) == NULL)
702 return NULL;
703
704 mpz_com(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000705 return (PyObject *)z;
Guido van Rossum272841c1996-08-19 23:06:45 +0000706} /* py_mpz_invert() */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000707
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000708static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000709mpz_lshift(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000710{
711 int cmpres;
712 mpzobject *z;
713
714
715 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
716 /* a << 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000717 Py_INCREF(a);
718 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000719 }
720
721 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000722 PyErr_SetString(PyExc_ValueError,
723 "mpz.<< negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000724 return NULL;
725 }
726
727#ifdef MPZ_LIB_DOES_CHECKING
728 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000729 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000730#else /* def MPZ_LIB_DOES_CHECKING */
731 /* wet finger method */
732 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000733 PyErr_SetString(PyExc_ValueError,
734 "mpz.<< outrageous shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000735 return NULL;
736 }
737#endif /* def MPZ_LIB_DOES_CHECKING else */
738
739 if ((z = newmpzobject()) == NULL)
740 return NULL;
741
742 mpz_mul_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000743 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000744} /* mpz_lshift() */
745
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000746static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000747mpz_rshift(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000748{
749 int cmpres;
750 mpzobject *z;
751
752
753 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
754 /* a >> 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000755 Py_INCREF(a);
756 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000757 }
758
759 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000760 PyErr_SetString(PyExc_ValueError,
761 "mpz.>> negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000762 return NULL;
763 }
764
765 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000766 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000767
768 if ((z = newmpzobject()) == NULL)
769 return NULL;
770
771 mpz_div_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000772 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000773} /* mpz_rshift() */
774
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000775static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000776mpz_andfunc(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000777{
778 mpzobject *z;
779
780
781 if ((z = newmpzobject()) == NULL)
782 return NULL;
783
784 mpz_and(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000785 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000786} /* mpz_andfunc() */
787
788/* hack Hack HAck HACk HACK, XXX this code is dead slow */
789void
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000790mpz_xor(MP_INT *res, const MP_INT *op1, const MP_INT *op2)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000791{
792 MP_INT tmpmpz;
Fred Drakec17b3cf2001-02-12 16:48:13 +0000793
Guido van Rossum5f59d601992-12-14 16:59:51 +0000794 mpz_init(&tmpmpz);
795
796 mpz_and(res, op1, op2);
797 mpz_com(&tmpmpz, res);
798 mpz_ior(res, op1, op2);
799 mpz_and(res, res, &tmpmpz);
800
801 mpz_clear(&tmpmpz);
802} /* mpz_xor() HACK */
803
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000804static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000805mpz_xorfunc(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000806{
807 mpzobject *z;
808
809
810 if ((z = newmpzobject()) == NULL)
811 return NULL;
812
813 mpz_xor(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000814 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000815} /* mpz_xorfunc() */
816
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000817static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000818mpz_orfunc(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000819{
820 mpzobject *z;
821
822
823 if ((z = newmpzobject()) == NULL)
824 return NULL;
825
826 mpz_ior(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000827 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000828} /* mpz_orfunc() */
829
830/* MPZ initialisation */
831
832#include "longintrepr.h"
833
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000834static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000835MPZ_mpz(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000836{
837 mpzobject *mpzp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000838
839
840#ifdef MPZ_DEBUG
841 fputs("MPZ_mpz() called...\n", stderr);
842#endif /* def MPZ_DEBUG */
843
Guido van Rossum5f59d601992-12-14 16:59:51 +0000844 /* at least we know it's some object */
Neal Norwitz02098fa2002-04-01 01:37:14 +0000845 /* note DON't Py_DECREF args */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000846
Neal Norwitz02098fa2002-04-01 01:37:14 +0000847 if (PyInt_Check(args)) {
848 long lval = PyInt_AS_LONG(args);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000849 if (lval == (long)0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000850 Py_INCREF(mpz_value_zero);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000851 mpzp = mpz_value_zero;
852 }
853 else if (lval == (long)1) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000854 Py_INCREF(mpz_value_one);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000855 mpzp = mpz_value_one;
856 }
857 else if ((mpzp = newmpzobject()) == NULL)
858 return NULL;
859 else mpz_set_si(&mpzp->mpz, lval);
860 }
Neal Norwitz02098fa2002-04-01 01:37:14 +0000861 else if (PyLong_Check(args)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000862 MP_INT mplongdigit;
863 int i;
864 unsigned char isnegative;
Fred Drakec17b3cf2001-02-12 16:48:13 +0000865
Guido van Rossum5f59d601992-12-14 16:59:51 +0000866
867 if ((mpzp = newmpzobject()) == NULL)
868 return NULL;
869
870 mpz_set_si(&mpzp->mpz, 0L);
871 mpz_init(&mplongdigit);
Fred Drakec17b3cf2001-02-12 16:48:13 +0000872
Guido van Rossum5f59d601992-12-14 16:59:51 +0000873 /* how we're gonna handle this? */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000874 if ((isnegative =
Neal Norwitz02098fa2002-04-01 01:37:14 +0000875 ((i = ((PyLongObject *)args)->ob_size) < 0) ))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000876 i = -i;
877
878 while (i--) {
879 mpz_set_ui(&mplongdigit,
880 (unsigned long)
Neal Norwitz02098fa2002-04-01 01:37:14 +0000881 ((PyLongObject *)args)->ob_digit[i]);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000882 mpz_mul_2exp(&mplongdigit,&mplongdigit,
883 (unsigned long int)i * SHIFT);
884 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
885 }
886
887 if (isnegative)
888 mpz_neg(&mpzp->mpz, &mpzp->mpz);
889
890 /* get rid of allocation for tmp variable */
891 mpz_clear(&mplongdigit);
892 }
Neal Norwitz02098fa2002-04-01 01:37:14 +0000893 else if (PyString_Check(args)) {
894 unsigned char *cp = (unsigned char *)PyString_AS_STRING(args);
895 int len = PyString_GET_SIZE(args);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000896 MP_INT mplongdigit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000897
898 if ((mpzp = newmpzobject()) == NULL)
899 return NULL;
900
901 mpz_set_si(&mpzp->mpz, 0L);
902 mpz_init(&mplongdigit);
Fred Drakec17b3cf2001-02-12 16:48:13 +0000903
Guido van Rossum5f59d601992-12-14 16:59:51 +0000904 /* let's do it the same way as with the long conversion:
905 without thinking how it can be faster (-: :-) */
906
907 cp += len;
908 while (len--) {
909 mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
910 mpz_mul_2exp(&mplongdigit,&mplongdigit,
911 (unsigned long int)len * 8);
912 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
913 }
914
915 /* get rid of allocation for tmp variable */
916 mpz_clear(&mplongdigit);
917 }
Neal Norwitz02098fa2002-04-01 01:37:14 +0000918 else if (is_mpzobject(args)) {
919 Py_INCREF(args);
920 mpzp = (mpzobject *)args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000921 }
922 else {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000923 PyErr_SetString(PyExc_TypeError,
924"mpz.mpz() expects integer, long, string or mpz object argument");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000925 return NULL;
926 }
927
928
929#ifdef MPZ_DEBUG
930 fputs("MPZ_mpz: created mpz=", stderr);
931 mpz_out_str(stderr, 10, &mpzp->mpz);
932 putc('\n', stderr);
933#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000934 return (PyObject *)mpzp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000935} /* MPZ_mpz() */
936
937static mpzobject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000938mpz_mpzcoerce(PyObject *z)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000939{
940 /* shortcut: 9 out of 10 times the type is already ok */
941 if (is_mpzobject(z)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000942 Py_INCREF(z);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000943 return (mpzobject *)z; /* coercion succeeded */
944 }
945
946 /* what types do we accept?: intobjects and longobjects */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000947 if (PyInt_Check(z) || PyLong_Check(z))
948 return (mpzobject *)MPZ_mpz((PyObject *)NULL, z);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000949
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000950 PyErr_SetString(PyExc_TypeError,
951 "number coercion (to mpzobject) failed");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000952 return NULL;
953} /* mpz_mpzcoerce() */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000954
955/* Forward */
Tim Petersdbd9ba62000-07-09 03:09:57 +0000956static void mpz_divm(MP_INT *res, const MP_INT *num,
957 const MP_INT *den, const MP_INT *mod);
Guido van Rossum67a5fdb1993-12-17 12:09:14 +0000958
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000959static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000960MPZ_powm(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000961{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000962 PyObject *base, *exp, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000963 mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
964 mpzobject *z;
965 int tstres;
966
Fred Drakec17b3cf2001-02-12 16:48:13 +0000967
Neal Norwitz02098fa2002-04-01 01:37:14 +0000968 if (!PyArg_ParseTuple(args, "OOO", &base, &exp, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000969 return NULL;
970
971 if ((mpzbase = mpz_mpzcoerce(base)) == NULL
972 || (mpzexp = mpz_mpzcoerce(exp)) == NULL
973 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
974 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000975 Py_XDECREF(mpzbase);
976 Py_XDECREF(mpzexp);
977 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000978 return NULL;
979 }
980
981 if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000982 Py_INCREF(mpz_value_one);
983 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000984 }
985
Neal Norwitz02098fa2002-04-01 01:37:14 +0000986 if (mpz_cmp_ui(&mpzmod->mpz, 0) == 0) {
987 Py_DECREF(mpzbase);
988 Py_DECREF(mpzexp);
989 Py_DECREF(mpzmod);
990 PyErr_SetString(PyExc_ValueError, "modulus cannot be 0");
991 return NULL;
992 }
993
Guido van Rossum5f59d601992-12-14 16:59:51 +0000994 if (tstres < 0) {
995 MP_INT absexp;
996 /* negative exp */
997
998 mpz_init_set(&absexp, &mpzexp->mpz);
999 mpz_abs(&absexp, &absexp);
1000 mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
1001
1002 mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
1003
1004 mpz_clear(&absexp);
1005 }
1006 else {
1007 mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
1008 }
Fred Drakec17b3cf2001-02-12 16:48:13 +00001009
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001010 Py_DECREF(mpzbase);
1011 Py_DECREF(mpzexp);
1012 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001013
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001014 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001015} /* MPZ_powm() */
1016
1017
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001018static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001019MPZ_gcd(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001020{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001021 PyObject *op1, *op2;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001022 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1023 mpzobject *z;
1024
Fred Drakec17b3cf2001-02-12 16:48:13 +00001025
Neal Norwitz02098fa2002-04-01 01:37:14 +00001026 if (!PyArg_ParseTuple(args, "OO", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001027 return NULL;
1028
1029 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1030 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
1031 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001032 Py_XDECREF(mpzop1);
1033 Py_XDECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001034 return NULL;
1035 }
1036
1037 /* ok, we have three mpzobjects, and an initialised result holder */
1038 mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
1039
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001040 Py_DECREF(mpzop1);
1041 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001042
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001043 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001044} /* MPZ_gcd() */
1045
1046
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001047static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001048MPZ_gcdext(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001049{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001050 PyObject *op1, *op2, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001051 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1052 mpzobject *g = NULL, *s = NULL, *t = NULL;
1053
Fred Drakec17b3cf2001-02-12 16:48:13 +00001054
Neal Norwitz02098fa2002-04-01 01:37:14 +00001055 if (!PyArg_ParseTuple(args, "OO", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001056 return NULL;
1057
1058 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1059 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001060 || (z = PyTuple_New(3)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001061 || (g = newmpzobject()) == NULL
1062 || (s = newmpzobject()) == NULL
1063 || (t = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001064 Py_XDECREF(mpzop1);
1065 Py_XDECREF(mpzop2);
1066 Py_XDECREF(z);
1067 Py_XDECREF(g);
1068 Py_XDECREF(s);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001069 /*Py_XDECREF(t);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001070 return NULL;
1071 }
1072
1073 mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
1074
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001075 Py_DECREF(mpzop1);
1076 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001077
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001078 (void)PyTuple_SetItem(z, 0, (PyObject *)g);
1079 (void)PyTuple_SetItem(z, 1, (PyObject *)s);
1080 (void)PyTuple_SetItem(z, 2, (PyObject *)t);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001081
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001082 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001083} /* MPZ_gcdext() */
1084
1085
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001086static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001087MPZ_sqrt(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001088{
Guido van Rossum5f59d601992-12-14 16:59:51 +00001089 mpzobject *mpzop = NULL;
1090 mpzobject *z;
1091
Fred Drakec17b3cf2001-02-12 16:48:13 +00001092
Neal Norwitz02098fa2002-04-01 01:37:14 +00001093 if ((mpzop = mpz_mpzcoerce(args)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001094 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001095 Py_XDECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001096 return NULL;
1097 }
1098
1099 mpz_sqrt(&z->mpz, &mpzop->mpz);
1100
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001101 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001102
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001103 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001104} /* MPZ_sqrt() */
1105
1106
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001107static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001108MPZ_sqrtrem(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001109{
Neal Norwitz02098fa2002-04-01 01:37:14 +00001110 PyObject *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001111 mpzobject *mpzop = NULL;
1112 mpzobject *root = NULL, *rem = NULL;
1113
Neal Norwitz02098fa2002-04-01 01:37:14 +00001114 if ((mpzop = mpz_mpzcoerce(args)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001115 || (z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001116 || (root = newmpzobject()) == NULL
1117 || (rem = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001118 Py_XDECREF(mpzop);
1119 Py_XDECREF(z);
1120 Py_XDECREF(root);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001121 /*Py_XDECREF(rem);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001122 return NULL;
1123 }
1124
1125 mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
1126
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001127 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001128
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001129 (void)PyTuple_SetItem(z, 0, (PyObject *)root);
1130 (void)PyTuple_SetItem(z, 1, (PyObject *)rem);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001131
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001132 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001133} /* MPZ_sqrtrem() */
1134
1135
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001136static void
Guido van Rossum5f59d601992-12-14 16:59:51 +00001137mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001138{
1139 MP_INT s0, s1, q, r, x, d0, d1;
1140
1141 mpz_init_set(&s0, num);
1142 mpz_init_set_ui(&s1, 0);
1143 mpz_init(&q);
1144 mpz_init(&r);
1145 mpz_init(&x);
1146 mpz_init_set(&d0, den);
1147 mpz_init_set(&d1, mod);
1148
Guido van Rossum272841c1996-08-19 23:06:45 +00001149#ifdef GMP2
1150 while (d1._mp_size != 0) {
1151#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001152 while (d1.size != 0) {
Guido van Rossum272841c1996-08-19 23:06:45 +00001153#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001154 mpz_divmod(&q, &r, &d0, &d1);
1155 mpz_set(&d0, &d1);
1156 mpz_set(&d1, &r);
1157
1158 mpz_mul(&x, &s1, &q);
1159 mpz_sub(&x, &s0, &x);
1160 mpz_set(&s0, &s1);
1161 mpz_set(&s1, &x);
1162 }
1163
Guido van Rossum272841c1996-08-19 23:06:45 +00001164#ifdef GMP2
1165 if (d0._mp_size != 1 || d0._mp_d[0] != 1)
1166 res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
1167#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001168 if (d0.size != 1 || d0.d[0] != 1)
1169 res->size = 0; /* trouble: the gcd != 1; set s to zero */
Guido van Rossum272841c1996-08-19 23:06:45 +00001170#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001171 else {
1172#ifdef MPZ_MDIV_BUG
1173 /* watch out here! first check the signs, and then perform
1174 the mpz_mod() since mod could point to res */
1175 if ((s0.size < 0) != (mod->size < 0)) {
1176 mpz_mod(res, &s0, mod);
1177
1178 if (res->size)
1179 mpz_add(res, res, mod);
1180 }
1181 else
1182 mpz_mod(res, &s0, mod);
Fred Drakec17b3cf2001-02-12 16:48:13 +00001183
Guido van Rossum5f59d601992-12-14 16:59:51 +00001184#else /* def MPZ_MDIV_BUG */
1185 mpz_mmod(res, &s0, mod);
1186#endif /* def MPZ_MDIV_BUG else */
1187 }
1188
1189 mpz_clear(&s0);
1190 mpz_clear(&s1);
1191 mpz_clear(&q);
1192 mpz_clear(&r);
1193 mpz_clear(&x);
1194 mpz_clear(&d0);
1195 mpz_clear(&d1);
1196} /* mpz_divm() */
1197
1198
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001199static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001200MPZ_divm(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001201{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001202 PyObject *num, *den, *mod;
Fred Drake06fdd2d2000-10-11 21:53:34 +00001203 mpzobject *mpznum, *mpzden = NULL, *mpzmod = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001204 mpzobject *z = NULL;
1205
Fred Drakec17b3cf2001-02-12 16:48:13 +00001206
Neal Norwitz02098fa2002-04-01 01:37:14 +00001207 if (!PyArg_ParseTuple(args, "OOO", &num, &den, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001208 return NULL;
1209
1210 if ((mpznum = mpz_mpzcoerce(num)) == NULL
1211 || (mpzden = mpz_mpzcoerce(den)) == NULL
1212 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1213 || (z = newmpzobject()) == NULL ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001214 Py_XDECREF(mpznum);
1215 Py_XDECREF(mpzden);
1216 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001217 return NULL;
1218 }
Fred Drakec17b3cf2001-02-12 16:48:13 +00001219
Guido van Rossum5f59d601992-12-14 16:59:51 +00001220 mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
1221
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001222 Py_DECREF(mpznum);
1223 Py_DECREF(mpzden);
1224 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001225
1226 if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001227 Py_DECREF(z);
1228 PyErr_SetString(PyExc_ValueError,
1229 "gcd(den, mod) != 1 or num == 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001230 return NULL;
1231 }
1232
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001233 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001234} /* MPZ_divm() */
1235
1236
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001237static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001238mpz_int(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001239{
1240 long sli;
1241
1242
Guido van Rossum5f59d601992-12-14 16:59:51 +00001243 if (mpz_size(&self->mpz) > 1
1244 || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001245 PyErr_SetString(PyExc_ValueError,
1246 "mpz.int() arg too long to convert");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001247 return NULL;
1248 }
1249
1250 if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
1251 sli = -sli;
1252
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001253 return PyInt_FromLong(sli);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001254} /* mpz_int() */
1255
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001256static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001257mpz_long(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001258{
1259 int i, isnegative;
1260 unsigned long int uli;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001261 PyLongObject *longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001262 int ldcount;
1263 int bitpointer, newbitpointer;
1264 MP_INT mpzscratch;
1265
1266
Guido van Rossum5f59d601992-12-14 16:59:51 +00001267 /* determine length of python-long to be allocated */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001268 if ((longobjp = _PyLong_New(i = (int)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001269 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
1270 + SHIFT - 1) /
1271 SHIFT))) == NULL)
1272 return NULL;
1273
1274 /* determine sign, and copy self to scratch var */
1275 mpz_init_set(&mpzscratch, &self->mpz);
Guido van Rossum272841c1996-08-19 23:06:45 +00001276 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001277 mpz_neg(&mpzscratch, &mpzscratch);
1278
1279 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001280 e.g. dismantle mpzscratch, build PyLongObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001281
1282 bitpointer = 0; /* the number of valid bits in stock */
1283 newbitpointer = 0;
1284 ldcount = 0; /* the python-long limb counter */
1285 uli = (unsigned long int)0;
1286 while (i--) {
1287 longobjp->ob_digit[ldcount] = uli & MASK;
1288
1289 /* check if we've had enough bits for this digit */
1290 if (bitpointer < SHIFT) {
1291 uli = mpz_get_ui(&mpzscratch);
1292 longobjp->ob_digit[ldcount] |=
1293 (uli << bitpointer) & MASK;
1294 uli >>= SHIFT-bitpointer;
1295 bitpointer += BITS_PER_MP_LIMB;
1296 mpz_div_2exp(&mpzscratch, &mpzscratch,
1297 BITS_PER_MP_LIMB);
1298 }
1299 else
1300 uli >>= SHIFT;
1301 bitpointer -= SHIFT;
1302 ldcount++;
1303 }
1304
1305 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1306 mpz_clear(&mpzscratch);
1307 assert(ldcount <= longobjp->ob_size);
1308
1309 /* long_normalize() is file-static */
1310 /* longobjp = long_normalize(longobjp); */
1311 while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
1312 ldcount--;
1313 longobjp->ob_size = ldcount;
Fred Drakec17b3cf2001-02-12 16:48:13 +00001314
Guido van Rossum5f59d601992-12-14 16:59:51 +00001315
1316 if (isnegative)
1317 longobjp->ob_size = -longobjp->ob_size;
1318
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001319 return (PyObject *)longobjp;
Fred Drakec17b3cf2001-02-12 16:48:13 +00001320
Guido van Rossum5f59d601992-12-14 16:59:51 +00001321} /* mpz_long() */
1322
1323
1324/* I would have avoided pow() anyways, so ... */
1325static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
Fred Drakec17b3cf2001-02-12 16:48:13 +00001326
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001327static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001328mpz_float(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001329{
1330 int i, isnegative;
1331 double x;
1332 double mulstate;
1333 MP_INT mpzscratch;
1334
1335
Guido van Rossum5f59d601992-12-14 16:59:51 +00001336 i = (int)mpz_size(&self->mpz);
Fred Drakec17b3cf2001-02-12 16:48:13 +00001337
Guido van Rossum5f59d601992-12-14 16:59:51 +00001338 /* determine sign, and copy abs(self) to scratch var */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001339 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
1340 {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001341 mpz_init(&mpzscratch);
1342 mpz_neg(&mpzscratch, &self->mpz);
1343 }
1344 else
1345 mpz_init_set(&mpzscratch, &self->mpz);
1346
1347 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001348 e.g. dismantle mpzscratch, build PyFloatObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001349
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001350 /* Can this overflow? Dunno, protect against that possibility. */
1351 PyFPE_START_PROTECT("mpz_float", return 0)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001352 x = 0.0;
1353 mulstate = 1.0;
1354 while (i--) {
1355 x += mulstate * mpz_get_ui(&mpzscratch);
1356 mulstate *= multiplier;
1357 mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
1358 }
Guido van Rossum45b83911997-03-14 04:32:50 +00001359 PyFPE_END_PROTECT(mulstate)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001360
1361 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1362 mpz_clear(&mpzscratch);
1363
1364 if (isnegative)
1365 x = -x;
1366
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001367 return PyFloat_FromDouble(x);
Fred Drakec17b3cf2001-02-12 16:48:13 +00001368
Guido van Rossum5f59d601992-12-14 16:59:51 +00001369} /* mpz_float() */
1370
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001371static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001372mpz_hex(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001373{
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001374 return mpz_format((PyObject *)self, 16, (unsigned char)1);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001375} /* mpz_hex() */
Fred Drakec17b3cf2001-02-12 16:48:13 +00001376
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001377static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001378mpz_oct(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001379{
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001380 return mpz_format((PyObject *)self, 8, (unsigned char)1);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001381} /* mpz_oct() */
Fred Drakec17b3cf2001-02-12 16:48:13 +00001382
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001383static PyObject *
Neal Norwitzba3a16c2002-03-31 15:27:00 +00001384mpz_binary(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001385{
1386 int size;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001387 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001388 char *cp;
1389 MP_INT mp;
1390 unsigned long ldigit;
Fred Drakec17b3cf2001-02-12 16:48:13 +00001391
Guido van Rossum5f59d601992-12-14 16:59:51 +00001392 if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001393 PyErr_SetString(PyExc_ValueError,
1394 "mpz.binary() arg must be >= 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001395 return NULL;
1396 }
1397
1398 mpz_init_set(&mp, &self->mpz);
1399 size = (int)mpz_size(&mp);
1400
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001401 if ((strobjp = (PyStringObject *)
1402 PyString_FromStringAndSize(
1403 (char *)0, size * sizeof (unsigned long int))) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001404 return NULL;
1405
1406 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001407 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001408
1409 /* this has been programmed using a (fairly) decent lib-i/f it could
1410 be must faster if we looked into the GMP lib */
1411 while (size--) {
1412 ldigit = mpz_get_ui(&mp);
1413 mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
1414 *cp++ = (unsigned char)(ldigit & 0xFF);
1415 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1416 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1417 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
Fred Drakec17b3cf2001-02-12 16:48:13 +00001418 if (sizeof(ldigit) == 8 && BITS_PER_MP_LIMB == 64) {
1419 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1420 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1421 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1422 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1423 }
Guido van Rossum5f59d601992-12-14 16:59:51 +00001424 }
1425
1426 while (strobjp->ob_size && !*--cp)
1427 strobjp->ob_size--;
1428
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001429 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001430} /* mpz_binary() */
Fred Drakec17b3cf2001-02-12 16:48:13 +00001431
Guido van Rossum5f59d601992-12-14 16:59:51 +00001432
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001433static PyMethodDef mpz_methods[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001434#ifdef MPZ_CONVERSIONS_AS_METHODS
Neal Norwitzba3a16c2002-03-31 15:27:00 +00001435 {"int", mpz_int, METH_NOARGS},
1436 {"long", mpz_long, METH_NOARGS},
1437 {"float", mpz_float, METH_NOARGS},
1438 {"hex", mpz_hex, METH_NOARGS},
1439 {"oct", mpz_oct, METH_NOARGS},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001440#endif /* def MPZ_CONVERSIONS_AS_METHODS */
Neal Norwitzba3a16c2002-03-31 15:27:00 +00001441 {"binary", (PyCFunction)mpz_binary, METH_NOARGS},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001442 {NULL, NULL} /* sentinel */
1443};
1444
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001445static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001446mpz_getattr(mpzobject *self, char *name)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001447{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001448 return Py_FindMethod(mpz_methods, (PyObject *)self, name);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001449} /* mpz_getattr() */
1450
1451
1452static int
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001453mpz_coerce(PyObject **pv, PyObject **pw)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001454{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001455 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001456
1457#ifdef MPZ_DEBUG
1458 fputs("mpz_coerce() called...\n", stderr);
1459#endif /* def MPZ_DEBUG */
1460
1461 assert(is_mpzobject(*pv));
1462
1463 /* always convert other arg to mpz value, except for floats */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001464 if (!PyFloat_Check(*pw)) {
1465 if ((z = (PyObject *)mpz_mpzcoerce(*pw)) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001466 return -1; /* -1: an error always has been set */
1467
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001468 Py_INCREF(*pv);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001469 *pw = z;
1470 }
1471 else {
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001472 if ((z = mpz_float((mpzobject *)(*pv))) == NULL)
1473 return -1;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001474
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001475 Py_INCREF(*pw);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001476 *pv = z;
1477 }
1478 return 0; /* coercion succeeded */
1479
1480} /* mpz_coerce() */
1481
1482
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001483static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001484mpz_repr(PyObject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001485{
1486 return mpz_format(v, 10, (unsigned char)1);
1487} /* mpz_repr() */
1488
1489
1490
Guido van Rossumb6775db1994-08-01 11:34:53 +00001491#define UF (unaryfunc)
1492#define BF (binaryfunc)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001493#define TF (ternaryfunc)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001494#define IF (inquiry)
1495#define CF (coercion)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001496
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001497static PyNumberMethods mpz_as_number = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001498 BF mpz_addition, /*nb_add*/
1499 BF mpz_substract, /*nb_subtract*/
1500 BF mpz_multiply, /*nb_multiply*/
1501 BF mpz_divide, /*nb_divide*/
1502 BF mpz_remainder, /*nb_remainder*/
1503 BF mpz_div_and_mod, /*nb_divmod*/
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001504 TF mpz_power, /*nb_power*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001505 UF mpz_negative, /*nb_negative*/
1506 UF mpz_positive, /*tp_positive*/
1507 UF mpz_absolute, /*tp_absolute*/
1508 IF mpz_nonzero, /*tp_nonzero*/
Guido van Rossum272841c1996-08-19 23:06:45 +00001509 UF py_mpz_invert, /*nb_invert*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001510 BF mpz_lshift, /*nb_lshift*/
1511 BF mpz_rshift, /*nb_rshift*/
1512 BF mpz_andfunc, /*nb_and*/
1513 BF mpz_xorfunc, /*nb_xor*/
1514 BF mpz_orfunc, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001515 CF mpz_coerce, /*nb_coerce*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001516#ifndef MPZ_CONVERSIONS_AS_METHODS
1517 UF mpz_int, /*nb_int*/
1518 UF mpz_long, /*nb_long*/
1519 UF mpz_float, /*nb_float*/
1520 UF mpz_oct, /*nb_oct*/
1521 UF mpz_hex, /*nb_hex*/
1522#endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1523};
1524
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001525static PyTypeObject MPZtype = {
Andrew M. Kuchling22aa6442001-02-06 22:33:45 +00001526 PyObject_HEAD_INIT(NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001527 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +00001528 "mpz.mpz", /*tp_name*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001529 sizeof(mpzobject), /*tp_size*/
1530 0, /*tp_itemsize*/
1531 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001532 (destructor)mpz_dealloc, /*tp_dealloc*/
1533 0, /*tp_print*/
1534 (getattrfunc)mpz_getattr, /*tp_getattr*/
1535 0, /*tp_setattr*/
1536 (cmpfunc)mpz_compare, /*tp_compare*/
1537 (reprfunc)mpz_repr, /*tp_repr*/
1538 &mpz_as_number, /*tp_as_number*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001539};
1540
1541/* List of functions exported by this module */
1542
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001543static PyMethodDef mpz_functions[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001544#if 0
Neal Norwitz02098fa2002-04-01 01:37:14 +00001545 {initialiser_name, MPZ_mpz, METH_O},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001546#else /* 0 */
Barry Warsawabb7efe1996-12-09 23:22:35 +00001547 /* until guido ``fixes'' struct PyMethodDef */
Neal Norwitz02098fa2002-04-01 01:37:14 +00001548 {(char *)initialiser_name, MPZ_mpz, METH_O},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001549#endif /* 0 else */
Neal Norwitz02098fa2002-04-01 01:37:14 +00001550 {"powm", MPZ_powm, METH_VARARGS},
1551 {"gcd", MPZ_gcd, METH_VARARGS},
1552 {"gcdext", MPZ_gcdext, METH_VARARGS},
1553 {"sqrt", MPZ_sqrt, METH_O},
1554 {"sqrtrem", MPZ_sqrtrem, METH_O},
1555 {"divm", MPZ_divm, METH_VARARGS},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001556 {NULL, NULL} /* Sentinel */
1557};
1558
1559
1560/* #define MP_TEST_ALLOC */
1561
1562#ifdef MP_TEST_ALLOC
1563#define MP_TEST_SIZE 4
1564static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001565static mp_test_error(int *location)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001566{
Thomas Wouters7e474022000-07-16 12:04:32 +00001567 /* assumptions: *alloc returns address divisible by 4,
1568 mpz_* routines allocate in chunks divisible by four */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001569 fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001570 Py_FatalError("MP_TEST_ERROR");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001571} /* static mp_test_error() */
1572#define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1573#define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1574#define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1575 ; \
1576 else \
1577 mp_test_error((int *)((char *)(basep) + size))
1578#else /* def MP_TEST_ALLOC */
1579#define MP_EXTRA_ALLOC(size) (size)
1580#define MP_SET_TEST(basep,size)
1581#define MP_DO_TEST(basep,size)
1582#endif /* def MP_TEST_ALLOC else */
1583
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001584void *mp_allocate(size_t alloc_size)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001585{
1586 void *res;
1587
1588#ifdef MPZ_DEBUG
1589 fprintf(stderr, "mp_allocate : size %ld\n",
1590 alloc_size);
1591#endif /* def MPZ_DEBUG */
1592
1593 if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001594 Py_FatalError("mp_allocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001595
1596#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001597 fprintf(stderr, "mp_allocate : address %08p\n", res);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001598#endif /* def MPZ_DEBUG */
1599
1600 MP_SET_TEST(res,alloc_size);
1601
1602 return res;
1603} /* mp_allocate() */
1604
1605
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001606void *mp_reallocate(void *ptr, size_t old_size, size_t new_size)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001607{
1608 void *res;
1609
1610#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001611 fprintf(stderr, "mp_reallocate: old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001612 ptr, old_size);
1613#endif /* def MPZ_DEBUG */
1614
1615 MP_DO_TEST(ptr, old_size);
1616
1617 if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001618 Py_FatalError("mp_reallocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001619
1620#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001621 fprintf(stderr, "mp_reallocate: new address %08p, new size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001622 res, new_size);
1623#endif /* def MPZ_DEBUG */
1624
1625 MP_SET_TEST(res, new_size);
1626
1627 return res;
1628} /* mp_reallocate() */
1629
1630
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001631void mp_free(void *ptr, size_t size)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001632{
1633
1634#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001635 fprintf(stderr, "mp_free : old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001636 ptr, size);
1637#endif /* def MPZ_DEBUG */
1638
1639 MP_DO_TEST(ptr, size);
1640 free(ptr);
1641} /* mp_free() */
1642
1643
1644
1645/* Initialize this module. */
1646
Guido van Rossum3886bb61998-12-04 18:50:17 +00001647DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001648initmpz(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001649{
Fred Drakefcc6c681998-04-03 15:33:43 +00001650 PyObject *module;
1651 PyObject *dict;
1652
Guido van Rossum5f59d601992-12-14 16:59:51 +00001653#ifdef MPZ_DEBUG
1654 fputs( "initmpz() called...\n", stderr );
1655#endif /* def MPZ_DEBUG */
1656
1657 mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
Andrew M. Kuchling22aa6442001-02-06 22:33:45 +00001658 MPZtype.ob_type = &PyType_Type;
Fred Drakefcc6c681998-04-03 15:33:43 +00001659 module = Py_InitModule("mpz", mpz_functions);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001660
1661 /* create some frequently used constants */
1662 if ((mpz_value_zero = newmpzobject()) == NULL)
Barry Warsaw9bfd2bf2000-09-01 09:01:32 +00001663 goto finally;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001664 mpz_set_ui(&mpz_value_zero->mpz, (unsigned long int)0);
1665
1666 if ((mpz_value_one = newmpzobject()) == NULL)
Barry Warsaw9bfd2bf2000-09-01 09:01:32 +00001667 goto finally;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001668 mpz_set_ui(&mpz_value_one->mpz, (unsigned long int)1);
1669
1670 if ((mpz_value_mone = newmpzobject()) == NULL)
Barry Warsaw9bfd2bf2000-09-01 09:01:32 +00001671 goto finally;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001672 mpz_set_si(&mpz_value_mone->mpz, (long)-1);
1673
Fred Drakefcc6c681998-04-03 15:33:43 +00001674 dict = PyModule_GetDict(module);
1675 if (dict != NULL) {
1676 PyDict_SetItemString(dict, "MPZType", (PyObject*)&MPZtype);
1677 }
Barry Warsaw9bfd2bf2000-09-01 09:01:32 +00001678 finally:
1679 return;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001680} /* initmpz() */
Barry Warsaw9bfd2bf2000-09-01 09:01:32 +00001681
Guido van Rossum5f59d601992-12-14 16:59:51 +00001682#ifdef MAKEDUMMYINT
1683int _mpz_dummy_int; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1684#endif /* def MAKEDUMMYINT */