blob: 38fa221f4d936fd84d643a57b739816a1dd9c383 [file] [log] [blame]
Guido van Rossum5f59d601992-12-14 16:59:51 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum5f59d601992-12-14 16:59:51 +00004
5 All Rights Reserved
6
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007Copyright (c) 2000, BeOpen.com.
8Copyright (c) 1995-2000, Corporation for National Research Initiatives.
9Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
10All rights reserved.
Guido van Rossum5f59d601992-12-14 16:59:51 +000011
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000012See the file "Misc/COPYRIGHT" for information on usage and
13redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum5f59d601992-12-14 16:59:51 +000014
15******************************************************************/
Guido van Rossumb6775db1994-08-01 11:34:53 +000016
Guido van Rossum5f59d601992-12-14 16:59:51 +000017/* MPZ module */
18
19/* This module provides an interface to an alternate Multi-Precision
20 library, GNU MP in this case */
21
22/* XXX note: everywhere where mpz_size is called,
23 sizeof (limb) == sizeof (long) has been assumed. */
24
25
26/* MPZ objects */
27
Barry Warsaw3bdf7461996-12-09 23:16:31 +000028#include "Python.h"
Guido van Rossuma597dde1995-01-10 20:56:29 +000029
Guido van Rossum5f59d601992-12-14 16:59:51 +000030#include <assert.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000031#include <sys/types.h> /* For size_t */
Guido van Rossum5f59d601992-12-14 16:59:51 +000032
33/*
34** These are the cpp-flags used in this file...
35**
36**
37** MPZ_MDIV_BUG works around the mpz_m{div,mod,...} routines.
38** This bug has been fixed in a later release of
39** GMP.
40**
41** MPZ_GET_STR_BUG mpz_get_str corrupts memory, seems to be fixed
42** in a later release
43**
44** MPZ_DEBUG generates a bunch of diagnostic messages
45**
46** MPZ_SPARE_MALLOC if set, results in extra code that tries to
47** minimize the creation of extra objects.
48**
49** MPZ_TEST_DIV extra diagnostic output on stderr, when division
50** routines are involved
51**
52** MPZ_LIB_DOES_CHECKING if set, assumes that mpz library doesn't call
53** alloca with arg < 0 (when casted to a signed
54** integral type).
55**
56** MPZ_CONVERSIONS_AS_METHODS if set, presents the conversions as
57** methods. e.g., `mpz(5).long() == 5L'
58** Later, Guido provided an interface to the
59** standard functions. So this flag has no been
60** cleared, and `long(mpz(5)) == 5L'
61**
62** MP_TEST_ALLOC If set, you would discover why MPZ_GET_STR_BUG
63** is needed
64**
65** MAKEDUMMYINT Must be set if dynamic linking will be used
66*/
67
68
69/*
70** IMHO, mpz_m{div,mod,divmod}() do the wrong things when the denominator < 0
Guido van Rossum272841c1996-08-19 23:06:45 +000071** This has been fixed with gmp release 2.0
Guido van Rossum5f59d601992-12-14 16:59:51 +000072*/
73/*#define MPZ_MDIV_BUG fixed the (for me) nexessary parts in libgmp.a */
74/*
75** IMO, mpz_get_str() assumes a bit too large target space, if he doesn't
76** allocate it himself
77*/
Guido van Rossum5f59d601992-12-14 16:59:51 +000078
79#include "gmp.h"
Guido van Rossume7ef74d2000-02-24 15:26:30 +000080
Guido van Rossum57e846f1997-08-17 19:08:33 +000081#if __GNU_MP__ + 0 == 2
Guido van Rossum272841c1996-08-19 23:06:45 +000082#define GMP2
Andrew M. Kuchlingb6f6e952000-02-25 22:23:31 +000083#define BITS_PER_MP_LIMB mp_bits_per_limb
Guido van Rossum272841c1996-08-19 23:06:45 +000084#else
85#define MPZ_GET_STR_BUG
Andrew M. Kuchlingb6f6e952000-02-25 22:23:31 +000086#include "gmp-mparam.h"
Guido van Rossum272841c1996-08-19 23:06:45 +000087#endif
88
Guido van Rossum5f59d601992-12-14 16:59:51 +000089typedef struct {
Barry Warsaw3bdf7461996-12-09 23:16:31 +000090 PyObject_HEAD
Guido van Rossum5f59d601992-12-14 16:59:51 +000091 MP_INT mpz; /* the actual number */
92} mpzobject;
93
Barry Warsaw3bdf7461996-12-09 23:16:31 +000094staticforward PyTypeObject MPZtype;
Guido van Rossum5f59d601992-12-14 16:59:51 +000095
96#define is_mpzobject(v) ((v)->ob_type == &MPZtype)
97
98static const char initialiser_name[] = "mpz";
99
100/* #define MPZ_DEBUG */
101
102static mpzobject *
103newmpzobject()
104{
105 mpzobject *mpzp;
106
107
108#ifdef MPZ_DEBUG
109 fputs( "mpz_object() called...\n", stderr );
110#endif /* def MPZ_DEBUG */
Guido van Rossumb18618d2000-05-03 23:44:39 +0000111 mpzp = PyObject_New(mpzobject, &MPZtype);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000112 if (mpzp == NULL)
113 return NULL;
114
115 mpz_init(&mpzp->mpz); /* actual initialisation */
116 return mpzp;
117} /* newmpzobject() */
118
119#ifdef MPZ_GET_STR_BUG
Guido van Rossum5f59d601992-12-14 16:59:51 +0000120#include "longlong.h"
121#endif /* def MPZ_GET_STR_BUG */
122
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000123static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000124mpz_format(objp, base, withname)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000125 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000126 int base;
127 unsigned char withname;
128{
129 mpzobject *mpzp = (mpzobject *)objp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000130 PyStringObject *strobjp;
Guido van Rossum2650a422000-06-28 21:29:47 +0000131 size_t i;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000132 int cmpres;
133 int taglong;
134 char *cp;
135 char prefix[5], *tcp;
136
137
138 tcp = &prefix[0];
139
140 if (mpzp == NULL || !is_mpzobject(mpzp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000141 PyErr_BadInternalCall();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000142 return NULL;
143 }
144
145 assert(base >= 2 && base <= 36);
146
147 if (withname)
148 i = strlen(initialiser_name) + 2; /* e.g. 'mpz(' + ')' */
149 else
150 i = 0;
151
152 if ((cmpres = mpz_cmp_si(&mpzp->mpz, 0L)) == 0)
153 base = 10; /* '0' in every base, right */
154 else if (cmpres < 0) {
155 *tcp++ = '-';
156 i += 1; /* space to hold '-' */
157 }
158
159#ifdef MPZ_DEBUG
160 fprintf(stderr, "mpz_format: mpz_sizeinbase %d\n",
161 (int)mpz_sizeinbase(&mpzp->mpz, base));
162#endif /* def MPZ_DEBUG */
163#ifdef MPZ_GET_STR_BUG
Guido van Rossum272841c1996-08-19 23:06:45 +0000164#ifdef GMP2
165 i += ((size_t) abs(mpzp->mpz._mp_size) * BITS_PER_MP_LIMB
166 * __mp_bases[base].chars_per_bit_exactly) + 1;
167#else
Guido van Rossum5f59d601992-12-14 16:59:51 +0000168 i += ((size_t) abs(mpzp->mpz.size) * BITS_PER_MP_LIMB
169 * __mp_bases[base].chars_per_bit_exactly) + 1;
Guido van Rossum272841c1996-08-19 23:06:45 +0000170#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +0000171#else /* def MPZ_GET_STR_BUG */
172 i += (int)mpz_sizeinbase(&mpzp->mpz, base);
173#endif /* def MPZ_GET_STR_BUG else */
174
175 if (base == 16) {
176 *tcp++ = '0';
177 *tcp++ = 'x';
178 i += 2; /* space to hold '0x' */
179 }
180 else if (base == 8) {
181 *tcp++ = '0';
182 i += 1; /* space to hold the extra '0' */
183 }
184 else if (base > 10) {
185 *tcp++ = '0' + base / 10;
186 *tcp++ = '0' + base % 10;
187 *tcp++ = '#';
188 i += 3; /* space to hold e.g. '12#' */
189 }
190 else if (base < 10) {
191 *tcp++ = '0' + base;
192 *tcp++ = '#';
193 i += 2; /* space to hold e.g. '6#' */
194 }
195
196 /*
197 ** the following code looks if we need a 'L' attached to the number
198 ** it will also attach an 'L' to the value -0x80000000
199 */
200 taglong = 0;
201 if (mpz_size(&mpzp->mpz) > 1
202 || (long)mpz_get_ui(&mpzp->mpz) < 0L) {
203 taglong = 1;
204 i += 1; /* space to hold 'L' */
205 }
206
207#ifdef MPZ_DEBUG
208 fprintf(stderr, "mpz_format: requesting string size %d\n", i);
209#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000210 if ((strobjp =
211 (PyStringObject *)PyString_FromStringAndSize((char *)0, i))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000212 == NULL)
213 return NULL;
214
215 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000216 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000217 if (withname) {
218 strcpy(cp, initialiser_name);
219 cp += strlen(initialiser_name);
220 *cp++ = '('; /*')'*/
221 }
222
223 /* copy the already prepared prefix; e.g. sign and base indicator */
224 *tcp = '\0';
225 strcpy(cp, prefix);
226 cp += tcp - prefix;
227
228 /* since' we have the sign already, let the lib think it's a positive
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000229 number */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000230 if (cmpres < 0)
231 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
232 (void)mpz_get_str(cp, base, &mpzp->mpz);
233 if (cmpres < 0)
234 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
235#ifdef MPZ_DEBUG
236 fprintf(stderr, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
237 base, cp);
238#endif /* def MPZ_DEBUG */
239 cp += strlen(cp);
240
241 if (taglong)
242 *cp++ = 'L';
243 if (withname)
244 *cp++ = /*'('*/ ')';
245
246 *cp = '\0';
247
248#ifdef MPZ_DEBUG
249 fprintf(stderr,
Fred Drakea44d3532000-06-30 15:01:00 +0000250 "mpz_format: cp (str end) %p, begin %p, diff %d, i %d\n",
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000251 cp, PyString_AS_STRING(strobjp),
252 cp - PyString_AS_STRING(strobjp), i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000253#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000254 assert(cp - PyString_AS_STRING(strobjp) <= i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000255
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000256 if (cp - PyString_AS_STRING(strobjp) != i) {
257 strobjp->ob_size -= i - (cp - PyString_AS_STRING(strobjp));
Guido van Rossum5f59d601992-12-14 16:59:51 +0000258 }
259
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000260 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000261} /* mpz_format() */
262
263/* MPZ methods */
264
265static void
266mpz_dealloc(mpzp)
267 mpzobject *mpzp;
268{
269#ifdef MPZ_DEBUG
270 fputs( "mpz_dealloc() called...\n", stderr );
271#endif /* def MPZ_DEBUG */
272 mpz_clear(&mpzp->mpz);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000273 PyObject_Del(mpzp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000274} /* mpz_dealloc() */
275
Guido van Rossum5f59d601992-12-14 16:59:51 +0000276
277/* pointers to frequently used values 0, 1 and -1 */
278static mpzobject *mpz_value_zero, *mpz_value_one, *mpz_value_mone;
279
280static int
281mpz_compare(a, b)
282 mpzobject *a, *b;
283{
284 int cmpres;
285
286
287 /* guido sez it's better to return -1, 0 or 1 */
288 return (cmpres = mpz_cmp( &a->mpz, &b->mpz )) == 0 ? 0
289 : cmpres > 0 ? 1 : -1;
290} /* mpz_compare() */
291
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000292static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000293mpz_addition(a, b)
294 mpzobject *a;
295 mpzobject *b;
296{
297 mpzobject *z;
298
299
300#ifdef MPZ_SPARE_MALLOC
301 if (mpz_cmp_ui(&a->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000302 Py_INCREF(b);
303 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000304 }
305
306 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000307 Py_INCREF(a);
308 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000309 }
310#endif /* def MPZ_SPARE_MALLOC */
311
312 if ((z = newmpzobject()) == NULL)
313 return NULL;
314
315 mpz_add(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000316 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000317} /* mpz_addition() */
318
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000319static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000320mpz_substract(a, b)
321 mpzobject *a;
322 mpzobject *b;
323{
324 mpzobject *z;
325
326
327#ifdef MPZ_SPARE_MALLOC
328 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000329 Py_INCREF(a);
330 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000331 }
332#endif /* MPZ_SPARE_MALLOC */
333
334 if ((z = newmpzobject()) == NULL)
335 return NULL;
336
337 mpz_sub(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000338 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000339} /* mpz_substract() */
340
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000341static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000342mpz_multiply(a, b)
343 mpzobject *a;
344 mpzobject *b;
345{
346#ifdef MPZ_SPARE_MALLOC
347 int cmpres;
348#endif /* def MPZ_SPARE_MALLOC */
349 mpzobject *z;
350
351
352#ifdef MPZ_SPARE_MALLOC
353 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000354 Py_INCREF(mpz_value_zero);
355 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000356 }
357 if (cmpres > 0 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000358 Py_INCREF(b);
359 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000360 }
361
362 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long_int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000363 Py_INCREF(mpz_value_zero);
364 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000365 }
366 if (cmpres > 0 && mpz_cmp_ui(&b->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000367 Py_INCREF(a);
368 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000369 }
370#endif /* MPZ_SPARE_MALLOC */
371
372 if ((z = newmpzobject()) == NULL)
373 return NULL;
374
375 mpz_mul( &z->mpz, &a->mpz, &b->mpz );
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000376 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000377
378} /* mpz_multiply() */
379
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000380static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000381mpz_divide(a, b)
382 mpzobject *a;
383 mpzobject *b;
384{
385#ifdef MPZ_SPARE_MALLOC
386 int cmpres;
387#endif /* def MPZ_SPARE_MALLOC */
388 mpzobject *z;
389
390
391 if ((
392#ifdef MPZ_SPARE_MALLOC
393 cmpres =
394#endif /* def MPZ_SPARE_MALLOC */
395 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000396 PyErr_SetString(PyExc_ZeroDivisionError, "mpz./ by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000397 return NULL;
398 }
399#ifdef MPZ_SPARE_MALLOC
400 if (cmpres > 0 && mpz_cmp_ui(&b->mpz(unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000401 Py_INCREF(a);
402 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000403 }
404#endif /* def MPZ_SPARE_MALLOC */
405
406 if ((z = newmpzobject()) == NULL)
407 return NULL;
408
409#ifdef MPZ_TEST_DIV
410 fputs("mpz_divide: div result", stderr);
411 mpz_div(&z->mpz, &a->mpz, &b->mpz);
412 mpz_out_str(stderr, 10, &z->mpz);
413 putc('\n', stderr);
414#endif /* def MPZ_TEST_DIV */
415#ifdef MPZ_MDIV_BUG
416 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
417 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)) {
418 /*
419 ** numerator has other sign than denominator: we have
420 ** to look at the remainder for a correction, since mpz_mdiv
421 ** also calls mpz_divmod, I can as well do it myself
422 */
423 MP_INT tmpmpz;
424
425
426 mpz_init(&tmpmpz);
427 mpz_divmod(&z->mpz, &tmpmpz, &a->mpz, &b->mpz);
428
429 if (mpz_cmp_ui(&tmpmpz, (unsigned long int)0) != 0)
430 mpz_sub_ui(&z->mpz, &z->mpz, (unsigned long int)1);
431
432 mpz_clear(&tmpmpz);
433 }
434 else
435 mpz_div(&z->mpz, &a->mpz, &b->mpz);
436 /* the ``naive'' implementation does it right for operands
437 having the same sign */
438
439#else /* def MPZ_MDIV_BUG */
440 mpz_mdiv(&z->mpz, &a->mpz, &b->mpz);
441#endif /* def MPZ_MDIV_BUG else */
442#ifdef MPZ_TEST_DIV
443 fputs("mpz_divide: mdiv result", stderr);
444 mpz_out_str(stderr, 10, &z->mpz);
445 putc('\n', stderr);
446#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000447 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000448
449} /* mpz_divide() */
450
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000451static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000452mpz_remainder(a, b)
453 mpzobject *a;
454 mpzobject *b;
455{
456#ifdef MPZ_SPARE_MALLOC
457 int cmpres;
458#endif /* def MPZ_SPARE_MALLOC */
459 mpzobject *z;
460
461
462 if ((
463#ifdef MPZ_SPARE_MALLOC
464 cmpres =
465#endif /* def MPZ_SPARE_MALLOC */
466 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000467 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.% by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000468 return NULL;
469 }
470#ifdef MPZ_SPARE_MALLOC
471 if (cmpres > 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000472 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)2)) == 0)
473 {
474 Py_INCREF(mpz_value_one);
475 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000476 }
477 if (cmpres < 0) {
478 /* b must be 1 now */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000479 Py_INCREF(mpz_value_zero);
480 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000481 }
482 }
483#endif /* def MPZ_SPARE_MALLOC */
484
485 if ((z = newmpzobject()) == NULL)
486 return NULL;
487
488#ifdef MPZ_TEST_DIV
489 fputs("mpz_remain: mod result", stderr);
490 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
491 mpz_out_str(stderr, 10, &z->mpz);
492 putc('\n', stderr);
493#endif /* def MPZ_TEST_DIV */
494#ifdef MPZ_MDIV_BUG
495
496 /* the ``naive'' implementation does it right for operands
497 having the same sign */
498 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
499
500 /* assumption: z, a and b all point to different locations */
501 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
502 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
503 && mpz_cmp_ui(&z->mpz, (unsigned long int)0) != 0)
504 mpz_add(&z->mpz, &z->mpz, &b->mpz);
505 /*
506 ** numerator has other sign than denominator: we have
507 ** to look at the remainder for a correction, since mpz_mdiv
508 ** also calls mpz_divmod, I can as well do it myself
509 */
510#else /* def MPZ_MDIV_BUG */
511 mpz_mmod(&z->mpz, &a->mpz, &b->mpz);
512#endif /* def MPZ_MDIV_BUG else */
513#ifdef MPZ_TEST_DIV
514 fputs("mpz_remain: mmod result", stderr);
515 mpz_out_str(stderr, 10, &z->mpz);
516 putc('\n', stderr);
517#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000518 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000519
520} /* mpz_remainder() */
521
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000522static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000523mpz_div_and_mod(a, b)
524 mpzobject *a;
525 mpzobject *b;
526{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000527 PyObject *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000528 mpzobject *x = NULL, *y = NULL;
529
530
531 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000532 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.divmod by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000533 return NULL;
534 }
535
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000536 if ((z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +0000537 || (x = newmpzobject()) == NULL
538 || (y = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000539 Py_XDECREF(z);
540 Py_XDECREF(x);
541 Py_XDECREF(y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000542 return NULL;
543 }
544
545#ifdef MPZ_TEST_DIV
546 fputs("mpz_divmod: dm result", stderr);
547 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
548 mpz_out_str(stderr, 10, &x->mpz);
549 putc('\n', stderr);
550 mpz_out_str(stderr, 10, &y->mpz);
551 putc('\n', stderr);
552#endif /* def MPZ_TEST_DIV */
553#ifdef MPZ_MDIV_BUG
554 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
555 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
556 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
557 && mpz_cmp_ui(&y->mpz, (unsigned long int)0) != 0) {
558 /*
559 ** numerator has other sign than denominator: we have
560 ** to look at the remainder for a correction.
561 */
562 mpz_add(&y->mpz, &y->mpz, &b->mpz);
563 mpz_sub_ui(&x->mpz, &x->mpz, (unsigned long int)1);
564 }
565#else /* def MPZ_MDIV_BUG */
566 mpz_mdivmod( &x->mpz, &y->mpz, &a->mpz, &b->mpz );
567#endif /* def MPZ_MDIV_BUG else */
568#ifdef MPZ_TEST_DIV
569 fputs("mpz_divmod: mdm result", stderr);
570 mpz_out_str(stderr, 10, &x->mpz);
571 putc('\n', stderr);
572 mpz_out_str(stderr, 10, &y->mpz);
573 putc('\n', stderr);
574#endif /* def MPZ_TEST_DIV */
575
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000576 (void)PyTuple_SetItem(z, 0, (PyObject *)x);
577 (void)PyTuple_SetItem(z, 1, (PyObject *)y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000578
579 return z;
580} /* mpz_div_and_mod() */
581
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000582static PyObject *
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000583mpz_power(a, b, m)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000584 mpzobject *a;
585 mpzobject *b;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000586 mpzobject *m;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000587{
588 mpzobject *z;
589 int cmpres;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000590
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000591 if ((PyObject *)m != Py_None) {
592 mpzobject *z2;
593 Py_INCREF(Py_None);
594 z=(mpzobject *)mpz_power(a, b, (mpzobject *)Py_None);
595 Py_DECREF(Py_None);
596 if (z==NULL) return((PyObject *)z);
597 z2=(mpzobject *)mpz_remainder(z, m);
598 Py_DECREF(z);
599 return((PyObject *)z2);
600 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000601
602 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
603 /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
604
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000605 Py_INCREF(mpz_value_one);
606 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000607 }
608
609 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000610 PyErr_SetString(PyExc_ValueError,
611 "mpz.pow to negative exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000612 return NULL;
613 }
614
615 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
616 /* the base is 0 */
617
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000618 Py_INCREF(mpz_value_zero);
619 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000620 }
621 else if (cmpres > 0
622 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
623 /* the base is 1 */
624
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000625 Py_INCREF(mpz_value_one);
626 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000627 }
628 else if (cmpres < 0
629 && mpz_cmp_si(&a->mpz, (long int)-1) == 0) {
630
631 MP_INT tmpmpz;
632 /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
633 /* XXX this code needs to be optimized: what's better?
634 mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
635 for *un*obvious reasons */
636
637 /* is the exponent even? */
638 mpz_init(&tmpmpz);
639
640 /* look to the remainder after a division by (1 << 1) */
641 mpz_mod_2exp(&tmpmpz, &b->mpz, (unsigned long int)1);
642
643 if (mpz_cmp_ui(&tmpmpz, (unsigned int)0) == 0) {
644 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000645 Py_INCREF(mpz_value_one);
646 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000647 }
648 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000649 Py_INCREF(mpz_value_mone);
650 return (PyObject *)mpz_value_mone;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000651 }
652
653#ifdef MPZ_LIB_DOES_CHECKING
654 /* check if it's doable: sizeof(exp) > sizeof(long) &&
655 abs(base) > 1 ?? --> No Way */
656 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000657 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000658#else /* def MPZ_LIB_DOES_CHECKING */
659 /* wet finger method */
660 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000661 PyErr_SetString(PyExc_ValueError,
662 "mpz.pow outrageous exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000663 return NULL;
664 }
665#endif /* def MPZ_LIB_DOES_CHECKING else */
666
667 if ((z = newmpzobject()) == NULL)
668 return NULL;
669
670 mpz_pow_ui(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
671
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000672 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000673} /* mpz_power() */
674
675
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000676static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000677mpz_negative(v)
678 mpzobject *v;
679{
680 mpzobject *z;
681
682
683#ifdef MPZ_SPARE_MALLOC
684 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) == 0) {
685 /* -0 == 0 */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000686 Py_INCREF(v);
687 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000688 }
689#endif /* def MPZ_SPARE_MALLOC */
690
691 if ((z = newmpzobject()) == NULL)
692 return NULL;
693
694 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000695 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000696} /* mpz_negative() */
697
698
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000699static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000700mpz_positive(v)
701 mpzobject *v;
702{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000703 Py_INCREF(v);
704 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000705} /* mpz_positive() */
706
707
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000708static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000709mpz_absolute(v)
710 mpzobject *v;
711{
712 mpzobject *z;
713
714
715 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000716 Py_INCREF(v);
717 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000718 }
719
720 if ((z = newmpzobject()) == NULL)
721 return NULL;
722
723 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000724 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000725} /* mpz_absolute() */
726
727static int
728mpz_nonzero(v)
729 mpzobject *v;
730{
731 return mpz_cmp_ui(&v->mpz, (unsigned long int)0) != 0;
732} /* mpz_nonzero() */
733
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000734static PyObject *
Guido van Rossum272841c1996-08-19 23:06:45 +0000735py_mpz_invert(v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000736 mpzobject *v;
737{
738 mpzobject *z;
739
740
741 /* I think mpz_com does exactly what needed */
742 if ((z = newmpzobject()) == NULL)
743 return NULL;
744
745 mpz_com(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000746 return (PyObject *)z;
Guido van Rossum272841c1996-08-19 23:06:45 +0000747} /* py_mpz_invert() */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000748
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000749static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000750mpz_lshift(a, b)
751 mpzobject *a;
752 mpzobject *b;
753{
754 int cmpres;
755 mpzobject *z;
756
757
758 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
759 /* a << 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000760 Py_INCREF(a);
761 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000762 }
763
764 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000765 PyErr_SetString(PyExc_ValueError,
766 "mpz.<< negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000767 return NULL;
768 }
769
770#ifdef MPZ_LIB_DOES_CHECKING
771 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000772 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000773#else /* def MPZ_LIB_DOES_CHECKING */
774 /* wet finger method */
775 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000776 PyErr_SetString(PyExc_ValueError,
777 "mpz.<< outrageous shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000778 return NULL;
779 }
780#endif /* def MPZ_LIB_DOES_CHECKING else */
781
782 if ((z = newmpzobject()) == NULL)
783 return NULL;
784
785 mpz_mul_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000786 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000787} /* mpz_lshift() */
788
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000789static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000790mpz_rshift(a, b)
791 mpzobject *a;
792 mpzobject *b;
793{
794 int cmpres;
795 mpzobject *z;
796
797
798 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
799 /* a >> 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000800 Py_INCREF(a);
801 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000802 }
803
804 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000805 PyErr_SetString(PyExc_ValueError,
806 "mpz.>> negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000807 return NULL;
808 }
809
810 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000811 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000812
813 if ((z = newmpzobject()) == NULL)
814 return NULL;
815
816 mpz_div_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000817 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000818} /* mpz_rshift() */
819
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000820static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000821mpz_andfunc(a, b)
822 mpzobject *a;
823 mpzobject *b;
824{
825 mpzobject *z;
826
827
828 if ((z = newmpzobject()) == NULL)
829 return NULL;
830
831 mpz_and(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000832 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000833} /* mpz_andfunc() */
834
835/* hack Hack HAck HACk HACK, XXX this code is dead slow */
836void
837mpz_xor(res, op1, op2)
838 MP_INT *res;
839 const MP_INT *op1;
840 const MP_INT *op2;
841{
842 MP_INT tmpmpz;
843
844 mpz_init(&tmpmpz);
845
846 mpz_and(res, op1, op2);
847 mpz_com(&tmpmpz, res);
848 mpz_ior(res, op1, op2);
849 mpz_and(res, res, &tmpmpz);
850
851 mpz_clear(&tmpmpz);
852} /* mpz_xor() HACK */
853
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000854static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000855mpz_xorfunc(a, b)
856 mpzobject *a;
857 mpzobject *b;
858{
859 mpzobject *z;
860
861
862 if ((z = newmpzobject()) == NULL)
863 return NULL;
864
865 mpz_xor(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000866 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000867} /* mpz_xorfunc() */
868
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000869static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000870mpz_orfunc(a, b)
871 mpzobject *a;
872 mpzobject *b;
873{
874 mpzobject *z;
875
876
877 if ((z = newmpzobject()) == NULL)
878 return NULL;
879
880 mpz_ior(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000881 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000882} /* mpz_orfunc() */
883
884/* MPZ initialisation */
885
886#include "longintrepr.h"
887
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000888static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000889MPZ_mpz(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000890 PyObject *self;
891 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000892{
893 mpzobject *mpzp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000894 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000895
896
897#ifdef MPZ_DEBUG
898 fputs("MPZ_mpz() called...\n", stderr);
899#endif /* def MPZ_DEBUG */
900
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000901 if (!PyArg_Parse(args, "O", &objp))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000902 return NULL;
903
904 /* at least we know it's some object */
Barry Warsawabb7efe1996-12-09 23:22:35 +0000905 /* note DON't Py_DECREF args NEITHER objp */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000906
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000907 if (PyInt_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000908 long lval;
909
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000910 if (!PyArg_Parse(objp, "l", &lval))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000911 return NULL;
912
913 if (lval == (long)0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000914 Py_INCREF(mpz_value_zero);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000915 mpzp = mpz_value_zero;
916 }
917 else if (lval == (long)1) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000918 Py_INCREF(mpz_value_one);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000919 mpzp = mpz_value_one;
920 }
921 else if ((mpzp = newmpzobject()) == NULL)
922 return NULL;
923 else mpz_set_si(&mpzp->mpz, lval);
924 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000925 else if (PyLong_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000926 MP_INT mplongdigit;
927 int i;
928 unsigned char isnegative;
929
930
931 if ((mpzp = newmpzobject()) == NULL)
932 return NULL;
933
934 mpz_set_si(&mpzp->mpz, 0L);
935 mpz_init(&mplongdigit);
936
937 /* how we're gonna handle this? */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000938 if ((isnegative =
939 ((i = ((PyLongObject *)objp)->ob_size) < 0) ))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000940 i = -i;
941
942 while (i--) {
943 mpz_set_ui(&mplongdigit,
944 (unsigned long)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000945 ((PyLongObject *)objp)->ob_digit[i]);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000946 mpz_mul_2exp(&mplongdigit,&mplongdigit,
947 (unsigned long int)i * SHIFT);
948 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
949 }
950
951 if (isnegative)
952 mpz_neg(&mpzp->mpz, &mpzp->mpz);
953
954 /* get rid of allocation for tmp variable */
955 mpz_clear(&mplongdigit);
956 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000957 else if (PyString_Check(objp)) {
Andrew M. Kuchling4c07f811998-12-14 19:36:14 +0000958 unsigned char *cp = (unsigned char *)PyString_AS_STRING(objp);
Guido van Rossum7e488981998-10-08 02:25:24 +0000959 int len = PyString_GET_SIZE(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000960 MP_INT mplongdigit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000961
962 if ((mpzp = newmpzobject()) == NULL)
963 return NULL;
964
965 mpz_set_si(&mpzp->mpz, 0L);
966 mpz_init(&mplongdigit);
967
968 /* let's do it the same way as with the long conversion:
969 without thinking how it can be faster (-: :-) */
970
971 cp += len;
972 while (len--) {
973 mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
974 mpz_mul_2exp(&mplongdigit,&mplongdigit,
975 (unsigned long int)len * 8);
976 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
977 }
978
979 /* get rid of allocation for tmp variable */
980 mpz_clear(&mplongdigit);
981 }
982 else if (is_mpzobject(objp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000983 Py_INCREF(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000984 mpzp = (mpzobject *)objp;
985 }
986 else {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000987 PyErr_SetString(PyExc_TypeError,
988"mpz.mpz() expects integer, long, string or mpz object argument");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000989 return NULL;
990 }
991
992
993#ifdef MPZ_DEBUG
994 fputs("MPZ_mpz: created mpz=", stderr);
995 mpz_out_str(stderr, 10, &mpzp->mpz);
996 putc('\n', stderr);
997#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000998 return (PyObject *)mpzp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000999} /* MPZ_mpz() */
1000
1001static mpzobject *
1002mpz_mpzcoerce(z)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001003 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001004{
1005 /* shortcut: 9 out of 10 times the type is already ok */
1006 if (is_mpzobject(z)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001007 Py_INCREF(z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001008 return (mpzobject *)z; /* coercion succeeded */
1009 }
1010
1011 /* what types do we accept?: intobjects and longobjects */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001012 if (PyInt_Check(z) || PyLong_Check(z))
1013 return (mpzobject *)MPZ_mpz((PyObject *)NULL, z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001014
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001015 PyErr_SetString(PyExc_TypeError,
1016 "number coercion (to mpzobject) failed");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001017 return NULL;
1018} /* mpz_mpzcoerce() */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001019
1020/* Forward */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001021static void mpz_divm Py_PROTO((MP_INT *res, const MP_INT *num,
1022 const MP_INT *den, const MP_INT *mod));
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001023
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001024static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001025MPZ_powm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001026 PyObject *self;
1027 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001028{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001029 PyObject *base, *exp, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001030 mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
1031 mpzobject *z;
1032 int tstres;
1033
1034
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001035 if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001036 return NULL;
1037
1038 if ((mpzbase = mpz_mpzcoerce(base)) == NULL
1039 || (mpzexp = mpz_mpzcoerce(exp)) == NULL
1040 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1041 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001042 Py_XDECREF(mpzbase);
1043 Py_XDECREF(mpzexp);
1044 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001045 return NULL;
1046 }
1047
1048 if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001049 Py_INCREF(mpz_value_one);
1050 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001051 }
1052
1053 if (tstres < 0) {
1054 MP_INT absexp;
1055 /* negative exp */
1056
1057 mpz_init_set(&absexp, &mpzexp->mpz);
1058 mpz_abs(&absexp, &absexp);
1059 mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
1060
1061 mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
1062
1063 mpz_clear(&absexp);
1064 }
1065 else {
1066 mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
1067 }
1068
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001069 Py_DECREF(mpzbase);
1070 Py_DECREF(mpzexp);
1071 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001072
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001073 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001074} /* MPZ_powm() */
1075
1076
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001077static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001078MPZ_gcd(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001079 PyObject *self;
1080 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001081{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001082 PyObject *op1, *op2;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001083 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1084 mpzobject *z;
1085
1086
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001087 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001088 return NULL;
1089
1090 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1091 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
1092 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001093 Py_XDECREF(mpzop1);
1094 Py_XDECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001095 return NULL;
1096 }
1097
1098 /* ok, we have three mpzobjects, and an initialised result holder */
1099 mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
1100
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001101 Py_DECREF(mpzop1);
1102 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001103
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001104 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001105} /* MPZ_gcd() */
1106
1107
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001108static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001109MPZ_gcdext(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001110 PyObject *self;
1111 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001112{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001113 PyObject *op1, *op2, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001114 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1115 mpzobject *g = NULL, *s = NULL, *t = NULL;
1116
1117
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001118 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001119 return NULL;
1120
1121 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1122 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001123 || (z = PyTuple_New(3)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001124 || (g = newmpzobject()) == NULL
1125 || (s = newmpzobject()) == NULL
1126 || (t = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001127 Py_XDECREF(mpzop1);
1128 Py_XDECREF(mpzop2);
1129 Py_XDECREF(z);
1130 Py_XDECREF(g);
1131 Py_XDECREF(s);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001132 /*Py_XDECREF(t);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001133 return NULL;
1134 }
1135
1136 mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
1137
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001138 Py_DECREF(mpzop1);
1139 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001140
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001141 (void)PyTuple_SetItem(z, 0, (PyObject *)g);
1142 (void)PyTuple_SetItem(z, 1, (PyObject *)s);
1143 (void)PyTuple_SetItem(z, 2, (PyObject *)t);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001144
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001145 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001146} /* MPZ_gcdext() */
1147
1148
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001149static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001150MPZ_sqrt(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001151 PyObject *self;
1152 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001153{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001154 PyObject *op;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001155 mpzobject *mpzop = NULL;
1156 mpzobject *z;
1157
1158
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001159 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001160 return NULL;
1161
1162 if ((mpzop = mpz_mpzcoerce(op)) == NULL
1163 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001164 Py_XDECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001165 return NULL;
1166 }
1167
1168 mpz_sqrt(&z->mpz, &mpzop->mpz);
1169
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001170 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001171
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001172 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001173} /* MPZ_sqrt() */
1174
1175
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001176static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001177MPZ_sqrtrem(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001178 PyObject *self;
1179 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001180{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001181 PyObject *op, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001182 mpzobject *mpzop = NULL;
1183 mpzobject *root = NULL, *rem = NULL;
1184
1185
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001186 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001187 return NULL;
1188
1189 if ((mpzop = mpz_mpzcoerce(op)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001190 || (z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001191 || (root = newmpzobject()) == NULL
1192 || (rem = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001193 Py_XDECREF(mpzop);
1194 Py_XDECREF(z);
1195 Py_XDECREF(root);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001196 /*Py_XDECREF(rem);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001197 return NULL;
1198 }
1199
1200 mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
1201
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001202 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001203
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001204 (void)PyTuple_SetItem(z, 0, (PyObject *)root);
1205 (void)PyTuple_SetItem(z, 1, (PyObject *)rem);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001206
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001207 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001208} /* MPZ_sqrtrem() */
1209
1210
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001211static void
Guido van Rossum5f59d601992-12-14 16:59:51 +00001212#if __STDC__
1213mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
1214#else
1215mpz_divm(res, num, den, mod)
1216 MP_INT *res;
1217 const MP_INT *num;
1218 const MP_INT *den;
1219 const MP_INT *mod;
1220#endif
1221{
1222 MP_INT s0, s1, q, r, x, d0, d1;
1223
1224 mpz_init_set(&s0, num);
1225 mpz_init_set_ui(&s1, 0);
1226 mpz_init(&q);
1227 mpz_init(&r);
1228 mpz_init(&x);
1229 mpz_init_set(&d0, den);
1230 mpz_init_set(&d1, mod);
1231
Guido van Rossum272841c1996-08-19 23:06:45 +00001232#ifdef GMP2
1233 while (d1._mp_size != 0) {
1234#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001235 while (d1.size != 0) {
Guido van Rossum272841c1996-08-19 23:06:45 +00001236#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001237 mpz_divmod(&q, &r, &d0, &d1);
1238 mpz_set(&d0, &d1);
1239 mpz_set(&d1, &r);
1240
1241 mpz_mul(&x, &s1, &q);
1242 mpz_sub(&x, &s0, &x);
1243 mpz_set(&s0, &s1);
1244 mpz_set(&s1, &x);
1245 }
1246
Guido van Rossum272841c1996-08-19 23:06:45 +00001247#ifdef GMP2
1248 if (d0._mp_size != 1 || d0._mp_d[0] != 1)
1249 res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
1250#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001251 if (d0.size != 1 || d0.d[0] != 1)
1252 res->size = 0; /* trouble: the gcd != 1; set s to zero */
Guido van Rossum272841c1996-08-19 23:06:45 +00001253#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001254 else {
1255#ifdef MPZ_MDIV_BUG
1256 /* watch out here! first check the signs, and then perform
1257 the mpz_mod() since mod could point to res */
1258 if ((s0.size < 0) != (mod->size < 0)) {
1259 mpz_mod(res, &s0, mod);
1260
1261 if (res->size)
1262 mpz_add(res, res, mod);
1263 }
1264 else
1265 mpz_mod(res, &s0, mod);
1266
1267#else /* def MPZ_MDIV_BUG */
1268 mpz_mmod(res, &s0, mod);
1269#endif /* def MPZ_MDIV_BUG else */
1270 }
1271
1272 mpz_clear(&s0);
1273 mpz_clear(&s1);
1274 mpz_clear(&q);
1275 mpz_clear(&r);
1276 mpz_clear(&x);
1277 mpz_clear(&d0);
1278 mpz_clear(&d1);
1279} /* mpz_divm() */
1280
1281
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001282static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001283MPZ_divm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001284 PyObject *self;
1285 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001286{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001287 PyObject *num, *den, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001288 mpzobject *mpznum, *mpzden, *mpzmod = NULL;
1289 mpzobject *z = NULL;
1290
1291
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001292 if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001293 return NULL;
1294
1295 if ((mpznum = mpz_mpzcoerce(num)) == NULL
1296 || (mpzden = mpz_mpzcoerce(den)) == NULL
1297 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1298 || (z = newmpzobject()) == NULL ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001299 Py_XDECREF(mpznum);
1300 Py_XDECREF(mpzden);
1301 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001302 return NULL;
1303 }
1304
1305 mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
1306
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001307 Py_DECREF(mpznum);
1308 Py_DECREF(mpzden);
1309 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001310
1311 if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001312 Py_DECREF(z);
1313 PyErr_SetString(PyExc_ValueError,
1314 "gcd(den, mod) != 1 or num == 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001315 return NULL;
1316 }
1317
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001318 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001319} /* MPZ_divm() */
1320
1321
1322/* MPZ methods-as-attributes */
1323#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001324static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001325mpz_int(self, args)
1326 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001327 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001328#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001329static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001330mpz_int(self)
1331 mpzobject *self;
1332#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1333{
1334 long sli;
1335
1336
1337#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001338 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001339 return NULL;
1340#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1341
1342 if (mpz_size(&self->mpz) > 1
1343 || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001344 PyErr_SetString(PyExc_ValueError,
1345 "mpz.int() arg too long to convert");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001346 return NULL;
1347 }
1348
1349 if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
1350 sli = -sli;
1351
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001352 return PyInt_FromLong(sli);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001353} /* mpz_int() */
1354
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001355static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001356#ifdef MPZ_CONVERSIONS_AS_METHODS
1357mpz_long(self, args)
1358 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001359 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001360#else /* def MPZ_CONVERSIONS_AS_METHODS */
1361mpz_long(self)
1362 mpzobject *self;
1363#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1364{
1365 int i, isnegative;
1366 unsigned long int uli;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001367 PyLongObject *longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001368 int ldcount;
1369 int bitpointer, newbitpointer;
1370 MP_INT mpzscratch;
1371
1372
1373#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001374 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001375 return NULL;
1376#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1377
1378 /* determine length of python-long to be allocated */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001379 if ((longobjp = _PyLong_New(i = (int)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001380 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
1381 + SHIFT - 1) /
1382 SHIFT))) == NULL)
1383 return NULL;
1384
1385 /* determine sign, and copy self to scratch var */
1386 mpz_init_set(&mpzscratch, &self->mpz);
Guido van Rossum272841c1996-08-19 23:06:45 +00001387 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001388 mpz_neg(&mpzscratch, &mpzscratch);
1389
1390 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001391 e.g. dismantle mpzscratch, build PyLongObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001392
1393 bitpointer = 0; /* the number of valid bits in stock */
1394 newbitpointer = 0;
1395 ldcount = 0; /* the python-long limb counter */
1396 uli = (unsigned long int)0;
1397 while (i--) {
1398 longobjp->ob_digit[ldcount] = uli & MASK;
1399
1400 /* check if we've had enough bits for this digit */
1401 if (bitpointer < SHIFT) {
1402 uli = mpz_get_ui(&mpzscratch);
1403 longobjp->ob_digit[ldcount] |=
1404 (uli << bitpointer) & MASK;
1405 uli >>= SHIFT-bitpointer;
1406 bitpointer += BITS_PER_MP_LIMB;
1407 mpz_div_2exp(&mpzscratch, &mpzscratch,
1408 BITS_PER_MP_LIMB);
1409 }
1410 else
1411 uli >>= SHIFT;
1412 bitpointer -= SHIFT;
1413 ldcount++;
1414 }
1415
1416 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1417 mpz_clear(&mpzscratch);
1418 assert(ldcount <= longobjp->ob_size);
1419
1420 /* long_normalize() is file-static */
1421 /* longobjp = long_normalize(longobjp); */
1422 while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
1423 ldcount--;
1424 longobjp->ob_size = ldcount;
1425
1426
1427 if (isnegative)
1428 longobjp->ob_size = -longobjp->ob_size;
1429
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001430 return (PyObject *)longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001431
1432} /* mpz_long() */
1433
1434
1435/* I would have avoided pow() anyways, so ... */
1436static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
1437
1438#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001439static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001440mpz_float(self, args)
1441 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001442 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001443#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001444static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001445mpz_float(self)
1446 mpzobject *self;
1447#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1448{
1449 int i, isnegative;
1450 double x;
1451 double mulstate;
1452 MP_INT mpzscratch;
1453
1454
1455#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001456 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001457 return NULL;
1458#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1459
1460 i = (int)mpz_size(&self->mpz);
1461
1462 /* determine sign, and copy abs(self) to scratch var */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001463 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
1464 {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001465 mpz_init(&mpzscratch);
1466 mpz_neg(&mpzscratch, &self->mpz);
1467 }
1468 else
1469 mpz_init_set(&mpzscratch, &self->mpz);
1470
1471 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001472 e.g. dismantle mpzscratch, build PyFloatObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001473
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001474 /* Can this overflow? Dunno, protect against that possibility. */
1475 PyFPE_START_PROTECT("mpz_float", return 0)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001476 x = 0.0;
1477 mulstate = 1.0;
1478 while (i--) {
1479 x += mulstate * mpz_get_ui(&mpzscratch);
1480 mulstate *= multiplier;
1481 mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
1482 }
Guido van Rossum45b83911997-03-14 04:32:50 +00001483 PyFPE_END_PROTECT(mulstate)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001484
1485 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1486 mpz_clear(&mpzscratch);
1487
1488 if (isnegative)
1489 x = -x;
1490
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001491 return PyFloat_FromDouble(x);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001492
1493} /* mpz_float() */
1494
1495#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001496static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001497mpz_hex(self, args)
1498 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001499 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001500#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001501static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001502mpz_hex(self)
1503 mpzobject *self;
1504#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1505{
1506#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001507 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001508 return NULL;
1509#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1510
1511 return mpz_format(self, 16, (unsigned char)1);
1512} /* mpz_hex() */
1513
1514#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001515static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001516mpz_oct(self, args)
1517 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001518 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001519#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001520static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001521mpz_oct(self)
1522 mpzobject *self;
1523#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1524{
1525#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001526 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001527 return NULL;
1528#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1529
1530 return mpz_format(self, 8, (unsigned char)1);
1531} /* mpz_oct() */
1532
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001533static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001534mpz_binary(self, args)
1535 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001536 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001537{
1538 int size;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001539 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001540 char *cp;
1541 MP_INT mp;
1542 unsigned long ldigit;
1543
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001544 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001545 return NULL;
1546
1547 if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001548 PyErr_SetString(PyExc_ValueError,
1549 "mpz.binary() arg must be >= 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001550 return NULL;
1551 }
1552
1553 mpz_init_set(&mp, &self->mpz);
1554 size = (int)mpz_size(&mp);
1555
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001556 if ((strobjp = (PyStringObject *)
1557 PyString_FromStringAndSize(
1558 (char *)0, size * sizeof (unsigned long int))) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001559 return NULL;
1560
1561 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001562 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001563
1564 /* this has been programmed using a (fairly) decent lib-i/f it could
1565 be must faster if we looked into the GMP lib */
1566 while (size--) {
1567 ldigit = mpz_get_ui(&mp);
1568 mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
1569 *cp++ = (unsigned char)(ldigit & 0xFF);
1570 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1571 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1572 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1573 }
1574
1575 while (strobjp->ob_size && !*--cp)
1576 strobjp->ob_size--;
1577
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001578 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001579} /* mpz_binary() */
1580
1581
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001582static PyMethodDef mpz_methods[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001583#ifdef MPZ_CONVERSIONS_AS_METHODS
1584 {"int", mpz_int},
1585 {"long", mpz_long},
1586 {"float", mpz_float},
1587 {"hex", mpz_hex},
1588 {"oct", mpz_oct},
1589#endif /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001590 {"binary", (PyCFunction)mpz_binary},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001591 {NULL, NULL} /* sentinel */
1592};
1593
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001594static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001595mpz_getattr(self, name)
1596 mpzobject *self;
1597 char *name;
1598{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001599 return Py_FindMethod(mpz_methods, (PyObject *)self, name);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001600} /* mpz_getattr() */
1601
1602
1603static int
1604mpz_coerce(pv, pw)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001605 PyObject **pv;
1606 PyObject **pw;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001607{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001608 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001609
1610#ifdef MPZ_DEBUG
1611 fputs("mpz_coerce() called...\n", stderr);
1612#endif /* def MPZ_DEBUG */
1613
1614 assert(is_mpzobject(*pv));
1615
1616 /* always convert other arg to mpz value, except for floats */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001617 if (!PyFloat_Check(*pw)) {
1618 if ((z = (PyObject *)mpz_mpzcoerce(*pw)) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001619 return -1; /* -1: an error always has been set */
1620
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001621 Py_INCREF(*pv);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001622 *pw = z;
1623 }
1624 else {
1625 if ((z = mpz_float(*pv, NULL)) == NULL)
1626 return -1;
1627
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001628 Py_INCREF(*pw);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001629 *pv = z;
1630 }
1631 return 0; /* coercion succeeded */
1632
1633} /* mpz_coerce() */
1634
1635
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001636static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001637mpz_repr(v)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001638 PyObject *v;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001639{
1640 return mpz_format(v, 10, (unsigned char)1);
1641} /* mpz_repr() */
1642
1643
1644
Guido van Rossumb6775db1994-08-01 11:34:53 +00001645#define UF (unaryfunc)
1646#define BF (binaryfunc)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001647#define TF (ternaryfunc)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001648#define IF (inquiry)
1649#define CF (coercion)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001650
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001651static PyNumberMethods mpz_as_number = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001652 BF mpz_addition, /*nb_add*/
1653 BF mpz_substract, /*nb_subtract*/
1654 BF mpz_multiply, /*nb_multiply*/
1655 BF mpz_divide, /*nb_divide*/
1656 BF mpz_remainder, /*nb_remainder*/
1657 BF mpz_div_and_mod, /*nb_divmod*/
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001658 TF mpz_power, /*nb_power*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001659 UF mpz_negative, /*nb_negative*/
1660 UF mpz_positive, /*tp_positive*/
1661 UF mpz_absolute, /*tp_absolute*/
1662 IF mpz_nonzero, /*tp_nonzero*/
Guido van Rossum272841c1996-08-19 23:06:45 +00001663 UF py_mpz_invert, /*nb_invert*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001664 BF mpz_lshift, /*nb_lshift*/
1665 BF mpz_rshift, /*nb_rshift*/
1666 BF mpz_andfunc, /*nb_and*/
1667 BF mpz_xorfunc, /*nb_xor*/
1668 BF mpz_orfunc, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001669 CF mpz_coerce, /*nb_coerce*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001670#ifndef MPZ_CONVERSIONS_AS_METHODS
1671 UF mpz_int, /*nb_int*/
1672 UF mpz_long, /*nb_long*/
1673 UF mpz_float, /*nb_float*/
1674 UF mpz_oct, /*nb_oct*/
1675 UF mpz_hex, /*nb_hex*/
1676#endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1677};
1678
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001679static PyTypeObject MPZtype = {
1680 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001681 0, /*ob_size*/
1682 "mpz", /*tp_name*/
1683 sizeof(mpzobject), /*tp_size*/
1684 0, /*tp_itemsize*/
1685 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001686 (destructor)mpz_dealloc, /*tp_dealloc*/
1687 0, /*tp_print*/
1688 (getattrfunc)mpz_getattr, /*tp_getattr*/
1689 0, /*tp_setattr*/
1690 (cmpfunc)mpz_compare, /*tp_compare*/
1691 (reprfunc)mpz_repr, /*tp_repr*/
1692 &mpz_as_number, /*tp_as_number*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001693};
1694
1695/* List of functions exported by this module */
1696
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001697static PyMethodDef mpz_functions[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001698#if 0
1699 {initialiser_name, MPZ_mpz},
1700#else /* 0 */
Barry Warsawabb7efe1996-12-09 23:22:35 +00001701 /* until guido ``fixes'' struct PyMethodDef */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001702 {(char *)initialiser_name, MPZ_mpz},
1703#endif /* 0 else */
1704 {"powm", MPZ_powm},
1705 {"gcd", MPZ_gcd},
1706 {"gcdext", MPZ_gcdext},
1707 {"sqrt", MPZ_sqrt},
1708 {"sqrtrem", MPZ_sqrtrem},
1709 {"divm", MPZ_divm},
1710 {NULL, NULL} /* Sentinel */
1711};
1712
1713
1714/* #define MP_TEST_ALLOC */
1715
1716#ifdef MP_TEST_ALLOC
1717#define MP_TEST_SIZE 4
1718static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
1719static mp_test_error( location )
1720 int *location;
1721{
1722 /* assumptions: *alloc returns address dividable by 4,
1723 mpz_* routines allocate in chunks dividable by four */
1724 fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001725 Py_FatalError("MP_TEST_ERROR");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001726} /* static mp_test_error() */
1727#define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1728#define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1729#define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1730 ; \
1731 else \
1732 mp_test_error((int *)((char *)(basep) + size))
1733#else /* def MP_TEST_ALLOC */
1734#define MP_EXTRA_ALLOC(size) (size)
1735#define MP_SET_TEST(basep,size)
1736#define MP_DO_TEST(basep,size)
1737#endif /* def MP_TEST_ALLOC else */
1738
1739void *mp_allocate( alloc_size )
1740 size_t alloc_size;
1741{
1742 void *res;
1743
1744#ifdef MPZ_DEBUG
1745 fprintf(stderr, "mp_allocate : size %ld\n",
1746 alloc_size);
1747#endif /* def MPZ_DEBUG */
1748
1749 if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001750 Py_FatalError("mp_allocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001751
1752#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001753 fprintf(stderr, "mp_allocate : address %08p\n", res);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001754#endif /* def MPZ_DEBUG */
1755
1756 MP_SET_TEST(res,alloc_size);
1757
1758 return res;
1759} /* mp_allocate() */
1760
1761
1762void *mp_reallocate( ptr, old_size, new_size )
1763 void *ptr;
1764 size_t old_size;
1765 size_t new_size;
1766{
1767 void *res;
1768
1769#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001770 fprintf(stderr, "mp_reallocate: old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001771 ptr, old_size);
1772#endif /* def MPZ_DEBUG */
1773
1774 MP_DO_TEST(ptr, old_size);
1775
1776 if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001777 Py_FatalError("mp_reallocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001778
1779#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001780 fprintf(stderr, "mp_reallocate: new address %08p, new size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001781 res, new_size);
1782#endif /* def MPZ_DEBUG */
1783
1784 MP_SET_TEST(res, new_size);
1785
1786 return res;
1787} /* mp_reallocate() */
1788
1789
1790void mp_free( ptr, size )
1791 void *ptr;
1792 size_t size;
1793{
1794
1795#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001796 fprintf(stderr, "mp_free : old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001797 ptr, size);
1798#endif /* def MPZ_DEBUG */
1799
1800 MP_DO_TEST(ptr, size);
1801 free(ptr);
1802} /* mp_free() */
1803
1804
1805
1806/* Initialize this module. */
1807
Guido van Rossum3886bb61998-12-04 18:50:17 +00001808DL_EXPORT(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001809initmpz()
1810{
Fred Drakefcc6c681998-04-03 15:33:43 +00001811 PyObject *module;
1812 PyObject *dict;
1813
Guido van Rossum5f59d601992-12-14 16:59:51 +00001814#ifdef MPZ_DEBUG
1815 fputs( "initmpz() called...\n", stderr );
1816#endif /* def MPZ_DEBUG */
1817
1818 mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
Fred Drakefcc6c681998-04-03 15:33:43 +00001819 module = Py_InitModule("mpz", mpz_functions);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001820
1821 /* create some frequently used constants */
1822 if ((mpz_value_zero = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001823 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001824 mpz_set_ui(&mpz_value_zero->mpz, (unsigned long int)0);
1825
1826 if ((mpz_value_one = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001827 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001828 mpz_set_ui(&mpz_value_one->mpz, (unsigned long int)1);
1829
1830 if ((mpz_value_mone = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001831 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001832 mpz_set_si(&mpz_value_mone->mpz, (long)-1);
1833
Fred Drakefcc6c681998-04-03 15:33:43 +00001834 dict = PyModule_GetDict(module);
1835 if (dict != NULL) {
1836 PyDict_SetItemString(dict, "MPZType", (PyObject*)&MPZtype);
1837 }
1838
Guido van Rossum5f59d601992-12-14 16:59:51 +00001839} /* initmpz() */
1840#ifdef MAKEDUMMYINT
1841int _mpz_dummy_int; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1842#endif /* def MAKEDUMMYINT */