blob: d4882c258af6576b6c775bcd945c1c52fc67bb5c [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 *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000118mpz_format(PyObject *objp, int base, unsigned char withname)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000119{
120 mpzobject *mpzp = (mpzobject *)objp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000121 PyStringObject *strobjp;
Guido van Rossum2650a422000-06-28 21:29:47 +0000122 size_t i;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000123 int cmpres;
124 int taglong;
125 char *cp;
126 char prefix[5], *tcp;
127
128
129 tcp = &prefix[0];
130
131 if (mpzp == NULL || !is_mpzobject(mpzp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000132 PyErr_BadInternalCall();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000133 return NULL;
134 }
135
136 assert(base >= 2 && base <= 36);
137
138 if (withname)
139 i = strlen(initialiser_name) + 2; /* e.g. 'mpz(' + ')' */
140 else
141 i = 0;
142
143 if ((cmpres = mpz_cmp_si(&mpzp->mpz, 0L)) == 0)
144 base = 10; /* '0' in every base, right */
145 else if (cmpres < 0) {
146 *tcp++ = '-';
147 i += 1; /* space to hold '-' */
148 }
149
150#ifdef MPZ_DEBUG
151 fprintf(stderr, "mpz_format: mpz_sizeinbase %d\n",
152 (int)mpz_sizeinbase(&mpzp->mpz, base));
153#endif /* def MPZ_DEBUG */
154#ifdef MPZ_GET_STR_BUG
Guido van Rossum272841c1996-08-19 23:06:45 +0000155#ifdef GMP2
156 i += ((size_t) abs(mpzp->mpz._mp_size) * BITS_PER_MP_LIMB
157 * __mp_bases[base].chars_per_bit_exactly) + 1;
158#else
Guido van Rossum5f59d601992-12-14 16:59:51 +0000159 i += ((size_t) abs(mpzp->mpz.size) * BITS_PER_MP_LIMB
160 * __mp_bases[base].chars_per_bit_exactly) + 1;
Guido van Rossum272841c1996-08-19 23:06:45 +0000161#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +0000162#else /* def MPZ_GET_STR_BUG */
163 i += (int)mpz_sizeinbase(&mpzp->mpz, base);
164#endif /* def MPZ_GET_STR_BUG else */
165
166 if (base == 16) {
167 *tcp++ = '0';
168 *tcp++ = 'x';
169 i += 2; /* space to hold '0x' */
170 }
171 else if (base == 8) {
172 *tcp++ = '0';
173 i += 1; /* space to hold the extra '0' */
174 }
175 else if (base > 10) {
176 *tcp++ = '0' + base / 10;
177 *tcp++ = '0' + base % 10;
178 *tcp++ = '#';
179 i += 3; /* space to hold e.g. '12#' */
180 }
181 else if (base < 10) {
182 *tcp++ = '0' + base;
183 *tcp++ = '#';
184 i += 2; /* space to hold e.g. '6#' */
185 }
186
187 /*
188 ** the following code looks if we need a 'L' attached to the number
189 ** it will also attach an 'L' to the value -0x80000000
190 */
191 taglong = 0;
192 if (mpz_size(&mpzp->mpz) > 1
193 || (long)mpz_get_ui(&mpzp->mpz) < 0L) {
194 taglong = 1;
195 i += 1; /* space to hold 'L' */
196 }
197
198#ifdef MPZ_DEBUG
199 fprintf(stderr, "mpz_format: requesting string size %d\n", i);
200#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000201 if ((strobjp =
202 (PyStringObject *)PyString_FromStringAndSize((char *)0, i))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000203 == NULL)
204 return NULL;
205
206 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000207 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000208 if (withname) {
209 strcpy(cp, initialiser_name);
210 cp += strlen(initialiser_name);
211 *cp++ = '('; /*')'*/
212 }
213
214 /* copy the already prepared prefix; e.g. sign and base indicator */
215 *tcp = '\0';
216 strcpy(cp, prefix);
217 cp += tcp - prefix;
218
219 /* since' we have the sign already, let the lib think it's a positive
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000220 number */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000221 if (cmpres < 0)
222 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
223 (void)mpz_get_str(cp, base, &mpzp->mpz);
224 if (cmpres < 0)
225 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
226#ifdef MPZ_DEBUG
227 fprintf(stderr, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
228 base, cp);
229#endif /* def MPZ_DEBUG */
230 cp += strlen(cp);
231
232 if (taglong)
233 *cp++ = 'L';
234 if (withname)
235 *cp++ = /*'('*/ ')';
236
237 *cp = '\0';
238
239#ifdef MPZ_DEBUG
240 fprintf(stderr,
Fred Drakea44d3532000-06-30 15:01:00 +0000241 "mpz_format: cp (str end) %p, begin %p, diff %d, i %d\n",
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000242 cp, PyString_AS_STRING(strobjp),
243 cp - PyString_AS_STRING(strobjp), i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000244#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000245 assert(cp - PyString_AS_STRING(strobjp) <= i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000246
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000247 if (cp - PyString_AS_STRING(strobjp) != i) {
248 strobjp->ob_size -= i - (cp - PyString_AS_STRING(strobjp));
Guido van Rossum5f59d601992-12-14 16:59:51 +0000249 }
250
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000251 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000252} /* mpz_format() */
253
254/* MPZ methods */
255
256static void
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000257mpz_dealloc(mpzobject *mpzp)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000258{
259#ifdef MPZ_DEBUG
260 fputs( "mpz_dealloc() called...\n", stderr );
261#endif /* def MPZ_DEBUG */
262 mpz_clear(&mpzp->mpz);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000263 PyObject_Del(mpzp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000264} /* mpz_dealloc() */
265
Guido van Rossum5f59d601992-12-14 16:59:51 +0000266
267/* pointers to frequently used values 0, 1 and -1 */
268static mpzobject *mpz_value_zero, *mpz_value_one, *mpz_value_mone;
269
270static int
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000271mpz_compare(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000272{
273 int cmpres;
274
275
276 /* guido sez it's better to return -1, 0 or 1 */
277 return (cmpres = mpz_cmp( &a->mpz, &b->mpz )) == 0 ? 0
278 : cmpres > 0 ? 1 : -1;
279} /* mpz_compare() */
280
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000281static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000282mpz_addition(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000283{
284 mpzobject *z;
285
286
287#ifdef MPZ_SPARE_MALLOC
288 if (mpz_cmp_ui(&a->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000289 Py_INCREF(b);
290 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000291 }
292
293 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000294 Py_INCREF(a);
295 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000296 }
297#endif /* def MPZ_SPARE_MALLOC */
298
299 if ((z = newmpzobject()) == NULL)
300 return NULL;
301
302 mpz_add(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000303 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000304} /* mpz_addition() */
305
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000306static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000307mpz_substract(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000308{
309 mpzobject *z;
310
311
312#ifdef MPZ_SPARE_MALLOC
313 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000314 Py_INCREF(a);
315 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000316 }
317#endif /* MPZ_SPARE_MALLOC */
318
319 if ((z = newmpzobject()) == NULL)
320 return NULL;
321
322 mpz_sub(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000323 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000324} /* mpz_substract() */
325
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000326static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000327mpz_multiply(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000328{
329#ifdef MPZ_SPARE_MALLOC
330 int cmpres;
331#endif /* def MPZ_SPARE_MALLOC */
332 mpzobject *z;
333
334
335#ifdef MPZ_SPARE_MALLOC
336 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000337 Py_INCREF(mpz_value_zero);
338 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000339 }
340 if (cmpres > 0 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000341 Py_INCREF(b);
342 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000343 }
344
345 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long_int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000346 Py_INCREF(mpz_value_zero);
347 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000348 }
349 if (cmpres > 0 && mpz_cmp_ui(&b->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000350 Py_INCREF(a);
351 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000352 }
353#endif /* MPZ_SPARE_MALLOC */
354
355 if ((z = newmpzobject()) == NULL)
356 return NULL;
357
358 mpz_mul( &z->mpz, &a->mpz, &b->mpz );
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000359 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000360
361} /* mpz_multiply() */
362
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000363static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000364mpz_divide(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000365{
366#ifdef MPZ_SPARE_MALLOC
367 int cmpres;
368#endif /* def MPZ_SPARE_MALLOC */
369 mpzobject *z;
370
371
372 if ((
373#ifdef MPZ_SPARE_MALLOC
374 cmpres =
375#endif /* def MPZ_SPARE_MALLOC */
376 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000377 PyErr_SetString(PyExc_ZeroDivisionError, "mpz./ by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000378 return NULL;
379 }
380#ifdef MPZ_SPARE_MALLOC
381 if (cmpres > 0 && mpz_cmp_ui(&b->mpz(unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000382 Py_INCREF(a);
383 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000384 }
385#endif /* def MPZ_SPARE_MALLOC */
386
387 if ((z = newmpzobject()) == NULL)
388 return NULL;
389
390#ifdef MPZ_TEST_DIV
391 fputs("mpz_divide: div result", stderr);
392 mpz_div(&z->mpz, &a->mpz, &b->mpz);
393 mpz_out_str(stderr, 10, &z->mpz);
394 putc('\n', stderr);
395#endif /* def MPZ_TEST_DIV */
396#ifdef MPZ_MDIV_BUG
397 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
398 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)) {
399 /*
400 ** numerator has other sign than denominator: we have
401 ** to look at the remainder for a correction, since mpz_mdiv
402 ** also calls mpz_divmod, I can as well do it myself
403 */
404 MP_INT tmpmpz;
405
406
407 mpz_init(&tmpmpz);
408 mpz_divmod(&z->mpz, &tmpmpz, &a->mpz, &b->mpz);
409
410 if (mpz_cmp_ui(&tmpmpz, (unsigned long int)0) != 0)
411 mpz_sub_ui(&z->mpz, &z->mpz, (unsigned long int)1);
412
413 mpz_clear(&tmpmpz);
414 }
415 else
416 mpz_div(&z->mpz, &a->mpz, &b->mpz);
417 /* the ``naive'' implementation does it right for operands
418 having the same sign */
419
420#else /* def MPZ_MDIV_BUG */
421 mpz_mdiv(&z->mpz, &a->mpz, &b->mpz);
422#endif /* def MPZ_MDIV_BUG else */
423#ifdef MPZ_TEST_DIV
424 fputs("mpz_divide: mdiv result", stderr);
425 mpz_out_str(stderr, 10, &z->mpz);
426 putc('\n', stderr);
427#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000428 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000429
430} /* mpz_divide() */
431
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000432static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000433mpz_remainder(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000434{
435#ifdef MPZ_SPARE_MALLOC
436 int cmpres;
437#endif /* def MPZ_SPARE_MALLOC */
438 mpzobject *z;
439
440
441 if ((
442#ifdef MPZ_SPARE_MALLOC
443 cmpres =
444#endif /* def MPZ_SPARE_MALLOC */
445 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000446 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.% by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000447 return NULL;
448 }
449#ifdef MPZ_SPARE_MALLOC
450 if (cmpres > 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000451 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)2)) == 0)
452 {
453 Py_INCREF(mpz_value_one);
454 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000455 }
456 if (cmpres < 0) {
457 /* b must be 1 now */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000458 Py_INCREF(mpz_value_zero);
459 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000460 }
461 }
462#endif /* def MPZ_SPARE_MALLOC */
463
464 if ((z = newmpzobject()) == NULL)
465 return NULL;
466
467#ifdef MPZ_TEST_DIV
468 fputs("mpz_remain: mod result", stderr);
469 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
470 mpz_out_str(stderr, 10, &z->mpz);
471 putc('\n', stderr);
472#endif /* def MPZ_TEST_DIV */
473#ifdef MPZ_MDIV_BUG
474
475 /* the ``naive'' implementation does it right for operands
476 having the same sign */
477 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
478
479 /* assumption: z, a and b all point to different locations */
480 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
481 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
482 && mpz_cmp_ui(&z->mpz, (unsigned long int)0) != 0)
483 mpz_add(&z->mpz, &z->mpz, &b->mpz);
484 /*
485 ** numerator has other sign than denominator: we have
486 ** to look at the remainder for a correction, since mpz_mdiv
487 ** also calls mpz_divmod, I can as well do it myself
488 */
489#else /* def MPZ_MDIV_BUG */
490 mpz_mmod(&z->mpz, &a->mpz, &b->mpz);
491#endif /* def MPZ_MDIV_BUG else */
492#ifdef MPZ_TEST_DIV
493 fputs("mpz_remain: mmod result", stderr);
494 mpz_out_str(stderr, 10, &z->mpz);
495 putc('\n', stderr);
496#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000497 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000498
499} /* mpz_remainder() */
500
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000501static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000502mpz_div_and_mod(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000503{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000504 PyObject *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000505 mpzobject *x = NULL, *y = NULL;
506
507
508 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000509 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.divmod by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000510 return NULL;
511 }
512
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000513 if ((z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +0000514 || (x = newmpzobject()) == NULL
515 || (y = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000516 Py_XDECREF(z);
517 Py_XDECREF(x);
518 Py_XDECREF(y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000519 return NULL;
520 }
521
522#ifdef MPZ_TEST_DIV
523 fputs("mpz_divmod: dm result", stderr);
524 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
525 mpz_out_str(stderr, 10, &x->mpz);
526 putc('\n', stderr);
527 mpz_out_str(stderr, 10, &y->mpz);
528 putc('\n', stderr);
529#endif /* def MPZ_TEST_DIV */
530#ifdef MPZ_MDIV_BUG
531 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
532 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
533 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
534 && mpz_cmp_ui(&y->mpz, (unsigned long int)0) != 0) {
535 /*
536 ** numerator has other sign than denominator: we have
537 ** to look at the remainder for a correction.
538 */
539 mpz_add(&y->mpz, &y->mpz, &b->mpz);
540 mpz_sub_ui(&x->mpz, &x->mpz, (unsigned long int)1);
541 }
542#else /* def MPZ_MDIV_BUG */
543 mpz_mdivmod( &x->mpz, &y->mpz, &a->mpz, &b->mpz );
544#endif /* def MPZ_MDIV_BUG else */
545#ifdef MPZ_TEST_DIV
546 fputs("mpz_divmod: mdm result", stderr);
547 mpz_out_str(stderr, 10, &x->mpz);
548 putc('\n', stderr);
549 mpz_out_str(stderr, 10, &y->mpz);
550 putc('\n', stderr);
551#endif /* def MPZ_TEST_DIV */
552
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000553 (void)PyTuple_SetItem(z, 0, (PyObject *)x);
554 (void)PyTuple_SetItem(z, 1, (PyObject *)y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000555
556 return z;
557} /* mpz_div_and_mod() */
558
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000559static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000560mpz_power(mpzobject *a, mpzobject *b, mpzobject *m)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000561{
562 mpzobject *z;
563 int cmpres;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000564
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000565 if ((PyObject *)m != Py_None) {
566 mpzobject *z2;
567 Py_INCREF(Py_None);
568 z=(mpzobject *)mpz_power(a, b, (mpzobject *)Py_None);
569 Py_DECREF(Py_None);
570 if (z==NULL) return((PyObject *)z);
571 z2=(mpzobject *)mpz_remainder(z, m);
572 Py_DECREF(z);
573 return((PyObject *)z2);
574 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000575
576 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
577 /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
578
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000579 Py_INCREF(mpz_value_one);
580 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000581 }
582
583 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000584 PyErr_SetString(PyExc_ValueError,
585 "mpz.pow to negative exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000586 return NULL;
587 }
588
589 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
590 /* the base is 0 */
591
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000592 Py_INCREF(mpz_value_zero);
593 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000594 }
595 else if (cmpres > 0
596 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
597 /* the base is 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 else if (cmpres < 0
603 && mpz_cmp_si(&a->mpz, (long int)-1) == 0) {
604
605 MP_INT tmpmpz;
606 /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
607 /* XXX this code needs to be optimized: what's better?
608 mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
609 for *un*obvious reasons */
610
611 /* is the exponent even? */
612 mpz_init(&tmpmpz);
613
614 /* look to the remainder after a division by (1 << 1) */
615 mpz_mod_2exp(&tmpmpz, &b->mpz, (unsigned long int)1);
616
617 if (mpz_cmp_ui(&tmpmpz, (unsigned int)0) == 0) {
618 mpz_clear(&tmpmpz);
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 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000623 Py_INCREF(mpz_value_mone);
624 return (PyObject *)mpz_value_mone;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000625 }
626
627#ifdef MPZ_LIB_DOES_CHECKING
628 /* check if it's doable: sizeof(exp) > sizeof(long) &&
629 abs(base) > 1 ?? --> No Way */
630 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000631 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000632#else /* def MPZ_LIB_DOES_CHECKING */
633 /* wet finger method */
634 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000635 PyErr_SetString(PyExc_ValueError,
636 "mpz.pow outrageous exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000637 return NULL;
638 }
639#endif /* def MPZ_LIB_DOES_CHECKING else */
640
641 if ((z = newmpzobject()) == NULL)
642 return NULL;
643
644 mpz_pow_ui(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
645
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000646 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000647} /* mpz_power() */
648
649
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000650static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000651mpz_negative(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000652{
653 mpzobject *z;
654
655
656#ifdef MPZ_SPARE_MALLOC
657 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) == 0) {
658 /* -0 == 0 */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000659 Py_INCREF(v);
660 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000661 }
662#endif /* def MPZ_SPARE_MALLOC */
663
664 if ((z = newmpzobject()) == NULL)
665 return NULL;
666
667 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000668 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000669} /* mpz_negative() */
670
671
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000672static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000673mpz_positive(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000674{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000675 Py_INCREF(v);
676 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000677} /* mpz_positive() */
678
679
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000680static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000681mpz_absolute(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000682{
683 mpzobject *z;
684
685
686 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000687 Py_INCREF(v);
688 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000689 }
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_absolute() */
697
698static int
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000699mpz_nonzero(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000700{
701 return mpz_cmp_ui(&v->mpz, (unsigned long int)0) != 0;
702} /* mpz_nonzero() */
703
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000704static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000705py_mpz_invert(mpzobject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000706{
707 mpzobject *z;
708
709
710 /* I think mpz_com does exactly what needed */
711 if ((z = newmpzobject()) == NULL)
712 return NULL;
713
714 mpz_com(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000715 return (PyObject *)z;
Guido van Rossum272841c1996-08-19 23:06:45 +0000716} /* py_mpz_invert() */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000717
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000718static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000719mpz_lshift(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000720{
721 int cmpres;
722 mpzobject *z;
723
724
725 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
726 /* a << 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000727 Py_INCREF(a);
728 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000729 }
730
731 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000732 PyErr_SetString(PyExc_ValueError,
733 "mpz.<< negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000734 return NULL;
735 }
736
737#ifdef MPZ_LIB_DOES_CHECKING
738 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000739 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000740#else /* def MPZ_LIB_DOES_CHECKING */
741 /* wet finger method */
742 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000743 PyErr_SetString(PyExc_ValueError,
744 "mpz.<< outrageous shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000745 return NULL;
746 }
747#endif /* def MPZ_LIB_DOES_CHECKING else */
748
749 if ((z = newmpzobject()) == NULL)
750 return NULL;
751
752 mpz_mul_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000753 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000754} /* mpz_lshift() */
755
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000756static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000757mpz_rshift(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000758{
759 int cmpres;
760 mpzobject *z;
761
762
763 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
764 /* a >> 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000765 Py_INCREF(a);
766 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000767 }
768
769 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000770 PyErr_SetString(PyExc_ValueError,
771 "mpz.>> negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000772 return NULL;
773 }
774
775 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000776 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000777
778 if ((z = newmpzobject()) == NULL)
779 return NULL;
780
781 mpz_div_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000782 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000783} /* mpz_rshift() */
784
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000785static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000786mpz_andfunc(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000787{
788 mpzobject *z;
789
790
791 if ((z = newmpzobject()) == NULL)
792 return NULL;
793
794 mpz_and(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000795 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000796} /* mpz_andfunc() */
797
798/* hack Hack HAck HACk HACK, XXX this code is dead slow */
799void
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000800mpz_xor(MP_INT *res, const MP_INT *op1, const MP_INT *op2)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000801{
802 MP_INT tmpmpz;
803
804 mpz_init(&tmpmpz);
805
806 mpz_and(res, op1, op2);
807 mpz_com(&tmpmpz, res);
808 mpz_ior(res, op1, op2);
809 mpz_and(res, res, &tmpmpz);
810
811 mpz_clear(&tmpmpz);
812} /* mpz_xor() HACK */
813
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000814static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000815mpz_xorfunc(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000816{
817 mpzobject *z;
818
819
820 if ((z = newmpzobject()) == NULL)
821 return NULL;
822
823 mpz_xor(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000824 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000825} /* mpz_xorfunc() */
826
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000827static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000828mpz_orfunc(mpzobject *a, mpzobject *b)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000829{
830 mpzobject *z;
831
832
833 if ((z = newmpzobject()) == NULL)
834 return NULL;
835
836 mpz_ior(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000837 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000838} /* mpz_orfunc() */
839
840/* MPZ initialisation */
841
842#include "longintrepr.h"
843
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000844static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000845MPZ_mpz(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000846{
847 mpzobject *mpzp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000848 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000849
850
851#ifdef MPZ_DEBUG
852 fputs("MPZ_mpz() called...\n", stderr);
853#endif /* def MPZ_DEBUG */
854
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000855 if (!PyArg_Parse(args, "O", &objp))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000856 return NULL;
857
858 /* at least we know it's some object */
Barry Warsawabb7efe1996-12-09 23:22:35 +0000859 /* note DON't Py_DECREF args NEITHER objp */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000860
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000861 if (PyInt_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000862 long lval;
863
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000864 if (!PyArg_Parse(objp, "l", &lval))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000865 return NULL;
866
867 if (lval == (long)0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000868 Py_INCREF(mpz_value_zero);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000869 mpzp = mpz_value_zero;
870 }
871 else if (lval == (long)1) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000872 Py_INCREF(mpz_value_one);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000873 mpzp = mpz_value_one;
874 }
875 else if ((mpzp = newmpzobject()) == NULL)
876 return NULL;
877 else mpz_set_si(&mpzp->mpz, lval);
878 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000879 else if (PyLong_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000880 MP_INT mplongdigit;
881 int i;
882 unsigned char isnegative;
883
884
885 if ((mpzp = newmpzobject()) == NULL)
886 return NULL;
887
888 mpz_set_si(&mpzp->mpz, 0L);
889 mpz_init(&mplongdigit);
890
891 /* how we're gonna handle this? */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000892 if ((isnegative =
893 ((i = ((PyLongObject *)objp)->ob_size) < 0) ))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000894 i = -i;
895
896 while (i--) {
897 mpz_set_ui(&mplongdigit,
898 (unsigned long)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000899 ((PyLongObject *)objp)->ob_digit[i]);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000900 mpz_mul_2exp(&mplongdigit,&mplongdigit,
901 (unsigned long int)i * SHIFT);
902 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
903 }
904
905 if (isnegative)
906 mpz_neg(&mpzp->mpz, &mpzp->mpz);
907
908 /* get rid of allocation for tmp variable */
909 mpz_clear(&mplongdigit);
910 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000911 else if (PyString_Check(objp)) {
Andrew M. Kuchling4c07f811998-12-14 19:36:14 +0000912 unsigned char *cp = (unsigned char *)PyString_AS_STRING(objp);
Guido van Rossum7e488981998-10-08 02:25:24 +0000913 int len = PyString_GET_SIZE(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000914 MP_INT mplongdigit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000915
916 if ((mpzp = newmpzobject()) == NULL)
917 return NULL;
918
919 mpz_set_si(&mpzp->mpz, 0L);
920 mpz_init(&mplongdigit);
921
922 /* let's do it the same way as with the long conversion:
923 without thinking how it can be faster (-: :-) */
924
925 cp += len;
926 while (len--) {
927 mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
928 mpz_mul_2exp(&mplongdigit,&mplongdigit,
929 (unsigned long int)len * 8);
930 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
931 }
932
933 /* get rid of allocation for tmp variable */
934 mpz_clear(&mplongdigit);
935 }
936 else if (is_mpzobject(objp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000937 Py_INCREF(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000938 mpzp = (mpzobject *)objp;
939 }
940 else {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000941 PyErr_SetString(PyExc_TypeError,
942"mpz.mpz() expects integer, long, string or mpz object argument");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000943 return NULL;
944 }
945
946
947#ifdef MPZ_DEBUG
948 fputs("MPZ_mpz: created mpz=", stderr);
949 mpz_out_str(stderr, 10, &mpzp->mpz);
950 putc('\n', stderr);
951#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000952 return (PyObject *)mpzp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000953} /* MPZ_mpz() */
954
955static mpzobject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000956mpz_mpzcoerce(PyObject *z)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000957{
958 /* shortcut: 9 out of 10 times the type is already ok */
959 if (is_mpzobject(z)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000960 Py_INCREF(z);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000961 return (mpzobject *)z; /* coercion succeeded */
962 }
963
964 /* what types do we accept?: intobjects and longobjects */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000965 if (PyInt_Check(z) || PyLong_Check(z))
966 return (mpzobject *)MPZ_mpz((PyObject *)NULL, z);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000967
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000968 PyErr_SetString(PyExc_TypeError,
969 "number coercion (to mpzobject) failed");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000970 return NULL;
971} /* mpz_mpzcoerce() */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000972
973/* Forward */
Tim Petersdbd9ba62000-07-09 03:09:57 +0000974static void mpz_divm(MP_INT *res, const MP_INT *num,
975 const MP_INT *den, const MP_INT *mod);
Guido van Rossum67a5fdb1993-12-17 12:09:14 +0000976
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000977static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +0000978MPZ_powm(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000979{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000980 PyObject *base, *exp, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000981 mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
982 mpzobject *z;
983 int tstres;
984
985
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000986 if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000987 return NULL;
988
989 if ((mpzbase = mpz_mpzcoerce(base)) == NULL
990 || (mpzexp = mpz_mpzcoerce(exp)) == NULL
991 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
992 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000993 Py_XDECREF(mpzbase);
994 Py_XDECREF(mpzexp);
995 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000996 return NULL;
997 }
998
999 if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001000 Py_INCREF(mpz_value_one);
1001 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001002 }
1003
1004 if (tstres < 0) {
1005 MP_INT absexp;
1006 /* negative exp */
1007
1008 mpz_init_set(&absexp, &mpzexp->mpz);
1009 mpz_abs(&absexp, &absexp);
1010 mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
1011
1012 mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
1013
1014 mpz_clear(&absexp);
1015 }
1016 else {
1017 mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
1018 }
1019
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001020 Py_DECREF(mpzbase);
1021 Py_DECREF(mpzexp);
1022 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001023
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001024 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001025} /* MPZ_powm() */
1026
1027
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001028static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001029MPZ_gcd(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001030{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001031 PyObject *op1, *op2;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001032 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1033 mpzobject *z;
1034
1035
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001036 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001037 return NULL;
1038
1039 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1040 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
1041 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001042 Py_XDECREF(mpzop1);
1043 Py_XDECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001044 return NULL;
1045 }
1046
1047 /* ok, we have three mpzobjects, and an initialised result holder */
1048 mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
1049
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001050 Py_DECREF(mpzop1);
1051 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001052
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001053 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001054} /* MPZ_gcd() */
1055
1056
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001057static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001058MPZ_gcdext(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001059{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001060 PyObject *op1, *op2, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001061 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1062 mpzobject *g = NULL, *s = NULL, *t = NULL;
1063
1064
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001065 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001066 return NULL;
1067
1068 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1069 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001070 || (z = PyTuple_New(3)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001071 || (g = newmpzobject()) == NULL
1072 || (s = newmpzobject()) == NULL
1073 || (t = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001074 Py_XDECREF(mpzop1);
1075 Py_XDECREF(mpzop2);
1076 Py_XDECREF(z);
1077 Py_XDECREF(g);
1078 Py_XDECREF(s);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001079 /*Py_XDECREF(t);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001080 return NULL;
1081 }
1082
1083 mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
1084
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001085 Py_DECREF(mpzop1);
1086 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001087
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001088 (void)PyTuple_SetItem(z, 0, (PyObject *)g);
1089 (void)PyTuple_SetItem(z, 1, (PyObject *)s);
1090 (void)PyTuple_SetItem(z, 2, (PyObject *)t);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001091
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001092 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001093} /* MPZ_gcdext() */
1094
1095
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001096static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001097MPZ_sqrt(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001098{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001099 PyObject *op;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001100 mpzobject *mpzop = NULL;
1101 mpzobject *z;
1102
1103
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001104 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001105 return NULL;
1106
1107 if ((mpzop = mpz_mpzcoerce(op)) == NULL
1108 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001109 Py_XDECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001110 return NULL;
1111 }
1112
1113 mpz_sqrt(&z->mpz, &mpzop->mpz);
1114
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001115 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001116
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001117 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001118} /* MPZ_sqrt() */
1119
1120
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001121static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001122MPZ_sqrtrem(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001123{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001124 PyObject *op, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001125 mpzobject *mpzop = NULL;
1126 mpzobject *root = NULL, *rem = NULL;
1127
1128
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001129 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001130 return NULL;
1131
1132 if ((mpzop = mpz_mpzcoerce(op)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001133 || (z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001134 || (root = newmpzobject()) == NULL
1135 || (rem = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001136 Py_XDECREF(mpzop);
1137 Py_XDECREF(z);
1138 Py_XDECREF(root);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001139 /*Py_XDECREF(rem);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001140 return NULL;
1141 }
1142
1143 mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
1144
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001145 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001146
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001147 (void)PyTuple_SetItem(z, 0, (PyObject *)root);
1148 (void)PyTuple_SetItem(z, 1, (PyObject *)rem);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001149
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001150 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001151} /* MPZ_sqrtrem() */
1152
1153
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001154static void
Guido van Rossum5f59d601992-12-14 16:59:51 +00001155mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001156{
1157 MP_INT s0, s1, q, r, x, d0, d1;
1158
1159 mpz_init_set(&s0, num);
1160 mpz_init_set_ui(&s1, 0);
1161 mpz_init(&q);
1162 mpz_init(&r);
1163 mpz_init(&x);
1164 mpz_init_set(&d0, den);
1165 mpz_init_set(&d1, mod);
1166
Guido van Rossum272841c1996-08-19 23:06:45 +00001167#ifdef GMP2
1168 while (d1._mp_size != 0) {
1169#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001170 while (d1.size != 0) {
Guido van Rossum272841c1996-08-19 23:06:45 +00001171#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001172 mpz_divmod(&q, &r, &d0, &d1);
1173 mpz_set(&d0, &d1);
1174 mpz_set(&d1, &r);
1175
1176 mpz_mul(&x, &s1, &q);
1177 mpz_sub(&x, &s0, &x);
1178 mpz_set(&s0, &s1);
1179 mpz_set(&s1, &x);
1180 }
1181
Guido van Rossum272841c1996-08-19 23:06:45 +00001182#ifdef GMP2
1183 if (d0._mp_size != 1 || d0._mp_d[0] != 1)
1184 res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
1185#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001186 if (d0.size != 1 || d0.d[0] != 1)
1187 res->size = 0; /* trouble: the gcd != 1; set s to zero */
Guido van Rossum272841c1996-08-19 23:06:45 +00001188#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001189 else {
1190#ifdef MPZ_MDIV_BUG
1191 /* watch out here! first check the signs, and then perform
1192 the mpz_mod() since mod could point to res */
1193 if ((s0.size < 0) != (mod->size < 0)) {
1194 mpz_mod(res, &s0, mod);
1195
1196 if (res->size)
1197 mpz_add(res, res, mod);
1198 }
1199 else
1200 mpz_mod(res, &s0, mod);
1201
1202#else /* def MPZ_MDIV_BUG */
1203 mpz_mmod(res, &s0, mod);
1204#endif /* def MPZ_MDIV_BUG else */
1205 }
1206
1207 mpz_clear(&s0);
1208 mpz_clear(&s1);
1209 mpz_clear(&q);
1210 mpz_clear(&r);
1211 mpz_clear(&x);
1212 mpz_clear(&d0);
1213 mpz_clear(&d1);
1214} /* mpz_divm() */
1215
1216
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001217static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001218MPZ_divm(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001219{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001220 PyObject *num, *den, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001221 mpzobject *mpznum, *mpzden, *mpzmod = NULL;
1222 mpzobject *z = NULL;
1223
1224
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001225 if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001226 return NULL;
1227
1228 if ((mpznum = mpz_mpzcoerce(num)) == NULL
1229 || (mpzden = mpz_mpzcoerce(den)) == NULL
1230 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1231 || (z = newmpzobject()) == NULL ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001232 Py_XDECREF(mpznum);
1233 Py_XDECREF(mpzden);
1234 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001235 return NULL;
1236 }
1237
1238 mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
1239
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001240 Py_DECREF(mpznum);
1241 Py_DECREF(mpzden);
1242 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001243
1244 if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001245 Py_DECREF(z);
1246 PyErr_SetString(PyExc_ValueError,
1247 "gcd(den, mod) != 1 or num == 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001248 return NULL;
1249 }
1250
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001251 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001252} /* MPZ_divm() */
1253
1254
1255/* MPZ methods-as-attributes */
1256#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001257static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001258mpz_int(mpzobject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001259#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001260static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001261mpz_int(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001262#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1263{
1264 long sli;
1265
1266
1267#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001268 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001269 return NULL;
1270#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1271
1272 if (mpz_size(&self->mpz) > 1
1273 || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001274 PyErr_SetString(PyExc_ValueError,
1275 "mpz.int() arg too long to convert");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001276 return NULL;
1277 }
1278
1279 if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
1280 sli = -sli;
1281
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001282 return PyInt_FromLong(sli);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001283} /* mpz_int() */
1284
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001285static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001286#ifdef MPZ_CONVERSIONS_AS_METHODS
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001287mpz_long(mpzobject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001288#else /* def MPZ_CONVERSIONS_AS_METHODS */
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001289mpz_long(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001290#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1291{
1292 int i, isnegative;
1293 unsigned long int uli;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001294 PyLongObject *longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001295 int ldcount;
1296 int bitpointer, newbitpointer;
1297 MP_INT mpzscratch;
1298
1299
1300#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001301 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001302 return NULL;
1303#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1304
1305 /* determine length of python-long to be allocated */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001306 if ((longobjp = _PyLong_New(i = (int)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001307 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
1308 + SHIFT - 1) /
1309 SHIFT))) == NULL)
1310 return NULL;
1311
1312 /* determine sign, and copy self to scratch var */
1313 mpz_init_set(&mpzscratch, &self->mpz);
Guido van Rossum272841c1996-08-19 23:06:45 +00001314 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001315 mpz_neg(&mpzscratch, &mpzscratch);
1316
1317 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001318 e.g. dismantle mpzscratch, build PyLongObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001319
1320 bitpointer = 0; /* the number of valid bits in stock */
1321 newbitpointer = 0;
1322 ldcount = 0; /* the python-long limb counter */
1323 uli = (unsigned long int)0;
1324 while (i--) {
1325 longobjp->ob_digit[ldcount] = uli & MASK;
1326
1327 /* check if we've had enough bits for this digit */
1328 if (bitpointer < SHIFT) {
1329 uli = mpz_get_ui(&mpzscratch);
1330 longobjp->ob_digit[ldcount] |=
1331 (uli << bitpointer) & MASK;
1332 uli >>= SHIFT-bitpointer;
1333 bitpointer += BITS_PER_MP_LIMB;
1334 mpz_div_2exp(&mpzscratch, &mpzscratch,
1335 BITS_PER_MP_LIMB);
1336 }
1337 else
1338 uli >>= SHIFT;
1339 bitpointer -= SHIFT;
1340 ldcount++;
1341 }
1342
1343 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1344 mpz_clear(&mpzscratch);
1345 assert(ldcount <= longobjp->ob_size);
1346
1347 /* long_normalize() is file-static */
1348 /* longobjp = long_normalize(longobjp); */
1349 while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
1350 ldcount--;
1351 longobjp->ob_size = ldcount;
1352
1353
1354 if (isnegative)
1355 longobjp->ob_size = -longobjp->ob_size;
1356
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001357 return (PyObject *)longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001358
1359} /* mpz_long() */
1360
1361
1362/* I would have avoided pow() anyways, so ... */
1363static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
1364
1365#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001366static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001367mpz_float(mpzobject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001368#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001369static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001370mpz_float(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001371#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1372{
1373 int i, isnegative;
1374 double x;
1375 double mulstate;
1376 MP_INT mpzscratch;
1377
1378
1379#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001380 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001381 return NULL;
1382#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1383
1384 i = (int)mpz_size(&self->mpz);
1385
1386 /* determine sign, and copy abs(self) to scratch var */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001387 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
1388 {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001389 mpz_init(&mpzscratch);
1390 mpz_neg(&mpzscratch, &self->mpz);
1391 }
1392 else
1393 mpz_init_set(&mpzscratch, &self->mpz);
1394
1395 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001396 e.g. dismantle mpzscratch, build PyFloatObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001397
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001398 /* Can this overflow? Dunno, protect against that possibility. */
1399 PyFPE_START_PROTECT("mpz_float", return 0)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001400 x = 0.0;
1401 mulstate = 1.0;
1402 while (i--) {
1403 x += mulstate * mpz_get_ui(&mpzscratch);
1404 mulstate *= multiplier;
1405 mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
1406 }
Guido van Rossum45b83911997-03-14 04:32:50 +00001407 PyFPE_END_PROTECT(mulstate)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001408
1409 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1410 mpz_clear(&mpzscratch);
1411
1412 if (isnegative)
1413 x = -x;
1414
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001415 return PyFloat_FromDouble(x);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001416
1417} /* mpz_float() */
1418
1419#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001420static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001421mpz_hex(mpzobject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001422#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001423static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001424mpz_hex(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001425#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1426{
1427#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001428 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001429 return NULL;
1430#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1431
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001432 return mpz_format((PyObject *)self, 16, (unsigned char)1);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001433} /* mpz_hex() */
1434
1435#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001436static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001437mpz_oct(mpzobject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001438#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001439static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001440mpz_oct(mpzobject *self)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001441#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1442{
1443#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001444 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001445 return NULL;
1446#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1447
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001448 return mpz_format((PyObject *)self, 8, (unsigned char)1);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001449} /* mpz_oct() */
1450
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001451static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001452mpz_binary(mpzobject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001453{
1454 int size;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001455 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001456 char *cp;
1457 MP_INT mp;
1458 unsigned long ldigit;
1459
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001460 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001461 return NULL;
1462
1463 if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001464 PyErr_SetString(PyExc_ValueError,
1465 "mpz.binary() arg must be >= 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001466 return NULL;
1467 }
1468
1469 mpz_init_set(&mp, &self->mpz);
1470 size = (int)mpz_size(&mp);
1471
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001472 if ((strobjp = (PyStringObject *)
1473 PyString_FromStringAndSize(
1474 (char *)0, size * sizeof (unsigned long int))) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001475 return NULL;
1476
1477 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001478 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001479
1480 /* this has been programmed using a (fairly) decent lib-i/f it could
1481 be must faster if we looked into the GMP lib */
1482 while (size--) {
1483 ldigit = mpz_get_ui(&mp);
1484 mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
1485 *cp++ = (unsigned char)(ldigit & 0xFF);
1486 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1487 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1488 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1489 }
1490
1491 while (strobjp->ob_size && !*--cp)
1492 strobjp->ob_size--;
1493
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001494 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001495} /* mpz_binary() */
1496
1497
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001498static PyMethodDef mpz_methods[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001499#ifdef MPZ_CONVERSIONS_AS_METHODS
1500 {"int", mpz_int},
1501 {"long", mpz_long},
1502 {"float", mpz_float},
1503 {"hex", mpz_hex},
1504 {"oct", mpz_oct},
1505#endif /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001506 {"binary", (PyCFunction)mpz_binary},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001507 {NULL, NULL} /* sentinel */
1508};
1509
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001510static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001511mpz_getattr(mpzobject *self, char *name)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001512{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001513 return Py_FindMethod(mpz_methods, (PyObject *)self, name);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001514} /* mpz_getattr() */
1515
1516
1517static int
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001518mpz_coerce(PyObject **pv, PyObject **pw)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001519{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001520 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001521
1522#ifdef MPZ_DEBUG
1523 fputs("mpz_coerce() called...\n", stderr);
1524#endif /* def MPZ_DEBUG */
1525
1526 assert(is_mpzobject(*pv));
1527
1528 /* always convert other arg to mpz value, except for floats */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001529 if (!PyFloat_Check(*pw)) {
1530 if ((z = (PyObject *)mpz_mpzcoerce(*pw)) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001531 return -1; /* -1: an error always has been set */
1532
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001533 Py_INCREF(*pv);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001534 *pw = z;
1535 }
1536 else {
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001537#ifdef MPZ_CONVERSIONS_AS_METHODS
1538 if ((z = mpz_float((mpzobject *)(*pv), NULL)) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001539 return -1;
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001540#else /* def MPZ_CONVERSIONS_AS_METHODS */
1541 if ((z = mpz_float((mpzobject *)(*pv))) == NULL)
1542 return -1;
1543#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001544
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001545 Py_INCREF(*pw);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001546 *pv = z;
1547 }
1548 return 0; /* coercion succeeded */
1549
1550} /* mpz_coerce() */
1551
1552
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001553static PyObject *
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001554mpz_repr(PyObject *v)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001555{
1556 return mpz_format(v, 10, (unsigned char)1);
1557} /* mpz_repr() */
1558
1559
1560
Guido van Rossumb6775db1994-08-01 11:34:53 +00001561#define UF (unaryfunc)
1562#define BF (binaryfunc)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001563#define TF (ternaryfunc)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001564#define IF (inquiry)
1565#define CF (coercion)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001566
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001567static PyNumberMethods mpz_as_number = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001568 BF mpz_addition, /*nb_add*/
1569 BF mpz_substract, /*nb_subtract*/
1570 BF mpz_multiply, /*nb_multiply*/
1571 BF mpz_divide, /*nb_divide*/
1572 BF mpz_remainder, /*nb_remainder*/
1573 BF mpz_div_and_mod, /*nb_divmod*/
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001574 TF mpz_power, /*nb_power*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001575 UF mpz_negative, /*nb_negative*/
1576 UF mpz_positive, /*tp_positive*/
1577 UF mpz_absolute, /*tp_absolute*/
1578 IF mpz_nonzero, /*tp_nonzero*/
Guido van Rossum272841c1996-08-19 23:06:45 +00001579 UF py_mpz_invert, /*nb_invert*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001580 BF mpz_lshift, /*nb_lshift*/
1581 BF mpz_rshift, /*nb_rshift*/
1582 BF mpz_andfunc, /*nb_and*/
1583 BF mpz_xorfunc, /*nb_xor*/
1584 BF mpz_orfunc, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001585 CF mpz_coerce, /*nb_coerce*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001586#ifndef MPZ_CONVERSIONS_AS_METHODS
1587 UF mpz_int, /*nb_int*/
1588 UF mpz_long, /*nb_long*/
1589 UF mpz_float, /*nb_float*/
1590 UF mpz_oct, /*nb_oct*/
1591 UF mpz_hex, /*nb_hex*/
1592#endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1593};
1594
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001595static PyTypeObject MPZtype = {
1596 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001597 0, /*ob_size*/
1598 "mpz", /*tp_name*/
1599 sizeof(mpzobject), /*tp_size*/
1600 0, /*tp_itemsize*/
1601 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001602 (destructor)mpz_dealloc, /*tp_dealloc*/
1603 0, /*tp_print*/
1604 (getattrfunc)mpz_getattr, /*tp_getattr*/
1605 0, /*tp_setattr*/
1606 (cmpfunc)mpz_compare, /*tp_compare*/
1607 (reprfunc)mpz_repr, /*tp_repr*/
1608 &mpz_as_number, /*tp_as_number*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001609};
1610
1611/* List of functions exported by this module */
1612
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001613static PyMethodDef mpz_functions[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001614#if 0
1615 {initialiser_name, MPZ_mpz},
1616#else /* 0 */
Barry Warsawabb7efe1996-12-09 23:22:35 +00001617 /* until guido ``fixes'' struct PyMethodDef */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001618 {(char *)initialiser_name, MPZ_mpz},
1619#endif /* 0 else */
1620 {"powm", MPZ_powm},
1621 {"gcd", MPZ_gcd},
1622 {"gcdext", MPZ_gcdext},
1623 {"sqrt", MPZ_sqrt},
1624 {"sqrtrem", MPZ_sqrtrem},
1625 {"divm", MPZ_divm},
1626 {NULL, NULL} /* Sentinel */
1627};
1628
1629
1630/* #define MP_TEST_ALLOC */
1631
1632#ifdef MP_TEST_ALLOC
1633#define MP_TEST_SIZE 4
1634static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
1635static mp_test_error( location )
1636 int *location;
1637{
Thomas Wouters7e474022000-07-16 12:04:32 +00001638 /* assumptions: *alloc returns address divisible by 4,
1639 mpz_* routines allocate in chunks divisible by four */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001640 fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001641 Py_FatalError("MP_TEST_ERROR");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001642} /* static mp_test_error() */
1643#define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1644#define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1645#define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1646 ; \
1647 else \
1648 mp_test_error((int *)((char *)(basep) + size))
1649#else /* def MP_TEST_ALLOC */
1650#define MP_EXTRA_ALLOC(size) (size)
1651#define MP_SET_TEST(basep,size)
1652#define MP_DO_TEST(basep,size)
1653#endif /* def MP_TEST_ALLOC else */
1654
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001655void *mp_allocate(size_t alloc_size)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001656{
1657 void *res;
1658
1659#ifdef MPZ_DEBUG
1660 fprintf(stderr, "mp_allocate : size %ld\n",
1661 alloc_size);
1662#endif /* def MPZ_DEBUG */
1663
1664 if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001665 Py_FatalError("mp_allocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001666
1667#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001668 fprintf(stderr, "mp_allocate : address %08p\n", res);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001669#endif /* def MPZ_DEBUG */
1670
1671 MP_SET_TEST(res,alloc_size);
1672
1673 return res;
1674} /* mp_allocate() */
1675
1676
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001677void *mp_reallocate(void *ptr, size_t old_size, size_t new_size)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001678{
1679 void *res;
1680
1681#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001682 fprintf(stderr, "mp_reallocate: old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001683 ptr, old_size);
1684#endif /* def MPZ_DEBUG */
1685
1686 MP_DO_TEST(ptr, old_size);
1687
1688 if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001689 Py_FatalError("mp_reallocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001690
1691#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001692 fprintf(stderr, "mp_reallocate: new address %08p, new size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001693 res, new_size);
1694#endif /* def MPZ_DEBUG */
1695
1696 MP_SET_TEST(res, new_size);
1697
1698 return res;
1699} /* mp_reallocate() */
1700
1701
Peter Schneider-Kamp36463662000-07-10 17:14:00 +00001702void mp_free(void *ptr, size_t size)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001703{
1704
1705#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001706 fprintf(stderr, "mp_free : old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001707 ptr, size);
1708#endif /* def MPZ_DEBUG */
1709
1710 MP_DO_TEST(ptr, size);
1711 free(ptr);
1712} /* mp_free() */
1713
1714
1715
1716/* Initialize this module. */
1717
Guido van Rossum3886bb61998-12-04 18:50:17 +00001718DL_EXPORT(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001719initmpz()
1720{
Fred Drakefcc6c681998-04-03 15:33:43 +00001721 PyObject *module;
1722 PyObject *dict;
1723
Guido van Rossum5f59d601992-12-14 16:59:51 +00001724#ifdef MPZ_DEBUG
1725 fputs( "initmpz() called...\n", stderr );
1726#endif /* def MPZ_DEBUG */
1727
1728 mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
Fred Drakefcc6c681998-04-03 15:33:43 +00001729 module = Py_InitModule("mpz", mpz_functions);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001730
1731 /* create some frequently used constants */
1732 if ((mpz_value_zero = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001733 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001734 mpz_set_ui(&mpz_value_zero->mpz, (unsigned long int)0);
1735
1736 if ((mpz_value_one = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001737 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001738 mpz_set_ui(&mpz_value_one->mpz, (unsigned long int)1);
1739
1740 if ((mpz_value_mone = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001741 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001742 mpz_set_si(&mpz_value_mone->mpz, (long)-1);
1743
Fred Drakefcc6c681998-04-03 15:33:43 +00001744 dict = PyModule_GetDict(module);
1745 if (dict != NULL) {
1746 PyDict_SetItemString(dict, "MPZType", (PyObject*)&MPZtype);
1747 }
1748
Guido van Rossum5f59d601992-12-14 16:59:51 +00001749} /* initmpz() */
1750#ifdef MAKEDUMMYINT
1751int _mpz_dummy_int; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1752#endif /* def MAKEDUMMYINT */