blob: 2d10df5bf53b2c4636907a25d667f927fa6a9581 [file] [log] [blame]
Guido van Rossum5f59d601992-12-14 16:59:51 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum5f59d601992-12-14 16:59:51 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum5f59d601992-12-14 16:59:51 +00009******************************************************************/
Guido van Rossumb6775db1994-08-01 11:34:53 +000010
Guido van Rossum5f59d601992-12-14 16:59:51 +000011/* MPZ module */
12
13/* This module provides an interface to an alternate Multi-Precision
14 library, GNU MP in this case */
15
16/* XXX note: everywhere where mpz_size is called,
17 sizeof (limb) == sizeof (long) has been assumed. */
18
19
20/* MPZ objects */
21
Barry Warsaw3bdf7461996-12-09 23:16:31 +000022#include "Python.h"
Guido van Rossuma597dde1995-01-10 20:56:29 +000023
Guido van Rossum5f59d601992-12-14 16:59:51 +000024#include <assert.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000025#include <sys/types.h> /* For size_t */
Guido van Rossum5f59d601992-12-14 16:59:51 +000026
27/*
28** These are the cpp-flags used in this file...
29**
30**
31** MPZ_MDIV_BUG works around the mpz_m{div,mod,...} routines.
32** This bug has been fixed in a later release of
33** GMP.
34**
35** MPZ_GET_STR_BUG mpz_get_str corrupts memory, seems to be fixed
36** in a later release
37**
38** MPZ_DEBUG generates a bunch of diagnostic messages
39**
40** MPZ_SPARE_MALLOC if set, results in extra code that tries to
41** minimize the creation of extra objects.
42**
43** MPZ_TEST_DIV extra diagnostic output on stderr, when division
44** routines are involved
45**
46** MPZ_LIB_DOES_CHECKING if set, assumes that mpz library doesn't call
47** alloca with arg < 0 (when casted to a signed
48** integral type).
49**
50** MPZ_CONVERSIONS_AS_METHODS if set, presents the conversions as
51** methods. e.g., `mpz(5).long() == 5L'
52** Later, Guido provided an interface to the
53** standard functions. So this flag has no been
54** cleared, and `long(mpz(5)) == 5L'
55**
56** MP_TEST_ALLOC If set, you would discover why MPZ_GET_STR_BUG
57** is needed
58**
59** MAKEDUMMYINT Must be set if dynamic linking will be used
60*/
61
62
63/*
64** IMHO, mpz_m{div,mod,divmod}() do the wrong things when the denominator < 0
Guido van Rossum272841c1996-08-19 23:06:45 +000065** This has been fixed with gmp release 2.0
Guido van Rossum5f59d601992-12-14 16:59:51 +000066*/
67/*#define MPZ_MDIV_BUG fixed the (for me) nexessary parts in libgmp.a */
68/*
69** IMO, mpz_get_str() assumes a bit too large target space, if he doesn't
70** allocate it himself
71*/
Guido van Rossum5f59d601992-12-14 16:59:51 +000072
73#include "gmp.h"
Guido van Rossume7ef74d2000-02-24 15:26:30 +000074
Guido van Rossum57e846f1997-08-17 19:08:33 +000075#if __GNU_MP__ + 0 == 2
Guido van Rossum272841c1996-08-19 23:06:45 +000076#define GMP2
Andrew M. Kuchlingb6f6e952000-02-25 22:23:31 +000077#define BITS_PER_MP_LIMB mp_bits_per_limb
Guido van Rossum272841c1996-08-19 23:06:45 +000078#else
79#define MPZ_GET_STR_BUG
Andrew M. Kuchlingb6f6e952000-02-25 22:23:31 +000080#include "gmp-mparam.h"
Guido van Rossum272841c1996-08-19 23:06:45 +000081#endif
82
Guido van Rossum5f59d601992-12-14 16:59:51 +000083typedef struct {
Barry Warsaw3bdf7461996-12-09 23:16:31 +000084 PyObject_HEAD
Guido van Rossum5f59d601992-12-14 16:59:51 +000085 MP_INT mpz; /* the actual number */
86} mpzobject;
87
Barry Warsaw3bdf7461996-12-09 23:16:31 +000088staticforward PyTypeObject MPZtype;
Guido van Rossum5f59d601992-12-14 16:59:51 +000089
90#define is_mpzobject(v) ((v)->ob_type == &MPZtype)
91
92static const char initialiser_name[] = "mpz";
93
94/* #define MPZ_DEBUG */
95
96static mpzobject *
97newmpzobject()
98{
99 mpzobject *mpzp;
100
101
102#ifdef MPZ_DEBUG
103 fputs( "mpz_object() called...\n", stderr );
104#endif /* def MPZ_DEBUG */
Guido van Rossumb18618d2000-05-03 23:44:39 +0000105 mpzp = PyObject_New(mpzobject, &MPZtype);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000106 if (mpzp == NULL)
107 return NULL;
108
109 mpz_init(&mpzp->mpz); /* actual initialisation */
110 return mpzp;
111} /* newmpzobject() */
112
113#ifdef MPZ_GET_STR_BUG
Guido van Rossum5f59d601992-12-14 16:59:51 +0000114#include "longlong.h"
115#endif /* def MPZ_GET_STR_BUG */
116
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000117static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000118mpz_format(objp, base, withname)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000119 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000120 int base;
121 unsigned char withname;
122{
123 mpzobject *mpzp = (mpzobject *)objp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000124 PyStringObject *strobjp;
Guido van Rossum2650a422000-06-28 21:29:47 +0000125 size_t i;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000126 int cmpres;
127 int taglong;
128 char *cp;
129 char prefix[5], *tcp;
130
131
132 tcp = &prefix[0];
133
134 if (mpzp == NULL || !is_mpzobject(mpzp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000135 PyErr_BadInternalCall();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000136 return NULL;
137 }
138
139 assert(base >= 2 && base <= 36);
140
141 if (withname)
142 i = strlen(initialiser_name) + 2; /* e.g. 'mpz(' + ')' */
143 else
144 i = 0;
145
146 if ((cmpres = mpz_cmp_si(&mpzp->mpz, 0L)) == 0)
147 base = 10; /* '0' in every base, right */
148 else if (cmpres < 0) {
149 *tcp++ = '-';
150 i += 1; /* space to hold '-' */
151 }
152
153#ifdef MPZ_DEBUG
154 fprintf(stderr, "mpz_format: mpz_sizeinbase %d\n",
155 (int)mpz_sizeinbase(&mpzp->mpz, base));
156#endif /* def MPZ_DEBUG */
157#ifdef MPZ_GET_STR_BUG
Guido van Rossum272841c1996-08-19 23:06:45 +0000158#ifdef GMP2
159 i += ((size_t) abs(mpzp->mpz._mp_size) * BITS_PER_MP_LIMB
160 * __mp_bases[base].chars_per_bit_exactly) + 1;
161#else
Guido van Rossum5f59d601992-12-14 16:59:51 +0000162 i += ((size_t) abs(mpzp->mpz.size) * BITS_PER_MP_LIMB
163 * __mp_bases[base].chars_per_bit_exactly) + 1;
Guido van Rossum272841c1996-08-19 23:06:45 +0000164#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +0000165#else /* def MPZ_GET_STR_BUG */
166 i += (int)mpz_sizeinbase(&mpzp->mpz, base);
167#endif /* def MPZ_GET_STR_BUG else */
168
169 if (base == 16) {
170 *tcp++ = '0';
171 *tcp++ = 'x';
172 i += 2; /* space to hold '0x' */
173 }
174 else if (base == 8) {
175 *tcp++ = '0';
176 i += 1; /* space to hold the extra '0' */
177 }
178 else if (base > 10) {
179 *tcp++ = '0' + base / 10;
180 *tcp++ = '0' + base % 10;
181 *tcp++ = '#';
182 i += 3; /* space to hold e.g. '12#' */
183 }
184 else if (base < 10) {
185 *tcp++ = '0' + base;
186 *tcp++ = '#';
187 i += 2; /* space to hold e.g. '6#' */
188 }
189
190 /*
191 ** the following code looks if we need a 'L' attached to the number
192 ** it will also attach an 'L' to the value -0x80000000
193 */
194 taglong = 0;
195 if (mpz_size(&mpzp->mpz) > 1
196 || (long)mpz_get_ui(&mpzp->mpz) < 0L) {
197 taglong = 1;
198 i += 1; /* space to hold 'L' */
199 }
200
201#ifdef MPZ_DEBUG
202 fprintf(stderr, "mpz_format: requesting string size %d\n", i);
203#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000204 if ((strobjp =
205 (PyStringObject *)PyString_FromStringAndSize((char *)0, i))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000206 == NULL)
207 return NULL;
208
209 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000210 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000211 if (withname) {
212 strcpy(cp, initialiser_name);
213 cp += strlen(initialiser_name);
214 *cp++ = '('; /*')'*/
215 }
216
217 /* copy the already prepared prefix; e.g. sign and base indicator */
218 *tcp = '\0';
219 strcpy(cp, prefix);
220 cp += tcp - prefix;
221
222 /* since' we have the sign already, let the lib think it's a positive
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000223 number */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000224 if (cmpres < 0)
225 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
226 (void)mpz_get_str(cp, base, &mpzp->mpz);
227 if (cmpres < 0)
228 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
229#ifdef MPZ_DEBUG
230 fprintf(stderr, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
231 base, cp);
232#endif /* def MPZ_DEBUG */
233 cp += strlen(cp);
234
235 if (taglong)
236 *cp++ = 'L';
237 if (withname)
238 *cp++ = /*'('*/ ')';
239
240 *cp = '\0';
241
242#ifdef MPZ_DEBUG
243 fprintf(stderr,
Fred Drakea44d3532000-06-30 15:01:00 +0000244 "mpz_format: cp (str end) %p, begin %p, diff %d, i %d\n",
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000245 cp, PyString_AS_STRING(strobjp),
246 cp - PyString_AS_STRING(strobjp), i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000247#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000248 assert(cp - PyString_AS_STRING(strobjp) <= i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000249
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000250 if (cp - PyString_AS_STRING(strobjp) != i) {
251 strobjp->ob_size -= i - (cp - PyString_AS_STRING(strobjp));
Guido van Rossum5f59d601992-12-14 16:59:51 +0000252 }
253
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000254 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000255} /* mpz_format() */
256
257/* MPZ methods */
258
259static void
260mpz_dealloc(mpzp)
261 mpzobject *mpzp;
262{
263#ifdef MPZ_DEBUG
264 fputs( "mpz_dealloc() called...\n", stderr );
265#endif /* def MPZ_DEBUG */
266 mpz_clear(&mpzp->mpz);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000267 PyObject_Del(mpzp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000268} /* mpz_dealloc() */
269
Guido van Rossum5f59d601992-12-14 16:59:51 +0000270
271/* pointers to frequently used values 0, 1 and -1 */
272static mpzobject *mpz_value_zero, *mpz_value_one, *mpz_value_mone;
273
274static int
275mpz_compare(a, b)
276 mpzobject *a, *b;
277{
278 int cmpres;
279
280
281 /* guido sez it's better to return -1, 0 or 1 */
282 return (cmpres = mpz_cmp( &a->mpz, &b->mpz )) == 0 ? 0
283 : cmpres > 0 ? 1 : -1;
284} /* mpz_compare() */
285
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000286static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000287mpz_addition(a, b)
288 mpzobject *a;
289 mpzobject *b;
290{
291 mpzobject *z;
292
293
294#ifdef MPZ_SPARE_MALLOC
295 if (mpz_cmp_ui(&a->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000296 Py_INCREF(b);
297 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000298 }
299
300 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000301 Py_INCREF(a);
302 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000303 }
304#endif /* def MPZ_SPARE_MALLOC */
305
306 if ((z = newmpzobject()) == NULL)
307 return NULL;
308
309 mpz_add(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000310 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000311} /* mpz_addition() */
312
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000313static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000314mpz_substract(a, b)
315 mpzobject *a;
316 mpzobject *b;
317{
318 mpzobject *z;
319
320
321#ifdef MPZ_SPARE_MALLOC
322 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000323 Py_INCREF(a);
324 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000325 }
326#endif /* MPZ_SPARE_MALLOC */
327
328 if ((z = newmpzobject()) == NULL)
329 return NULL;
330
331 mpz_sub(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000332 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000333} /* mpz_substract() */
334
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000335static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000336mpz_multiply(a, b)
337 mpzobject *a;
338 mpzobject *b;
339{
340#ifdef MPZ_SPARE_MALLOC
341 int cmpres;
342#endif /* def MPZ_SPARE_MALLOC */
343 mpzobject *z;
344
345
346#ifdef MPZ_SPARE_MALLOC
347 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000348 Py_INCREF(mpz_value_zero);
349 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000350 }
351 if (cmpres > 0 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000352 Py_INCREF(b);
353 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000354 }
355
356 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long_int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000357 Py_INCREF(mpz_value_zero);
358 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000359 }
360 if (cmpres > 0 && mpz_cmp_ui(&b->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000361 Py_INCREF(a);
362 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000363 }
364#endif /* MPZ_SPARE_MALLOC */
365
366 if ((z = newmpzobject()) == NULL)
367 return NULL;
368
369 mpz_mul( &z->mpz, &a->mpz, &b->mpz );
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000370 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000371
372} /* mpz_multiply() */
373
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000374static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000375mpz_divide(a, b)
376 mpzobject *a;
377 mpzobject *b;
378{
379#ifdef MPZ_SPARE_MALLOC
380 int cmpres;
381#endif /* def MPZ_SPARE_MALLOC */
382 mpzobject *z;
383
384
385 if ((
386#ifdef MPZ_SPARE_MALLOC
387 cmpres =
388#endif /* def MPZ_SPARE_MALLOC */
389 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000390 PyErr_SetString(PyExc_ZeroDivisionError, "mpz./ by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000391 return NULL;
392 }
393#ifdef MPZ_SPARE_MALLOC
394 if (cmpres > 0 && mpz_cmp_ui(&b->mpz(unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000395 Py_INCREF(a);
396 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000397 }
398#endif /* def MPZ_SPARE_MALLOC */
399
400 if ((z = newmpzobject()) == NULL)
401 return NULL;
402
403#ifdef MPZ_TEST_DIV
404 fputs("mpz_divide: div result", stderr);
405 mpz_div(&z->mpz, &a->mpz, &b->mpz);
406 mpz_out_str(stderr, 10, &z->mpz);
407 putc('\n', stderr);
408#endif /* def MPZ_TEST_DIV */
409#ifdef MPZ_MDIV_BUG
410 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
411 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)) {
412 /*
413 ** numerator has other sign than denominator: we have
414 ** to look at the remainder for a correction, since mpz_mdiv
415 ** also calls mpz_divmod, I can as well do it myself
416 */
417 MP_INT tmpmpz;
418
419
420 mpz_init(&tmpmpz);
421 mpz_divmod(&z->mpz, &tmpmpz, &a->mpz, &b->mpz);
422
423 if (mpz_cmp_ui(&tmpmpz, (unsigned long int)0) != 0)
424 mpz_sub_ui(&z->mpz, &z->mpz, (unsigned long int)1);
425
426 mpz_clear(&tmpmpz);
427 }
428 else
429 mpz_div(&z->mpz, &a->mpz, &b->mpz);
430 /* the ``naive'' implementation does it right for operands
431 having the same sign */
432
433#else /* def MPZ_MDIV_BUG */
434 mpz_mdiv(&z->mpz, &a->mpz, &b->mpz);
435#endif /* def MPZ_MDIV_BUG else */
436#ifdef MPZ_TEST_DIV
437 fputs("mpz_divide: mdiv result", stderr);
438 mpz_out_str(stderr, 10, &z->mpz);
439 putc('\n', stderr);
440#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000441 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000442
443} /* mpz_divide() */
444
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000445static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000446mpz_remainder(a, b)
447 mpzobject *a;
448 mpzobject *b;
449{
450#ifdef MPZ_SPARE_MALLOC
451 int cmpres;
452#endif /* def MPZ_SPARE_MALLOC */
453 mpzobject *z;
454
455
456 if ((
457#ifdef MPZ_SPARE_MALLOC
458 cmpres =
459#endif /* def MPZ_SPARE_MALLOC */
460 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000461 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.% by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000462 return NULL;
463 }
464#ifdef MPZ_SPARE_MALLOC
465 if (cmpres > 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000466 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)2)) == 0)
467 {
468 Py_INCREF(mpz_value_one);
469 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000470 }
471 if (cmpres < 0) {
472 /* b must be 1 now */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000473 Py_INCREF(mpz_value_zero);
474 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000475 }
476 }
477#endif /* def MPZ_SPARE_MALLOC */
478
479 if ((z = newmpzobject()) == NULL)
480 return NULL;
481
482#ifdef MPZ_TEST_DIV
483 fputs("mpz_remain: mod result", stderr);
484 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
485 mpz_out_str(stderr, 10, &z->mpz);
486 putc('\n', stderr);
487#endif /* def MPZ_TEST_DIV */
488#ifdef MPZ_MDIV_BUG
489
490 /* the ``naive'' implementation does it right for operands
491 having the same sign */
492 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
493
494 /* assumption: z, a and b all point to different locations */
495 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
496 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
497 && mpz_cmp_ui(&z->mpz, (unsigned long int)0) != 0)
498 mpz_add(&z->mpz, &z->mpz, &b->mpz);
499 /*
500 ** numerator has other sign than denominator: we have
501 ** to look at the remainder for a correction, since mpz_mdiv
502 ** also calls mpz_divmod, I can as well do it myself
503 */
504#else /* def MPZ_MDIV_BUG */
505 mpz_mmod(&z->mpz, &a->mpz, &b->mpz);
506#endif /* def MPZ_MDIV_BUG else */
507#ifdef MPZ_TEST_DIV
508 fputs("mpz_remain: mmod result", stderr);
509 mpz_out_str(stderr, 10, &z->mpz);
510 putc('\n', stderr);
511#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000512 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000513
514} /* mpz_remainder() */
515
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000516static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000517mpz_div_and_mod(a, b)
518 mpzobject *a;
519 mpzobject *b;
520{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000521 PyObject *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000522 mpzobject *x = NULL, *y = NULL;
523
524
525 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000526 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.divmod by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000527 return NULL;
528 }
529
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000530 if ((z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +0000531 || (x = newmpzobject()) == NULL
532 || (y = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000533 Py_XDECREF(z);
534 Py_XDECREF(x);
535 Py_XDECREF(y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000536 return NULL;
537 }
538
539#ifdef MPZ_TEST_DIV
540 fputs("mpz_divmod: dm result", stderr);
541 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
542 mpz_out_str(stderr, 10, &x->mpz);
543 putc('\n', stderr);
544 mpz_out_str(stderr, 10, &y->mpz);
545 putc('\n', stderr);
546#endif /* def MPZ_TEST_DIV */
547#ifdef MPZ_MDIV_BUG
548 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
549 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
550 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
551 && mpz_cmp_ui(&y->mpz, (unsigned long int)0) != 0) {
552 /*
553 ** numerator has other sign than denominator: we have
554 ** to look at the remainder for a correction.
555 */
556 mpz_add(&y->mpz, &y->mpz, &b->mpz);
557 mpz_sub_ui(&x->mpz, &x->mpz, (unsigned long int)1);
558 }
559#else /* def MPZ_MDIV_BUG */
560 mpz_mdivmod( &x->mpz, &y->mpz, &a->mpz, &b->mpz );
561#endif /* def MPZ_MDIV_BUG else */
562#ifdef MPZ_TEST_DIV
563 fputs("mpz_divmod: mdm result", stderr);
564 mpz_out_str(stderr, 10, &x->mpz);
565 putc('\n', stderr);
566 mpz_out_str(stderr, 10, &y->mpz);
567 putc('\n', stderr);
568#endif /* def MPZ_TEST_DIV */
569
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000570 (void)PyTuple_SetItem(z, 0, (PyObject *)x);
571 (void)PyTuple_SetItem(z, 1, (PyObject *)y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000572
573 return z;
574} /* mpz_div_and_mod() */
575
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000576static PyObject *
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000577mpz_power(a, b, m)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000578 mpzobject *a;
579 mpzobject *b;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000580 mpzobject *m;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000581{
582 mpzobject *z;
583 int cmpres;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000584
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000585 if ((PyObject *)m != Py_None) {
586 mpzobject *z2;
587 Py_INCREF(Py_None);
588 z=(mpzobject *)mpz_power(a, b, (mpzobject *)Py_None);
589 Py_DECREF(Py_None);
590 if (z==NULL) return((PyObject *)z);
591 z2=(mpzobject *)mpz_remainder(z, m);
592 Py_DECREF(z);
593 return((PyObject *)z2);
594 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000595
596 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
597 /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
598
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000599 Py_INCREF(mpz_value_one);
600 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000601 }
602
603 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000604 PyErr_SetString(PyExc_ValueError,
605 "mpz.pow to negative exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000606 return NULL;
607 }
608
609 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
610 /* the base is 0 */
611
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000612 Py_INCREF(mpz_value_zero);
613 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000614 }
615 else if (cmpres > 0
616 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
617 /* the base is 1 */
618
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000619 Py_INCREF(mpz_value_one);
620 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000621 }
622 else if (cmpres < 0
623 && mpz_cmp_si(&a->mpz, (long int)-1) == 0) {
624
625 MP_INT tmpmpz;
626 /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
627 /* XXX this code needs to be optimized: what's better?
628 mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
629 for *un*obvious reasons */
630
631 /* is the exponent even? */
632 mpz_init(&tmpmpz);
633
634 /* look to the remainder after a division by (1 << 1) */
635 mpz_mod_2exp(&tmpmpz, &b->mpz, (unsigned long int)1);
636
637 if (mpz_cmp_ui(&tmpmpz, (unsigned int)0) == 0) {
638 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000639 Py_INCREF(mpz_value_one);
640 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000641 }
642 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000643 Py_INCREF(mpz_value_mone);
644 return (PyObject *)mpz_value_mone;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000645 }
646
647#ifdef MPZ_LIB_DOES_CHECKING
648 /* check if it's doable: sizeof(exp) > sizeof(long) &&
649 abs(base) > 1 ?? --> No Way */
650 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000651 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000652#else /* def MPZ_LIB_DOES_CHECKING */
653 /* wet finger method */
654 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000655 PyErr_SetString(PyExc_ValueError,
656 "mpz.pow outrageous exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000657 return NULL;
658 }
659#endif /* def MPZ_LIB_DOES_CHECKING else */
660
661 if ((z = newmpzobject()) == NULL)
662 return NULL;
663
664 mpz_pow_ui(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
665
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000666 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000667} /* mpz_power() */
668
669
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000670static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000671mpz_negative(v)
672 mpzobject *v;
673{
674 mpzobject *z;
675
676
677#ifdef MPZ_SPARE_MALLOC
678 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) == 0) {
679 /* -0 == 0 */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000680 Py_INCREF(v);
681 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000682 }
683#endif /* def MPZ_SPARE_MALLOC */
684
685 if ((z = newmpzobject()) == NULL)
686 return NULL;
687
688 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000689 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000690} /* mpz_negative() */
691
692
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000693static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000694mpz_positive(v)
695 mpzobject *v;
696{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000697 Py_INCREF(v);
698 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000699} /* mpz_positive() */
700
701
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000702static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000703mpz_absolute(v)
704 mpzobject *v;
705{
706 mpzobject *z;
707
708
709 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000710 Py_INCREF(v);
711 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000712 }
713
714 if ((z = newmpzobject()) == NULL)
715 return NULL;
716
717 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000718 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000719} /* mpz_absolute() */
720
721static int
722mpz_nonzero(v)
723 mpzobject *v;
724{
725 return mpz_cmp_ui(&v->mpz, (unsigned long int)0) != 0;
726} /* mpz_nonzero() */
727
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000728static PyObject *
Guido van Rossum272841c1996-08-19 23:06:45 +0000729py_mpz_invert(v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000730 mpzobject *v;
731{
732 mpzobject *z;
733
734
735 /* I think mpz_com does exactly what needed */
736 if ((z = newmpzobject()) == NULL)
737 return NULL;
738
739 mpz_com(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000740 return (PyObject *)z;
Guido van Rossum272841c1996-08-19 23:06:45 +0000741} /* py_mpz_invert() */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000742
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000743static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000744mpz_lshift(a, b)
745 mpzobject *a;
746 mpzobject *b;
747{
748 int cmpres;
749 mpzobject *z;
750
751
752 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
753 /* a << 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000754 Py_INCREF(a);
755 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000756 }
757
758 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000759 PyErr_SetString(PyExc_ValueError,
760 "mpz.<< negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000761 return NULL;
762 }
763
764#ifdef MPZ_LIB_DOES_CHECKING
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#else /* def MPZ_LIB_DOES_CHECKING */
768 /* wet finger method */
769 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000770 PyErr_SetString(PyExc_ValueError,
771 "mpz.<< outrageous shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000772 return NULL;
773 }
774#endif /* def MPZ_LIB_DOES_CHECKING else */
775
776 if ((z = newmpzobject()) == NULL)
777 return NULL;
778
779 mpz_mul_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000780 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000781} /* mpz_lshift() */
782
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000783static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000784mpz_rshift(a, b)
785 mpzobject *a;
786 mpzobject *b;
787{
788 int cmpres;
789 mpzobject *z;
790
791
792 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
793 /* a >> 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000794 Py_INCREF(a);
795 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000796 }
797
798 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000799 PyErr_SetString(PyExc_ValueError,
800 "mpz.>> negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000801 return NULL;
802 }
803
804 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000805 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000806
807 if ((z = newmpzobject()) == NULL)
808 return NULL;
809
810 mpz_div_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000811 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000812} /* mpz_rshift() */
813
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000814static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000815mpz_andfunc(a, b)
816 mpzobject *a;
817 mpzobject *b;
818{
819 mpzobject *z;
820
821
822 if ((z = newmpzobject()) == NULL)
823 return NULL;
824
825 mpz_and(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000826 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000827} /* mpz_andfunc() */
828
829/* hack Hack HAck HACk HACK, XXX this code is dead slow */
830void
831mpz_xor(res, op1, op2)
832 MP_INT *res;
833 const MP_INT *op1;
834 const MP_INT *op2;
835{
836 MP_INT tmpmpz;
837
838 mpz_init(&tmpmpz);
839
840 mpz_and(res, op1, op2);
841 mpz_com(&tmpmpz, res);
842 mpz_ior(res, op1, op2);
843 mpz_and(res, res, &tmpmpz);
844
845 mpz_clear(&tmpmpz);
846} /* mpz_xor() HACK */
847
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000848static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000849mpz_xorfunc(a, b)
850 mpzobject *a;
851 mpzobject *b;
852{
853 mpzobject *z;
854
855
856 if ((z = newmpzobject()) == NULL)
857 return NULL;
858
859 mpz_xor(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000860 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000861} /* mpz_xorfunc() */
862
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000863static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000864mpz_orfunc(a, b)
865 mpzobject *a;
866 mpzobject *b;
867{
868 mpzobject *z;
869
870
871 if ((z = newmpzobject()) == NULL)
872 return NULL;
873
874 mpz_ior(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000875 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000876} /* mpz_orfunc() */
877
878/* MPZ initialisation */
879
880#include "longintrepr.h"
881
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000882static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000883MPZ_mpz(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000884 PyObject *self;
885 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000886{
887 mpzobject *mpzp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000888 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000889
890
891#ifdef MPZ_DEBUG
892 fputs("MPZ_mpz() called...\n", stderr);
893#endif /* def MPZ_DEBUG */
894
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000895 if (!PyArg_Parse(args, "O", &objp))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000896 return NULL;
897
898 /* at least we know it's some object */
Barry Warsawabb7efe1996-12-09 23:22:35 +0000899 /* note DON't Py_DECREF args NEITHER objp */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000900
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000901 if (PyInt_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000902 long lval;
903
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000904 if (!PyArg_Parse(objp, "l", &lval))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000905 return NULL;
906
907 if (lval == (long)0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000908 Py_INCREF(mpz_value_zero);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000909 mpzp = mpz_value_zero;
910 }
911 else if (lval == (long)1) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000912 Py_INCREF(mpz_value_one);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000913 mpzp = mpz_value_one;
914 }
915 else if ((mpzp = newmpzobject()) == NULL)
916 return NULL;
917 else mpz_set_si(&mpzp->mpz, lval);
918 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000919 else if (PyLong_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000920 MP_INT mplongdigit;
921 int i;
922 unsigned char isnegative;
923
924
925 if ((mpzp = newmpzobject()) == NULL)
926 return NULL;
927
928 mpz_set_si(&mpzp->mpz, 0L);
929 mpz_init(&mplongdigit);
930
931 /* how we're gonna handle this? */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000932 if ((isnegative =
933 ((i = ((PyLongObject *)objp)->ob_size) < 0) ))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000934 i = -i;
935
936 while (i--) {
937 mpz_set_ui(&mplongdigit,
938 (unsigned long)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000939 ((PyLongObject *)objp)->ob_digit[i]);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000940 mpz_mul_2exp(&mplongdigit,&mplongdigit,
941 (unsigned long int)i * SHIFT);
942 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
943 }
944
945 if (isnegative)
946 mpz_neg(&mpzp->mpz, &mpzp->mpz);
947
948 /* get rid of allocation for tmp variable */
949 mpz_clear(&mplongdigit);
950 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000951 else if (PyString_Check(objp)) {
Andrew M. Kuchling4c07f811998-12-14 19:36:14 +0000952 unsigned char *cp = (unsigned char *)PyString_AS_STRING(objp);
Guido van Rossum7e488981998-10-08 02:25:24 +0000953 int len = PyString_GET_SIZE(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000954 MP_INT mplongdigit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000955
956 if ((mpzp = newmpzobject()) == NULL)
957 return NULL;
958
959 mpz_set_si(&mpzp->mpz, 0L);
960 mpz_init(&mplongdigit);
961
962 /* let's do it the same way as with the long conversion:
963 without thinking how it can be faster (-: :-) */
964
965 cp += len;
966 while (len--) {
967 mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
968 mpz_mul_2exp(&mplongdigit,&mplongdigit,
969 (unsigned long int)len * 8);
970 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
971 }
972
973 /* get rid of allocation for tmp variable */
974 mpz_clear(&mplongdigit);
975 }
976 else if (is_mpzobject(objp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000977 Py_INCREF(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000978 mpzp = (mpzobject *)objp;
979 }
980 else {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000981 PyErr_SetString(PyExc_TypeError,
982"mpz.mpz() expects integer, long, string or mpz object argument");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000983 return NULL;
984 }
985
986
987#ifdef MPZ_DEBUG
988 fputs("MPZ_mpz: created mpz=", stderr);
989 mpz_out_str(stderr, 10, &mpzp->mpz);
990 putc('\n', stderr);
991#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000992 return (PyObject *)mpzp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000993} /* MPZ_mpz() */
994
995static mpzobject *
996mpz_mpzcoerce(z)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000997 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000998{
999 /* shortcut: 9 out of 10 times the type is already ok */
1000 if (is_mpzobject(z)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001001 Py_INCREF(z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001002 return (mpzobject *)z; /* coercion succeeded */
1003 }
1004
1005 /* what types do we accept?: intobjects and longobjects */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001006 if (PyInt_Check(z) || PyLong_Check(z))
1007 return (mpzobject *)MPZ_mpz((PyObject *)NULL, z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001008
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001009 PyErr_SetString(PyExc_TypeError,
1010 "number coercion (to mpzobject) failed");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001011 return NULL;
1012} /* mpz_mpzcoerce() */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001013
1014/* Forward */
Tim Petersdbd9ba62000-07-09 03:09:57 +00001015static void mpz_divm(MP_INT *res, const MP_INT *num,
1016 const MP_INT *den, const MP_INT *mod);
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001017
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001018static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001019MPZ_powm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001020 PyObject *self;
1021 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001022{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001023 PyObject *base, *exp, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001024 mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
1025 mpzobject *z;
1026 int tstres;
1027
1028
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001029 if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001030 return NULL;
1031
1032 if ((mpzbase = mpz_mpzcoerce(base)) == NULL
1033 || (mpzexp = mpz_mpzcoerce(exp)) == NULL
1034 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1035 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001036 Py_XDECREF(mpzbase);
1037 Py_XDECREF(mpzexp);
1038 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001039 return NULL;
1040 }
1041
1042 if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001043 Py_INCREF(mpz_value_one);
1044 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001045 }
1046
1047 if (tstres < 0) {
1048 MP_INT absexp;
1049 /* negative exp */
1050
1051 mpz_init_set(&absexp, &mpzexp->mpz);
1052 mpz_abs(&absexp, &absexp);
1053 mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
1054
1055 mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
1056
1057 mpz_clear(&absexp);
1058 }
1059 else {
1060 mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
1061 }
1062
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001063 Py_DECREF(mpzbase);
1064 Py_DECREF(mpzexp);
1065 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001066
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001067 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001068} /* MPZ_powm() */
1069
1070
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001071static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001072MPZ_gcd(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001073 PyObject *self;
1074 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001075{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001076 PyObject *op1, *op2;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001077 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1078 mpzobject *z;
1079
1080
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001081 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001082 return NULL;
1083
1084 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1085 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
1086 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001087 Py_XDECREF(mpzop1);
1088 Py_XDECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001089 return NULL;
1090 }
1091
1092 /* ok, we have three mpzobjects, and an initialised result holder */
1093 mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
1094
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001095 Py_DECREF(mpzop1);
1096 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001097
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001098 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001099} /* MPZ_gcd() */
1100
1101
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001102static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001103MPZ_gcdext(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001104 PyObject *self;
1105 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001106{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001107 PyObject *op1, *op2, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001108 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1109 mpzobject *g = NULL, *s = NULL, *t = NULL;
1110
1111
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001112 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001113 return NULL;
1114
1115 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1116 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001117 || (z = PyTuple_New(3)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001118 || (g = newmpzobject()) == NULL
1119 || (s = newmpzobject()) == NULL
1120 || (t = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001121 Py_XDECREF(mpzop1);
1122 Py_XDECREF(mpzop2);
1123 Py_XDECREF(z);
1124 Py_XDECREF(g);
1125 Py_XDECREF(s);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001126 /*Py_XDECREF(t);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001127 return NULL;
1128 }
1129
1130 mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
1131
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001132 Py_DECREF(mpzop1);
1133 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001134
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001135 (void)PyTuple_SetItem(z, 0, (PyObject *)g);
1136 (void)PyTuple_SetItem(z, 1, (PyObject *)s);
1137 (void)PyTuple_SetItem(z, 2, (PyObject *)t);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001138
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001139 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001140} /* MPZ_gcdext() */
1141
1142
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001143static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001144MPZ_sqrt(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001145 PyObject *self;
1146 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001147{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001148 PyObject *op;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001149 mpzobject *mpzop = NULL;
1150 mpzobject *z;
1151
1152
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001153 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001154 return NULL;
1155
1156 if ((mpzop = mpz_mpzcoerce(op)) == NULL
1157 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001158 Py_XDECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001159 return NULL;
1160 }
1161
1162 mpz_sqrt(&z->mpz, &mpzop->mpz);
1163
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001164 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001165
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001166 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001167} /* MPZ_sqrt() */
1168
1169
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001170static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001171MPZ_sqrtrem(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001172 PyObject *self;
1173 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001174{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001175 PyObject *op, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001176 mpzobject *mpzop = NULL;
1177 mpzobject *root = NULL, *rem = NULL;
1178
1179
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001180 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001181 return NULL;
1182
1183 if ((mpzop = mpz_mpzcoerce(op)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001184 || (z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001185 || (root = newmpzobject()) == NULL
1186 || (rem = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001187 Py_XDECREF(mpzop);
1188 Py_XDECREF(z);
1189 Py_XDECREF(root);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001190 /*Py_XDECREF(rem);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001191 return NULL;
1192 }
1193
1194 mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
1195
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001196 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001197
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001198 (void)PyTuple_SetItem(z, 0, (PyObject *)root);
1199 (void)PyTuple_SetItem(z, 1, (PyObject *)rem);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001200
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001201 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001202} /* MPZ_sqrtrem() */
1203
1204
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001205static void
Guido van Rossum5f59d601992-12-14 16:59:51 +00001206#if __STDC__
1207mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
1208#else
1209mpz_divm(res, num, den, mod)
1210 MP_INT *res;
1211 const MP_INT *num;
1212 const MP_INT *den;
1213 const MP_INT *mod;
1214#endif
1215{
1216 MP_INT s0, s1, q, r, x, d0, d1;
1217
1218 mpz_init_set(&s0, num);
1219 mpz_init_set_ui(&s1, 0);
1220 mpz_init(&q);
1221 mpz_init(&r);
1222 mpz_init(&x);
1223 mpz_init_set(&d0, den);
1224 mpz_init_set(&d1, mod);
1225
Guido van Rossum272841c1996-08-19 23:06:45 +00001226#ifdef GMP2
1227 while (d1._mp_size != 0) {
1228#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001229 while (d1.size != 0) {
Guido van Rossum272841c1996-08-19 23:06:45 +00001230#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001231 mpz_divmod(&q, &r, &d0, &d1);
1232 mpz_set(&d0, &d1);
1233 mpz_set(&d1, &r);
1234
1235 mpz_mul(&x, &s1, &q);
1236 mpz_sub(&x, &s0, &x);
1237 mpz_set(&s0, &s1);
1238 mpz_set(&s1, &x);
1239 }
1240
Guido van Rossum272841c1996-08-19 23:06:45 +00001241#ifdef GMP2
1242 if (d0._mp_size != 1 || d0._mp_d[0] != 1)
1243 res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
1244#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001245 if (d0.size != 1 || d0.d[0] != 1)
1246 res->size = 0; /* trouble: the gcd != 1; set s to zero */
Guido van Rossum272841c1996-08-19 23:06:45 +00001247#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001248 else {
1249#ifdef MPZ_MDIV_BUG
1250 /* watch out here! first check the signs, and then perform
1251 the mpz_mod() since mod could point to res */
1252 if ((s0.size < 0) != (mod->size < 0)) {
1253 mpz_mod(res, &s0, mod);
1254
1255 if (res->size)
1256 mpz_add(res, res, mod);
1257 }
1258 else
1259 mpz_mod(res, &s0, mod);
1260
1261#else /* def MPZ_MDIV_BUG */
1262 mpz_mmod(res, &s0, mod);
1263#endif /* def MPZ_MDIV_BUG else */
1264 }
1265
1266 mpz_clear(&s0);
1267 mpz_clear(&s1);
1268 mpz_clear(&q);
1269 mpz_clear(&r);
1270 mpz_clear(&x);
1271 mpz_clear(&d0);
1272 mpz_clear(&d1);
1273} /* mpz_divm() */
1274
1275
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001276static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001277MPZ_divm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001278 PyObject *self;
1279 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001280{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001281 PyObject *num, *den, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001282 mpzobject *mpznum, *mpzden, *mpzmod = NULL;
1283 mpzobject *z = NULL;
1284
1285
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001286 if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001287 return NULL;
1288
1289 if ((mpznum = mpz_mpzcoerce(num)) == NULL
1290 || (mpzden = mpz_mpzcoerce(den)) == NULL
1291 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1292 || (z = newmpzobject()) == NULL ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001293 Py_XDECREF(mpznum);
1294 Py_XDECREF(mpzden);
1295 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001296 return NULL;
1297 }
1298
1299 mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
1300
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001301 Py_DECREF(mpznum);
1302 Py_DECREF(mpzden);
1303 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001304
1305 if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001306 Py_DECREF(z);
1307 PyErr_SetString(PyExc_ValueError,
1308 "gcd(den, mod) != 1 or num == 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001309 return NULL;
1310 }
1311
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001312 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001313} /* MPZ_divm() */
1314
1315
1316/* MPZ methods-as-attributes */
1317#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001318static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001319mpz_int(self, args)
1320 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001321 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001322#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001323static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001324mpz_int(self)
1325 mpzobject *self;
1326#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1327{
1328 long sli;
1329
1330
1331#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001332 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001333 return NULL;
1334#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1335
1336 if (mpz_size(&self->mpz) > 1
1337 || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001338 PyErr_SetString(PyExc_ValueError,
1339 "mpz.int() arg too long to convert");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001340 return NULL;
1341 }
1342
1343 if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
1344 sli = -sli;
1345
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001346 return PyInt_FromLong(sli);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001347} /* mpz_int() */
1348
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001349static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001350#ifdef MPZ_CONVERSIONS_AS_METHODS
1351mpz_long(self, args)
1352 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001353 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001354#else /* def MPZ_CONVERSIONS_AS_METHODS */
1355mpz_long(self)
1356 mpzobject *self;
1357#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1358{
1359 int i, isnegative;
1360 unsigned long int uli;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001361 PyLongObject *longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001362 int ldcount;
1363 int bitpointer, newbitpointer;
1364 MP_INT mpzscratch;
1365
1366
1367#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001368 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001369 return NULL;
1370#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1371
1372 /* determine length of python-long to be allocated */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001373 if ((longobjp = _PyLong_New(i = (int)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001374 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
1375 + SHIFT - 1) /
1376 SHIFT))) == NULL)
1377 return NULL;
1378
1379 /* determine sign, and copy self to scratch var */
1380 mpz_init_set(&mpzscratch, &self->mpz);
Guido van Rossum272841c1996-08-19 23:06:45 +00001381 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001382 mpz_neg(&mpzscratch, &mpzscratch);
1383
1384 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001385 e.g. dismantle mpzscratch, build PyLongObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001386
1387 bitpointer = 0; /* the number of valid bits in stock */
1388 newbitpointer = 0;
1389 ldcount = 0; /* the python-long limb counter */
1390 uli = (unsigned long int)0;
1391 while (i--) {
1392 longobjp->ob_digit[ldcount] = uli & MASK;
1393
1394 /* check if we've had enough bits for this digit */
1395 if (bitpointer < SHIFT) {
1396 uli = mpz_get_ui(&mpzscratch);
1397 longobjp->ob_digit[ldcount] |=
1398 (uli << bitpointer) & MASK;
1399 uli >>= SHIFT-bitpointer;
1400 bitpointer += BITS_PER_MP_LIMB;
1401 mpz_div_2exp(&mpzscratch, &mpzscratch,
1402 BITS_PER_MP_LIMB);
1403 }
1404 else
1405 uli >>= SHIFT;
1406 bitpointer -= SHIFT;
1407 ldcount++;
1408 }
1409
1410 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1411 mpz_clear(&mpzscratch);
1412 assert(ldcount <= longobjp->ob_size);
1413
1414 /* long_normalize() is file-static */
1415 /* longobjp = long_normalize(longobjp); */
1416 while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
1417 ldcount--;
1418 longobjp->ob_size = ldcount;
1419
1420
1421 if (isnegative)
1422 longobjp->ob_size = -longobjp->ob_size;
1423
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001424 return (PyObject *)longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001425
1426} /* mpz_long() */
1427
1428
1429/* I would have avoided pow() anyways, so ... */
1430static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
1431
1432#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001433static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001434mpz_float(self, args)
1435 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001436 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001437#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001438static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001439mpz_float(self)
1440 mpzobject *self;
1441#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1442{
1443 int i, isnegative;
1444 double x;
1445 double mulstate;
1446 MP_INT mpzscratch;
1447
1448
1449#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001450 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001451 return NULL;
1452#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1453
1454 i = (int)mpz_size(&self->mpz);
1455
1456 /* determine sign, and copy abs(self) to scratch var */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001457 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
1458 {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001459 mpz_init(&mpzscratch);
1460 mpz_neg(&mpzscratch, &self->mpz);
1461 }
1462 else
1463 mpz_init_set(&mpzscratch, &self->mpz);
1464
1465 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001466 e.g. dismantle mpzscratch, build PyFloatObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001467
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001468 /* Can this overflow? Dunno, protect against that possibility. */
1469 PyFPE_START_PROTECT("mpz_float", return 0)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001470 x = 0.0;
1471 mulstate = 1.0;
1472 while (i--) {
1473 x += mulstate * mpz_get_ui(&mpzscratch);
1474 mulstate *= multiplier;
1475 mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
1476 }
Guido van Rossum45b83911997-03-14 04:32:50 +00001477 PyFPE_END_PROTECT(mulstate)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001478
1479 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1480 mpz_clear(&mpzscratch);
1481
1482 if (isnegative)
1483 x = -x;
1484
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001485 return PyFloat_FromDouble(x);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001486
1487} /* mpz_float() */
1488
1489#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001490static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001491mpz_hex(self, args)
1492 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001493 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001494#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001495static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001496mpz_hex(self)
1497 mpzobject *self;
1498#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1499{
1500#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001501 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001502 return NULL;
1503#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1504
1505 return mpz_format(self, 16, (unsigned char)1);
1506} /* mpz_hex() */
1507
1508#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001509static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001510mpz_oct(self, args)
1511 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001512 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001513#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001514static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001515mpz_oct(self)
1516 mpzobject *self;
1517#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1518{
1519#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001520 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001521 return NULL;
1522#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1523
1524 return mpz_format(self, 8, (unsigned char)1);
1525} /* mpz_oct() */
1526
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001527static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001528mpz_binary(self, args)
1529 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001530 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001531{
1532 int size;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001533 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001534 char *cp;
1535 MP_INT mp;
1536 unsigned long ldigit;
1537
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001538 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001539 return NULL;
1540
1541 if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001542 PyErr_SetString(PyExc_ValueError,
1543 "mpz.binary() arg must be >= 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001544 return NULL;
1545 }
1546
1547 mpz_init_set(&mp, &self->mpz);
1548 size = (int)mpz_size(&mp);
1549
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001550 if ((strobjp = (PyStringObject *)
1551 PyString_FromStringAndSize(
1552 (char *)0, size * sizeof (unsigned long int))) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001553 return NULL;
1554
1555 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001556 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001557
1558 /* this has been programmed using a (fairly) decent lib-i/f it could
1559 be must faster if we looked into the GMP lib */
1560 while (size--) {
1561 ldigit = mpz_get_ui(&mp);
1562 mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
1563 *cp++ = (unsigned char)(ldigit & 0xFF);
1564 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1565 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1566 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1567 }
1568
1569 while (strobjp->ob_size && !*--cp)
1570 strobjp->ob_size--;
1571
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001572 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001573} /* mpz_binary() */
1574
1575
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001576static PyMethodDef mpz_methods[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001577#ifdef MPZ_CONVERSIONS_AS_METHODS
1578 {"int", mpz_int},
1579 {"long", mpz_long},
1580 {"float", mpz_float},
1581 {"hex", mpz_hex},
1582 {"oct", mpz_oct},
1583#endif /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001584 {"binary", (PyCFunction)mpz_binary},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001585 {NULL, NULL} /* sentinel */
1586};
1587
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001588static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001589mpz_getattr(self, name)
1590 mpzobject *self;
1591 char *name;
1592{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001593 return Py_FindMethod(mpz_methods, (PyObject *)self, name);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001594} /* mpz_getattr() */
1595
1596
1597static int
1598mpz_coerce(pv, pw)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001599 PyObject **pv;
1600 PyObject **pw;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001601{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001602 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001603
1604#ifdef MPZ_DEBUG
1605 fputs("mpz_coerce() called...\n", stderr);
1606#endif /* def MPZ_DEBUG */
1607
1608 assert(is_mpzobject(*pv));
1609
1610 /* always convert other arg to mpz value, except for floats */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001611 if (!PyFloat_Check(*pw)) {
1612 if ((z = (PyObject *)mpz_mpzcoerce(*pw)) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001613 return -1; /* -1: an error always has been set */
1614
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001615 Py_INCREF(*pv);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001616 *pw = z;
1617 }
1618 else {
1619 if ((z = mpz_float(*pv, NULL)) == NULL)
1620 return -1;
1621
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001622 Py_INCREF(*pw);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001623 *pv = z;
1624 }
1625 return 0; /* coercion succeeded */
1626
1627} /* mpz_coerce() */
1628
1629
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001630static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001631mpz_repr(v)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001632 PyObject *v;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001633{
1634 return mpz_format(v, 10, (unsigned char)1);
1635} /* mpz_repr() */
1636
1637
1638
Guido van Rossumb6775db1994-08-01 11:34:53 +00001639#define UF (unaryfunc)
1640#define BF (binaryfunc)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001641#define TF (ternaryfunc)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001642#define IF (inquiry)
1643#define CF (coercion)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001644
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001645static PyNumberMethods mpz_as_number = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001646 BF mpz_addition, /*nb_add*/
1647 BF mpz_substract, /*nb_subtract*/
1648 BF mpz_multiply, /*nb_multiply*/
1649 BF mpz_divide, /*nb_divide*/
1650 BF mpz_remainder, /*nb_remainder*/
1651 BF mpz_div_and_mod, /*nb_divmod*/
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001652 TF mpz_power, /*nb_power*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001653 UF mpz_negative, /*nb_negative*/
1654 UF mpz_positive, /*tp_positive*/
1655 UF mpz_absolute, /*tp_absolute*/
1656 IF mpz_nonzero, /*tp_nonzero*/
Guido van Rossum272841c1996-08-19 23:06:45 +00001657 UF py_mpz_invert, /*nb_invert*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001658 BF mpz_lshift, /*nb_lshift*/
1659 BF mpz_rshift, /*nb_rshift*/
1660 BF mpz_andfunc, /*nb_and*/
1661 BF mpz_xorfunc, /*nb_xor*/
1662 BF mpz_orfunc, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001663 CF mpz_coerce, /*nb_coerce*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001664#ifndef MPZ_CONVERSIONS_AS_METHODS
1665 UF mpz_int, /*nb_int*/
1666 UF mpz_long, /*nb_long*/
1667 UF mpz_float, /*nb_float*/
1668 UF mpz_oct, /*nb_oct*/
1669 UF mpz_hex, /*nb_hex*/
1670#endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1671};
1672
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001673static PyTypeObject MPZtype = {
1674 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001675 0, /*ob_size*/
1676 "mpz", /*tp_name*/
1677 sizeof(mpzobject), /*tp_size*/
1678 0, /*tp_itemsize*/
1679 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001680 (destructor)mpz_dealloc, /*tp_dealloc*/
1681 0, /*tp_print*/
1682 (getattrfunc)mpz_getattr, /*tp_getattr*/
1683 0, /*tp_setattr*/
1684 (cmpfunc)mpz_compare, /*tp_compare*/
1685 (reprfunc)mpz_repr, /*tp_repr*/
1686 &mpz_as_number, /*tp_as_number*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001687};
1688
1689/* List of functions exported by this module */
1690
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001691static PyMethodDef mpz_functions[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001692#if 0
1693 {initialiser_name, MPZ_mpz},
1694#else /* 0 */
Barry Warsawabb7efe1996-12-09 23:22:35 +00001695 /* until guido ``fixes'' struct PyMethodDef */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001696 {(char *)initialiser_name, MPZ_mpz},
1697#endif /* 0 else */
1698 {"powm", MPZ_powm},
1699 {"gcd", MPZ_gcd},
1700 {"gcdext", MPZ_gcdext},
1701 {"sqrt", MPZ_sqrt},
1702 {"sqrtrem", MPZ_sqrtrem},
1703 {"divm", MPZ_divm},
1704 {NULL, NULL} /* Sentinel */
1705};
1706
1707
1708/* #define MP_TEST_ALLOC */
1709
1710#ifdef MP_TEST_ALLOC
1711#define MP_TEST_SIZE 4
1712static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
1713static mp_test_error( location )
1714 int *location;
1715{
1716 /* assumptions: *alloc returns address dividable by 4,
1717 mpz_* routines allocate in chunks dividable by four */
1718 fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001719 Py_FatalError("MP_TEST_ERROR");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001720} /* static mp_test_error() */
1721#define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1722#define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1723#define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1724 ; \
1725 else \
1726 mp_test_error((int *)((char *)(basep) + size))
1727#else /* def MP_TEST_ALLOC */
1728#define MP_EXTRA_ALLOC(size) (size)
1729#define MP_SET_TEST(basep,size)
1730#define MP_DO_TEST(basep,size)
1731#endif /* def MP_TEST_ALLOC else */
1732
1733void *mp_allocate( alloc_size )
1734 size_t alloc_size;
1735{
1736 void *res;
1737
1738#ifdef MPZ_DEBUG
1739 fprintf(stderr, "mp_allocate : size %ld\n",
1740 alloc_size);
1741#endif /* def MPZ_DEBUG */
1742
1743 if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001744 Py_FatalError("mp_allocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001745
1746#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001747 fprintf(stderr, "mp_allocate : address %08p\n", res);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001748#endif /* def MPZ_DEBUG */
1749
1750 MP_SET_TEST(res,alloc_size);
1751
1752 return res;
1753} /* mp_allocate() */
1754
1755
1756void *mp_reallocate( ptr, old_size, new_size )
1757 void *ptr;
1758 size_t old_size;
1759 size_t new_size;
1760{
1761 void *res;
1762
1763#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001764 fprintf(stderr, "mp_reallocate: old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001765 ptr, old_size);
1766#endif /* def MPZ_DEBUG */
1767
1768 MP_DO_TEST(ptr, old_size);
1769
1770 if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001771 Py_FatalError("mp_reallocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001772
1773#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001774 fprintf(stderr, "mp_reallocate: new address %08p, new size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001775 res, new_size);
1776#endif /* def MPZ_DEBUG */
1777
1778 MP_SET_TEST(res, new_size);
1779
1780 return res;
1781} /* mp_reallocate() */
1782
1783
1784void mp_free( ptr, size )
1785 void *ptr;
1786 size_t size;
1787{
1788
1789#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001790 fprintf(stderr, "mp_free : old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001791 ptr, size);
1792#endif /* def MPZ_DEBUG */
1793
1794 MP_DO_TEST(ptr, size);
1795 free(ptr);
1796} /* mp_free() */
1797
1798
1799
1800/* Initialize this module. */
1801
Guido van Rossum3886bb61998-12-04 18:50:17 +00001802DL_EXPORT(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001803initmpz()
1804{
Fred Drakefcc6c681998-04-03 15:33:43 +00001805 PyObject *module;
1806 PyObject *dict;
1807
Guido van Rossum5f59d601992-12-14 16:59:51 +00001808#ifdef MPZ_DEBUG
1809 fputs( "initmpz() called...\n", stderr );
1810#endif /* def MPZ_DEBUG */
1811
1812 mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
Fred Drakefcc6c681998-04-03 15:33:43 +00001813 module = Py_InitModule("mpz", mpz_functions);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001814
1815 /* create some frequently used constants */
1816 if ((mpz_value_zero = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001817 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001818 mpz_set_ui(&mpz_value_zero->mpz, (unsigned long int)0);
1819
1820 if ((mpz_value_one = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001821 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001822 mpz_set_ui(&mpz_value_one->mpz, (unsigned long int)1);
1823
1824 if ((mpz_value_mone = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001825 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001826 mpz_set_si(&mpz_value_mone->mpz, (long)-1);
1827
Fred Drakefcc6c681998-04-03 15:33:43 +00001828 dict = PyModule_GetDict(module);
1829 if (dict != NULL) {
1830 PyDict_SetItemString(dict, "MPZType", (PyObject*)&MPZtype);
1831 }
1832
Guido van Rossum5f59d601992-12-14 16:59:51 +00001833} /* initmpz() */
1834#ifdef MAKEDUMMYINT
1835int _mpz_dummy_int; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1836#endif /* def MAKEDUMMYINT */