blob: 09d46b9e8fc5a6d186dc73e6dc878206adfb9cad [file] [log] [blame]
Guido van Rossum5f59d601992-12-14 16:59:51 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum5f59d601992-12-14 16:59:51 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum5f59d601992-12-14 16:59:51 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum5f59d601992-12-14 16:59:51 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum5f59d601992-12-14 16:59:51 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum5f59d601992-12-14 16:59:51 +000029
30******************************************************************/
Guido van Rossumb6775db1994-08-01 11:34:53 +000031
Guido van Rossum5f59d601992-12-14 16:59:51 +000032/* MPZ module */
33
34/* This module provides an interface to an alternate Multi-Precision
35 library, GNU MP in this case */
36
37/* XXX note: everywhere where mpz_size is called,
38 sizeof (limb) == sizeof (long) has been assumed. */
39
40
41/* MPZ objects */
42
Barry Warsaw3bdf7461996-12-09 23:16:31 +000043#include "Python.h"
Guido van Rossuma597dde1995-01-10 20:56:29 +000044
Guido van Rossum5f59d601992-12-14 16:59:51 +000045#include <assert.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000046#include <sys/types.h> /* For size_t */
Guido van Rossum5f59d601992-12-14 16:59:51 +000047
48/*
49** These are the cpp-flags used in this file...
50**
51**
52** MPZ_MDIV_BUG works around the mpz_m{div,mod,...} routines.
53** This bug has been fixed in a later release of
54** GMP.
55**
56** MPZ_GET_STR_BUG mpz_get_str corrupts memory, seems to be fixed
57** in a later release
58**
59** MPZ_DEBUG generates a bunch of diagnostic messages
60**
61** MPZ_SPARE_MALLOC if set, results in extra code that tries to
62** minimize the creation of extra objects.
63**
64** MPZ_TEST_DIV extra diagnostic output on stderr, when division
65** routines are involved
66**
67** MPZ_LIB_DOES_CHECKING if set, assumes that mpz library doesn't call
68** alloca with arg < 0 (when casted to a signed
69** integral type).
70**
71** MPZ_CONVERSIONS_AS_METHODS if set, presents the conversions as
72** methods. e.g., `mpz(5).long() == 5L'
73** Later, Guido provided an interface to the
74** standard functions. So this flag has no been
75** cleared, and `long(mpz(5)) == 5L'
76**
77** MP_TEST_ALLOC If set, you would discover why MPZ_GET_STR_BUG
78** is needed
79**
80** MAKEDUMMYINT Must be set if dynamic linking will be used
81*/
82
83
84/*
85** IMHO, mpz_m{div,mod,divmod}() do the wrong things when the denominator < 0
Guido van Rossum272841c1996-08-19 23:06:45 +000086** This has been fixed with gmp release 2.0
Guido van Rossum5f59d601992-12-14 16:59:51 +000087*/
88/*#define MPZ_MDIV_BUG fixed the (for me) nexessary parts in libgmp.a */
89/*
90** IMO, mpz_get_str() assumes a bit too large target space, if he doesn't
91** allocate it himself
92*/
Guido van Rossum5f59d601992-12-14 16:59:51 +000093
94#include "gmp.h"
Guido van Rossume7ef74d2000-02-24 15:26:30 +000095
Guido van Rossum57e846f1997-08-17 19:08:33 +000096#if __GNU_MP__ + 0 == 2
Guido van Rossum272841c1996-08-19 23:06:45 +000097#define GMP2
Andrew M. Kuchlingb6f6e952000-02-25 22:23:31 +000098#define BITS_PER_MP_LIMB mp_bits_per_limb
Guido van Rossum272841c1996-08-19 23:06:45 +000099#else
100#define MPZ_GET_STR_BUG
Andrew M. Kuchlingb6f6e952000-02-25 22:23:31 +0000101#include "gmp-mparam.h"
Guido van Rossum272841c1996-08-19 23:06:45 +0000102#endif
103
Guido van Rossum5f59d601992-12-14 16:59:51 +0000104typedef struct {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000105 PyObject_HEAD
Guido van Rossum5f59d601992-12-14 16:59:51 +0000106 MP_INT mpz; /* the actual number */
107} mpzobject;
108
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000109staticforward PyTypeObject MPZtype;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000110
111#define is_mpzobject(v) ((v)->ob_type == &MPZtype)
112
113static const char initialiser_name[] = "mpz";
114
115/* #define MPZ_DEBUG */
116
117static mpzobject *
118newmpzobject()
119{
120 mpzobject *mpzp;
121
122
123#ifdef MPZ_DEBUG
124 fputs( "mpz_object() called...\n", stderr );
125#endif /* def MPZ_DEBUG */
Guido van Rossumb18618d2000-05-03 23:44:39 +0000126 mpzp = PyObject_New(mpzobject, &MPZtype);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000127 if (mpzp == NULL)
128 return NULL;
129
130 mpz_init(&mpzp->mpz); /* actual initialisation */
131 return mpzp;
132} /* newmpzobject() */
133
134#ifdef MPZ_GET_STR_BUG
Guido van Rossum5f59d601992-12-14 16:59:51 +0000135#include "longlong.h"
136#endif /* def MPZ_GET_STR_BUG */
137
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000138static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000139mpz_format(objp, base, withname)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000140 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000141 int base;
142 unsigned char withname;
143{
144 mpzobject *mpzp = (mpzobject *)objp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000145 PyStringObject *strobjp;
Guido van Rossum2650a422000-06-28 21:29:47 +0000146 size_t i;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000147 int cmpres;
148 int taglong;
149 char *cp;
150 char prefix[5], *tcp;
151
152
153 tcp = &prefix[0];
154
155 if (mpzp == NULL || !is_mpzobject(mpzp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000156 PyErr_BadInternalCall();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000157 return NULL;
158 }
159
160 assert(base >= 2 && base <= 36);
161
162 if (withname)
163 i = strlen(initialiser_name) + 2; /* e.g. 'mpz(' + ')' */
164 else
165 i = 0;
166
167 if ((cmpres = mpz_cmp_si(&mpzp->mpz, 0L)) == 0)
168 base = 10; /* '0' in every base, right */
169 else if (cmpres < 0) {
170 *tcp++ = '-';
171 i += 1; /* space to hold '-' */
172 }
173
174#ifdef MPZ_DEBUG
175 fprintf(stderr, "mpz_format: mpz_sizeinbase %d\n",
176 (int)mpz_sizeinbase(&mpzp->mpz, base));
177#endif /* def MPZ_DEBUG */
178#ifdef MPZ_GET_STR_BUG
Guido van Rossum272841c1996-08-19 23:06:45 +0000179#ifdef GMP2
180 i += ((size_t) abs(mpzp->mpz._mp_size) * BITS_PER_MP_LIMB
181 * __mp_bases[base].chars_per_bit_exactly) + 1;
182#else
Guido van Rossum5f59d601992-12-14 16:59:51 +0000183 i += ((size_t) abs(mpzp->mpz.size) * BITS_PER_MP_LIMB
184 * __mp_bases[base].chars_per_bit_exactly) + 1;
Guido van Rossum272841c1996-08-19 23:06:45 +0000185#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +0000186#else /* def MPZ_GET_STR_BUG */
187 i += (int)mpz_sizeinbase(&mpzp->mpz, base);
188#endif /* def MPZ_GET_STR_BUG else */
189
190 if (base == 16) {
191 *tcp++ = '0';
192 *tcp++ = 'x';
193 i += 2; /* space to hold '0x' */
194 }
195 else if (base == 8) {
196 *tcp++ = '0';
197 i += 1; /* space to hold the extra '0' */
198 }
199 else if (base > 10) {
200 *tcp++ = '0' + base / 10;
201 *tcp++ = '0' + base % 10;
202 *tcp++ = '#';
203 i += 3; /* space to hold e.g. '12#' */
204 }
205 else if (base < 10) {
206 *tcp++ = '0' + base;
207 *tcp++ = '#';
208 i += 2; /* space to hold e.g. '6#' */
209 }
210
211 /*
212 ** the following code looks if we need a 'L' attached to the number
213 ** it will also attach an 'L' to the value -0x80000000
214 */
215 taglong = 0;
216 if (mpz_size(&mpzp->mpz) > 1
217 || (long)mpz_get_ui(&mpzp->mpz) < 0L) {
218 taglong = 1;
219 i += 1; /* space to hold 'L' */
220 }
221
222#ifdef MPZ_DEBUG
223 fprintf(stderr, "mpz_format: requesting string size %d\n", i);
224#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000225 if ((strobjp =
226 (PyStringObject *)PyString_FromStringAndSize((char *)0, i))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000227 == NULL)
228 return NULL;
229
230 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000231 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000232 if (withname) {
233 strcpy(cp, initialiser_name);
234 cp += strlen(initialiser_name);
235 *cp++ = '('; /*')'*/
236 }
237
238 /* copy the already prepared prefix; e.g. sign and base indicator */
239 *tcp = '\0';
240 strcpy(cp, prefix);
241 cp += tcp - prefix;
242
243 /* since' we have the sign already, let the lib think it's a positive
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000244 number */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000245 if (cmpres < 0)
246 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
247 (void)mpz_get_str(cp, base, &mpzp->mpz);
248 if (cmpres < 0)
249 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
250#ifdef MPZ_DEBUG
251 fprintf(stderr, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
252 base, cp);
253#endif /* def MPZ_DEBUG */
254 cp += strlen(cp);
255
256 if (taglong)
257 *cp++ = 'L';
258 if (withname)
259 *cp++ = /*'('*/ ')';
260
261 *cp = '\0';
262
263#ifdef MPZ_DEBUG
264 fprintf(stderr,
Fred Drakea44d3532000-06-30 15:01:00 +0000265 "mpz_format: cp (str end) %p, begin %p, diff %d, i %d\n",
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000266 cp, PyString_AS_STRING(strobjp),
267 cp - PyString_AS_STRING(strobjp), i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000268#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000269 assert(cp - PyString_AS_STRING(strobjp) <= i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000270
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000271 if (cp - PyString_AS_STRING(strobjp) != i) {
272 strobjp->ob_size -= i - (cp - PyString_AS_STRING(strobjp));
Guido van Rossum5f59d601992-12-14 16:59:51 +0000273 }
274
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000275 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000276} /* mpz_format() */
277
278/* MPZ methods */
279
280static void
281mpz_dealloc(mpzp)
282 mpzobject *mpzp;
283{
284#ifdef MPZ_DEBUG
285 fputs( "mpz_dealloc() called...\n", stderr );
286#endif /* def MPZ_DEBUG */
287 mpz_clear(&mpzp->mpz);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000288 PyObject_Del(mpzp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000289} /* mpz_dealloc() */
290
Guido van Rossum5f59d601992-12-14 16:59:51 +0000291
292/* pointers to frequently used values 0, 1 and -1 */
293static mpzobject *mpz_value_zero, *mpz_value_one, *mpz_value_mone;
294
295static int
296mpz_compare(a, b)
297 mpzobject *a, *b;
298{
299 int cmpres;
300
301
302 /* guido sez it's better to return -1, 0 or 1 */
303 return (cmpres = mpz_cmp( &a->mpz, &b->mpz )) == 0 ? 0
304 : cmpres > 0 ? 1 : -1;
305} /* mpz_compare() */
306
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000307static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000308mpz_addition(a, b)
309 mpzobject *a;
310 mpzobject *b;
311{
312 mpzobject *z;
313
314
315#ifdef MPZ_SPARE_MALLOC
316 if (mpz_cmp_ui(&a->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000317 Py_INCREF(b);
318 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000319 }
320
321 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000322 Py_INCREF(a);
323 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000324 }
325#endif /* def MPZ_SPARE_MALLOC */
326
327 if ((z = newmpzobject()) == NULL)
328 return NULL;
329
330 mpz_add(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000331 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000332} /* mpz_addition() */
333
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000334static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000335mpz_substract(a, b)
336 mpzobject *a;
337 mpzobject *b;
338{
339 mpzobject *z;
340
341
342#ifdef MPZ_SPARE_MALLOC
343 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000344 Py_INCREF(a);
345 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000346 }
347#endif /* MPZ_SPARE_MALLOC */
348
349 if ((z = newmpzobject()) == NULL)
350 return NULL;
351
352 mpz_sub(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000353 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000354} /* mpz_substract() */
355
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000356static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000357mpz_multiply(a, b)
358 mpzobject *a;
359 mpzobject *b;
360{
361#ifdef MPZ_SPARE_MALLOC
362 int cmpres;
363#endif /* def MPZ_SPARE_MALLOC */
364 mpzobject *z;
365
366
367#ifdef MPZ_SPARE_MALLOC
368 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000369 Py_INCREF(mpz_value_zero);
370 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000371 }
372 if (cmpres > 0 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000373 Py_INCREF(b);
374 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000375 }
376
377 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long_int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000378 Py_INCREF(mpz_value_zero);
379 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000380 }
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 /* MPZ_SPARE_MALLOC */
386
387 if ((z = newmpzobject()) == NULL)
388 return NULL;
389
390 mpz_mul( &z->mpz, &a->mpz, &b->mpz );
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000391 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000392
393} /* mpz_multiply() */
394
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000395static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000396mpz_divide(a, b)
397 mpzobject *a;
398 mpzobject *b;
399{
400#ifdef MPZ_SPARE_MALLOC
401 int cmpres;
402#endif /* def MPZ_SPARE_MALLOC */
403 mpzobject *z;
404
405
406 if ((
407#ifdef MPZ_SPARE_MALLOC
408 cmpres =
409#endif /* def MPZ_SPARE_MALLOC */
410 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000411 PyErr_SetString(PyExc_ZeroDivisionError, "mpz./ by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000412 return NULL;
413 }
414#ifdef MPZ_SPARE_MALLOC
415 if (cmpres > 0 && mpz_cmp_ui(&b->mpz(unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000416 Py_INCREF(a);
417 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000418 }
419#endif /* def MPZ_SPARE_MALLOC */
420
421 if ((z = newmpzobject()) == NULL)
422 return NULL;
423
424#ifdef MPZ_TEST_DIV
425 fputs("mpz_divide: div result", stderr);
426 mpz_div(&z->mpz, &a->mpz, &b->mpz);
427 mpz_out_str(stderr, 10, &z->mpz);
428 putc('\n', stderr);
429#endif /* def MPZ_TEST_DIV */
430#ifdef MPZ_MDIV_BUG
431 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
432 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)) {
433 /*
434 ** numerator has other sign than denominator: we have
435 ** to look at the remainder for a correction, since mpz_mdiv
436 ** also calls mpz_divmod, I can as well do it myself
437 */
438 MP_INT tmpmpz;
439
440
441 mpz_init(&tmpmpz);
442 mpz_divmod(&z->mpz, &tmpmpz, &a->mpz, &b->mpz);
443
444 if (mpz_cmp_ui(&tmpmpz, (unsigned long int)0) != 0)
445 mpz_sub_ui(&z->mpz, &z->mpz, (unsigned long int)1);
446
447 mpz_clear(&tmpmpz);
448 }
449 else
450 mpz_div(&z->mpz, &a->mpz, &b->mpz);
451 /* the ``naive'' implementation does it right for operands
452 having the same sign */
453
454#else /* def MPZ_MDIV_BUG */
455 mpz_mdiv(&z->mpz, &a->mpz, &b->mpz);
456#endif /* def MPZ_MDIV_BUG else */
457#ifdef MPZ_TEST_DIV
458 fputs("mpz_divide: mdiv result", stderr);
459 mpz_out_str(stderr, 10, &z->mpz);
460 putc('\n', stderr);
461#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000462 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000463
464} /* mpz_divide() */
465
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000466static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000467mpz_remainder(a, b)
468 mpzobject *a;
469 mpzobject *b;
470{
471#ifdef MPZ_SPARE_MALLOC
472 int cmpres;
473#endif /* def MPZ_SPARE_MALLOC */
474 mpzobject *z;
475
476
477 if ((
478#ifdef MPZ_SPARE_MALLOC
479 cmpres =
480#endif /* def MPZ_SPARE_MALLOC */
481 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000482 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.% by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000483 return NULL;
484 }
485#ifdef MPZ_SPARE_MALLOC
486 if (cmpres > 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000487 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)2)) == 0)
488 {
489 Py_INCREF(mpz_value_one);
490 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000491 }
492 if (cmpres < 0) {
493 /* b must be 1 now */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000494 Py_INCREF(mpz_value_zero);
495 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000496 }
497 }
498#endif /* def MPZ_SPARE_MALLOC */
499
500 if ((z = newmpzobject()) == NULL)
501 return NULL;
502
503#ifdef MPZ_TEST_DIV
504 fputs("mpz_remain: mod result", stderr);
505 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
506 mpz_out_str(stderr, 10, &z->mpz);
507 putc('\n', stderr);
508#endif /* def MPZ_TEST_DIV */
509#ifdef MPZ_MDIV_BUG
510
511 /* the ``naive'' implementation does it right for operands
512 having the same sign */
513 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
514
515 /* assumption: z, a and b all point to different locations */
516 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
517 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
518 && mpz_cmp_ui(&z->mpz, (unsigned long int)0) != 0)
519 mpz_add(&z->mpz, &z->mpz, &b->mpz);
520 /*
521 ** numerator has other sign than denominator: we have
522 ** to look at the remainder for a correction, since mpz_mdiv
523 ** also calls mpz_divmod, I can as well do it myself
524 */
525#else /* def MPZ_MDIV_BUG */
526 mpz_mmod(&z->mpz, &a->mpz, &b->mpz);
527#endif /* def MPZ_MDIV_BUG else */
528#ifdef MPZ_TEST_DIV
529 fputs("mpz_remain: mmod result", stderr);
530 mpz_out_str(stderr, 10, &z->mpz);
531 putc('\n', stderr);
532#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000533 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000534
535} /* mpz_remainder() */
536
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000537static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000538mpz_div_and_mod(a, b)
539 mpzobject *a;
540 mpzobject *b;
541{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000542 PyObject *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000543 mpzobject *x = NULL, *y = NULL;
544
545
546 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000547 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.divmod by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000548 return NULL;
549 }
550
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000551 if ((z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +0000552 || (x = newmpzobject()) == NULL
553 || (y = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000554 Py_XDECREF(z);
555 Py_XDECREF(x);
556 Py_XDECREF(y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000557 return NULL;
558 }
559
560#ifdef MPZ_TEST_DIV
561 fputs("mpz_divmod: dm result", stderr);
562 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
563 mpz_out_str(stderr, 10, &x->mpz);
564 putc('\n', stderr);
565 mpz_out_str(stderr, 10, &y->mpz);
566 putc('\n', stderr);
567#endif /* def MPZ_TEST_DIV */
568#ifdef MPZ_MDIV_BUG
569 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
570 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
571 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
572 && mpz_cmp_ui(&y->mpz, (unsigned long int)0) != 0) {
573 /*
574 ** numerator has other sign than denominator: we have
575 ** to look at the remainder for a correction.
576 */
577 mpz_add(&y->mpz, &y->mpz, &b->mpz);
578 mpz_sub_ui(&x->mpz, &x->mpz, (unsigned long int)1);
579 }
580#else /* def MPZ_MDIV_BUG */
581 mpz_mdivmod( &x->mpz, &y->mpz, &a->mpz, &b->mpz );
582#endif /* def MPZ_MDIV_BUG else */
583#ifdef MPZ_TEST_DIV
584 fputs("mpz_divmod: mdm result", stderr);
585 mpz_out_str(stderr, 10, &x->mpz);
586 putc('\n', stderr);
587 mpz_out_str(stderr, 10, &y->mpz);
588 putc('\n', stderr);
589#endif /* def MPZ_TEST_DIV */
590
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000591 (void)PyTuple_SetItem(z, 0, (PyObject *)x);
592 (void)PyTuple_SetItem(z, 1, (PyObject *)y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000593
594 return z;
595} /* mpz_div_and_mod() */
596
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000597static PyObject *
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000598mpz_power(a, b, m)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000599 mpzobject *a;
600 mpzobject *b;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000601 mpzobject *m;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000602{
603 mpzobject *z;
604 int cmpres;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000605
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000606 if ((PyObject *)m != Py_None) {
607 mpzobject *z2;
608 Py_INCREF(Py_None);
609 z=(mpzobject *)mpz_power(a, b, (mpzobject *)Py_None);
610 Py_DECREF(Py_None);
611 if (z==NULL) return((PyObject *)z);
612 z2=(mpzobject *)mpz_remainder(z, m);
613 Py_DECREF(z);
614 return((PyObject *)z2);
615 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000616
617 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
618 /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
619
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000620 Py_INCREF(mpz_value_one);
621 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000622 }
623
624 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000625 PyErr_SetString(PyExc_ValueError,
626 "mpz.pow to negative exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000627 return NULL;
628 }
629
630 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
631 /* the base is 0 */
632
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000633 Py_INCREF(mpz_value_zero);
634 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000635 }
636 else if (cmpres > 0
637 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
638 /* the base is 1 */
639
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000640 Py_INCREF(mpz_value_one);
641 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000642 }
643 else if (cmpres < 0
644 && mpz_cmp_si(&a->mpz, (long int)-1) == 0) {
645
646 MP_INT tmpmpz;
647 /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
648 /* XXX this code needs to be optimized: what's better?
649 mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
650 for *un*obvious reasons */
651
652 /* is the exponent even? */
653 mpz_init(&tmpmpz);
654
655 /* look to the remainder after a division by (1 << 1) */
656 mpz_mod_2exp(&tmpmpz, &b->mpz, (unsigned long int)1);
657
658 if (mpz_cmp_ui(&tmpmpz, (unsigned int)0) == 0) {
659 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000660 Py_INCREF(mpz_value_one);
661 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000662 }
663 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000664 Py_INCREF(mpz_value_mone);
665 return (PyObject *)mpz_value_mone;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000666 }
667
668#ifdef MPZ_LIB_DOES_CHECKING
669 /* check if it's doable: sizeof(exp) > sizeof(long) &&
670 abs(base) > 1 ?? --> No Way */
671 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000672 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000673#else /* def MPZ_LIB_DOES_CHECKING */
674 /* wet finger method */
675 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000676 PyErr_SetString(PyExc_ValueError,
677 "mpz.pow outrageous exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000678 return NULL;
679 }
680#endif /* def MPZ_LIB_DOES_CHECKING else */
681
682 if ((z = newmpzobject()) == NULL)
683 return NULL;
684
685 mpz_pow_ui(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
686
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000687 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000688} /* mpz_power() */
689
690
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000691static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000692mpz_negative(v)
693 mpzobject *v;
694{
695 mpzobject *z;
696
697
698#ifdef MPZ_SPARE_MALLOC
699 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) == 0) {
700 /* -0 == 0 */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000701 Py_INCREF(v);
702 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000703 }
704#endif /* def MPZ_SPARE_MALLOC */
705
706 if ((z = newmpzobject()) == NULL)
707 return NULL;
708
709 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000710 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000711} /* mpz_negative() */
712
713
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000714static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000715mpz_positive(v)
716 mpzobject *v;
717{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000718 Py_INCREF(v);
719 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000720} /* mpz_positive() */
721
722
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000723static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000724mpz_absolute(v)
725 mpzobject *v;
726{
727 mpzobject *z;
728
729
730 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000731 Py_INCREF(v);
732 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000733 }
734
735 if ((z = newmpzobject()) == NULL)
736 return NULL;
737
738 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000739 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000740} /* mpz_absolute() */
741
742static int
743mpz_nonzero(v)
744 mpzobject *v;
745{
746 return mpz_cmp_ui(&v->mpz, (unsigned long int)0) != 0;
747} /* mpz_nonzero() */
748
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000749static PyObject *
Guido van Rossum272841c1996-08-19 23:06:45 +0000750py_mpz_invert(v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000751 mpzobject *v;
752{
753 mpzobject *z;
754
755
756 /* I think mpz_com does exactly what needed */
757 if ((z = newmpzobject()) == NULL)
758 return NULL;
759
760 mpz_com(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000761 return (PyObject *)z;
Guido van Rossum272841c1996-08-19 23:06:45 +0000762} /* py_mpz_invert() */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000763
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000764static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000765mpz_lshift(a, b)
766 mpzobject *a;
767 mpzobject *b;
768{
769 int cmpres;
770 mpzobject *z;
771
772
773 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
774 /* a << 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000775 Py_INCREF(a);
776 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000777 }
778
779 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000780 PyErr_SetString(PyExc_ValueError,
781 "mpz.<< negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000782 return NULL;
783 }
784
785#ifdef MPZ_LIB_DOES_CHECKING
786 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000787 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000788#else /* def MPZ_LIB_DOES_CHECKING */
789 /* wet finger method */
790 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000791 PyErr_SetString(PyExc_ValueError,
792 "mpz.<< outrageous shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000793 return NULL;
794 }
795#endif /* def MPZ_LIB_DOES_CHECKING else */
796
797 if ((z = newmpzobject()) == NULL)
798 return NULL;
799
800 mpz_mul_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000801 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000802} /* mpz_lshift() */
803
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000804static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000805mpz_rshift(a, b)
806 mpzobject *a;
807 mpzobject *b;
808{
809 int cmpres;
810 mpzobject *z;
811
812
813 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
814 /* a >> 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000815 Py_INCREF(a);
816 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000817 }
818
819 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000820 PyErr_SetString(PyExc_ValueError,
821 "mpz.>> negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000822 return NULL;
823 }
824
825 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000826 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000827
828 if ((z = newmpzobject()) == NULL)
829 return NULL;
830
831 mpz_div_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000832 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000833} /* mpz_rshift() */
834
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000835static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000836mpz_andfunc(a, b)
837 mpzobject *a;
838 mpzobject *b;
839{
840 mpzobject *z;
841
842
843 if ((z = newmpzobject()) == NULL)
844 return NULL;
845
846 mpz_and(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000847 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000848} /* mpz_andfunc() */
849
850/* hack Hack HAck HACk HACK, XXX this code is dead slow */
851void
852mpz_xor(res, op1, op2)
853 MP_INT *res;
854 const MP_INT *op1;
855 const MP_INT *op2;
856{
857 MP_INT tmpmpz;
858
859 mpz_init(&tmpmpz);
860
861 mpz_and(res, op1, op2);
862 mpz_com(&tmpmpz, res);
863 mpz_ior(res, op1, op2);
864 mpz_and(res, res, &tmpmpz);
865
866 mpz_clear(&tmpmpz);
867} /* mpz_xor() HACK */
868
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000869static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000870mpz_xorfunc(a, b)
871 mpzobject *a;
872 mpzobject *b;
873{
874 mpzobject *z;
875
876
877 if ((z = newmpzobject()) == NULL)
878 return NULL;
879
880 mpz_xor(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000881 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000882} /* mpz_xorfunc() */
883
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000884static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000885mpz_orfunc(a, b)
886 mpzobject *a;
887 mpzobject *b;
888{
889 mpzobject *z;
890
891
892 if ((z = newmpzobject()) == NULL)
893 return NULL;
894
895 mpz_ior(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000896 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000897} /* mpz_orfunc() */
898
899/* MPZ initialisation */
900
901#include "longintrepr.h"
902
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000903static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000904MPZ_mpz(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000905 PyObject *self;
906 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000907{
908 mpzobject *mpzp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000909 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000910
911
912#ifdef MPZ_DEBUG
913 fputs("MPZ_mpz() called...\n", stderr);
914#endif /* def MPZ_DEBUG */
915
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000916 if (!PyArg_Parse(args, "O", &objp))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000917 return NULL;
918
919 /* at least we know it's some object */
Barry Warsawabb7efe1996-12-09 23:22:35 +0000920 /* note DON't Py_DECREF args NEITHER objp */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000921
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000922 if (PyInt_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000923 long lval;
924
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000925 if (!PyArg_Parse(objp, "l", &lval))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000926 return NULL;
927
928 if (lval == (long)0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000929 Py_INCREF(mpz_value_zero);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000930 mpzp = mpz_value_zero;
931 }
932 else if (lval == (long)1) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000933 Py_INCREF(mpz_value_one);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000934 mpzp = mpz_value_one;
935 }
936 else if ((mpzp = newmpzobject()) == NULL)
937 return NULL;
938 else mpz_set_si(&mpzp->mpz, lval);
939 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000940 else if (PyLong_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000941 MP_INT mplongdigit;
942 int i;
943 unsigned char isnegative;
944
945
946 if ((mpzp = newmpzobject()) == NULL)
947 return NULL;
948
949 mpz_set_si(&mpzp->mpz, 0L);
950 mpz_init(&mplongdigit);
951
952 /* how we're gonna handle this? */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000953 if ((isnegative =
954 ((i = ((PyLongObject *)objp)->ob_size) < 0) ))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000955 i = -i;
956
957 while (i--) {
958 mpz_set_ui(&mplongdigit,
959 (unsigned long)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000960 ((PyLongObject *)objp)->ob_digit[i]);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000961 mpz_mul_2exp(&mplongdigit,&mplongdigit,
962 (unsigned long int)i * SHIFT);
963 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
964 }
965
966 if (isnegative)
967 mpz_neg(&mpzp->mpz, &mpzp->mpz);
968
969 /* get rid of allocation for tmp variable */
970 mpz_clear(&mplongdigit);
971 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000972 else if (PyString_Check(objp)) {
Andrew M. Kuchling4c07f811998-12-14 19:36:14 +0000973 unsigned char *cp = (unsigned char *)PyString_AS_STRING(objp);
Guido van Rossum7e488981998-10-08 02:25:24 +0000974 int len = PyString_GET_SIZE(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000975 MP_INT mplongdigit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000976
977 if ((mpzp = newmpzobject()) == NULL)
978 return NULL;
979
980 mpz_set_si(&mpzp->mpz, 0L);
981 mpz_init(&mplongdigit);
982
983 /* let's do it the same way as with the long conversion:
984 without thinking how it can be faster (-: :-) */
985
986 cp += len;
987 while (len--) {
988 mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
989 mpz_mul_2exp(&mplongdigit,&mplongdigit,
990 (unsigned long int)len * 8);
991 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
992 }
993
994 /* get rid of allocation for tmp variable */
995 mpz_clear(&mplongdigit);
996 }
997 else if (is_mpzobject(objp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000998 Py_INCREF(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000999 mpzp = (mpzobject *)objp;
1000 }
1001 else {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001002 PyErr_SetString(PyExc_TypeError,
1003"mpz.mpz() expects integer, long, string or mpz object argument");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001004 return NULL;
1005 }
1006
1007
1008#ifdef MPZ_DEBUG
1009 fputs("MPZ_mpz: created mpz=", stderr);
1010 mpz_out_str(stderr, 10, &mpzp->mpz);
1011 putc('\n', stderr);
1012#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001013 return (PyObject *)mpzp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001014} /* MPZ_mpz() */
1015
1016static mpzobject *
1017mpz_mpzcoerce(z)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001018 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001019{
1020 /* shortcut: 9 out of 10 times the type is already ok */
1021 if (is_mpzobject(z)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001022 Py_INCREF(z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001023 return (mpzobject *)z; /* coercion succeeded */
1024 }
1025
1026 /* what types do we accept?: intobjects and longobjects */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001027 if (PyInt_Check(z) || PyLong_Check(z))
1028 return (mpzobject *)MPZ_mpz((PyObject *)NULL, z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001029
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001030 PyErr_SetString(PyExc_TypeError,
1031 "number coercion (to mpzobject) failed");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001032 return NULL;
1033} /* mpz_mpzcoerce() */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001034
1035/* Forward */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001036static void mpz_divm Py_PROTO((MP_INT *res, const MP_INT *num,
1037 const MP_INT *den, const MP_INT *mod));
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001038
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001039static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001040MPZ_powm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001041 PyObject *self;
1042 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001043{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001044 PyObject *base, *exp, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001045 mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
1046 mpzobject *z;
1047 int tstres;
1048
1049
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001050 if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001051 return NULL;
1052
1053 if ((mpzbase = mpz_mpzcoerce(base)) == NULL
1054 || (mpzexp = mpz_mpzcoerce(exp)) == NULL
1055 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1056 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001057 Py_XDECREF(mpzbase);
1058 Py_XDECREF(mpzexp);
1059 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001060 return NULL;
1061 }
1062
1063 if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001064 Py_INCREF(mpz_value_one);
1065 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001066 }
1067
1068 if (tstres < 0) {
1069 MP_INT absexp;
1070 /* negative exp */
1071
1072 mpz_init_set(&absexp, &mpzexp->mpz);
1073 mpz_abs(&absexp, &absexp);
1074 mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
1075
1076 mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
1077
1078 mpz_clear(&absexp);
1079 }
1080 else {
1081 mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
1082 }
1083
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001084 Py_DECREF(mpzbase);
1085 Py_DECREF(mpzexp);
1086 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001087
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001088 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001089} /* MPZ_powm() */
1090
1091
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001092static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001093MPZ_gcd(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001094 PyObject *self;
1095 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001096{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001097 PyObject *op1, *op2;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001098 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1099 mpzobject *z;
1100
1101
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001102 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001103 return NULL;
1104
1105 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1106 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
1107 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001108 Py_XDECREF(mpzop1);
1109 Py_XDECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001110 return NULL;
1111 }
1112
1113 /* ok, we have three mpzobjects, and an initialised result holder */
1114 mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
1115
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001116 Py_DECREF(mpzop1);
1117 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001118
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001119 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001120} /* MPZ_gcd() */
1121
1122
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001123static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001124MPZ_gcdext(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001125 PyObject *self;
1126 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001127{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001128 PyObject *op1, *op2, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001129 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1130 mpzobject *g = NULL, *s = NULL, *t = NULL;
1131
1132
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001133 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001134 return NULL;
1135
1136 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1137 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001138 || (z = PyTuple_New(3)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001139 || (g = newmpzobject()) == NULL
1140 || (s = newmpzobject()) == NULL
1141 || (t = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001142 Py_XDECREF(mpzop1);
1143 Py_XDECREF(mpzop2);
1144 Py_XDECREF(z);
1145 Py_XDECREF(g);
1146 Py_XDECREF(s);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001147 /*Py_XDECREF(t);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001148 return NULL;
1149 }
1150
1151 mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
1152
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001153 Py_DECREF(mpzop1);
1154 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001155
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001156 (void)PyTuple_SetItem(z, 0, (PyObject *)g);
1157 (void)PyTuple_SetItem(z, 1, (PyObject *)s);
1158 (void)PyTuple_SetItem(z, 2, (PyObject *)t);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001159
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001160 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001161} /* MPZ_gcdext() */
1162
1163
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001164static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001165MPZ_sqrt(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001166 PyObject *self;
1167 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001168{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001169 PyObject *op;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001170 mpzobject *mpzop = NULL;
1171 mpzobject *z;
1172
1173
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001174 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001175 return NULL;
1176
1177 if ((mpzop = mpz_mpzcoerce(op)) == NULL
1178 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001179 Py_XDECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001180 return NULL;
1181 }
1182
1183 mpz_sqrt(&z->mpz, &mpzop->mpz);
1184
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001185 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001186
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001187 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001188} /* MPZ_sqrt() */
1189
1190
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001191static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001192MPZ_sqrtrem(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001193 PyObject *self;
1194 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001195{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001196 PyObject *op, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001197 mpzobject *mpzop = NULL;
1198 mpzobject *root = NULL, *rem = NULL;
1199
1200
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001201 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001202 return NULL;
1203
1204 if ((mpzop = mpz_mpzcoerce(op)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001205 || (z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001206 || (root = newmpzobject()) == NULL
1207 || (rem = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001208 Py_XDECREF(mpzop);
1209 Py_XDECREF(z);
1210 Py_XDECREF(root);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001211 /*Py_XDECREF(rem);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001212 return NULL;
1213 }
1214
1215 mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
1216
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001217 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001218
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001219 (void)PyTuple_SetItem(z, 0, (PyObject *)root);
1220 (void)PyTuple_SetItem(z, 1, (PyObject *)rem);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001221
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001222 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001223} /* MPZ_sqrtrem() */
1224
1225
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001226static void
Guido van Rossum5f59d601992-12-14 16:59:51 +00001227#if __STDC__
1228mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
1229#else
1230mpz_divm(res, num, den, mod)
1231 MP_INT *res;
1232 const MP_INT *num;
1233 const MP_INT *den;
1234 const MP_INT *mod;
1235#endif
1236{
1237 MP_INT s0, s1, q, r, x, d0, d1;
1238
1239 mpz_init_set(&s0, num);
1240 mpz_init_set_ui(&s1, 0);
1241 mpz_init(&q);
1242 mpz_init(&r);
1243 mpz_init(&x);
1244 mpz_init_set(&d0, den);
1245 mpz_init_set(&d1, mod);
1246
Guido van Rossum272841c1996-08-19 23:06:45 +00001247#ifdef GMP2
1248 while (d1._mp_size != 0) {
1249#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001250 while (d1.size != 0) {
Guido van Rossum272841c1996-08-19 23:06:45 +00001251#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001252 mpz_divmod(&q, &r, &d0, &d1);
1253 mpz_set(&d0, &d1);
1254 mpz_set(&d1, &r);
1255
1256 mpz_mul(&x, &s1, &q);
1257 mpz_sub(&x, &s0, &x);
1258 mpz_set(&s0, &s1);
1259 mpz_set(&s1, &x);
1260 }
1261
Guido van Rossum272841c1996-08-19 23:06:45 +00001262#ifdef GMP2
1263 if (d0._mp_size != 1 || d0._mp_d[0] != 1)
1264 res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
1265#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001266 if (d0.size != 1 || d0.d[0] != 1)
1267 res->size = 0; /* trouble: the gcd != 1; set s to zero */
Guido van Rossum272841c1996-08-19 23:06:45 +00001268#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001269 else {
1270#ifdef MPZ_MDIV_BUG
1271 /* watch out here! first check the signs, and then perform
1272 the mpz_mod() since mod could point to res */
1273 if ((s0.size < 0) != (mod->size < 0)) {
1274 mpz_mod(res, &s0, mod);
1275
1276 if (res->size)
1277 mpz_add(res, res, mod);
1278 }
1279 else
1280 mpz_mod(res, &s0, mod);
1281
1282#else /* def MPZ_MDIV_BUG */
1283 mpz_mmod(res, &s0, mod);
1284#endif /* def MPZ_MDIV_BUG else */
1285 }
1286
1287 mpz_clear(&s0);
1288 mpz_clear(&s1);
1289 mpz_clear(&q);
1290 mpz_clear(&r);
1291 mpz_clear(&x);
1292 mpz_clear(&d0);
1293 mpz_clear(&d1);
1294} /* mpz_divm() */
1295
1296
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001297static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001298MPZ_divm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001299 PyObject *self;
1300 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001301{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001302 PyObject *num, *den, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001303 mpzobject *mpznum, *mpzden, *mpzmod = NULL;
1304 mpzobject *z = NULL;
1305
1306
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001307 if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001308 return NULL;
1309
1310 if ((mpznum = mpz_mpzcoerce(num)) == NULL
1311 || (mpzden = mpz_mpzcoerce(den)) == NULL
1312 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1313 || (z = newmpzobject()) == NULL ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001314 Py_XDECREF(mpznum);
1315 Py_XDECREF(mpzden);
1316 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001317 return NULL;
1318 }
1319
1320 mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
1321
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001322 Py_DECREF(mpznum);
1323 Py_DECREF(mpzden);
1324 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001325
1326 if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001327 Py_DECREF(z);
1328 PyErr_SetString(PyExc_ValueError,
1329 "gcd(den, mod) != 1 or num == 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001330 return NULL;
1331 }
1332
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001333 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001334} /* MPZ_divm() */
1335
1336
1337/* MPZ methods-as-attributes */
1338#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001339static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001340mpz_int(self, args)
1341 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001342 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001343#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001344static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001345mpz_int(self)
1346 mpzobject *self;
1347#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1348{
1349 long sli;
1350
1351
1352#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001353 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001354 return NULL;
1355#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1356
1357 if (mpz_size(&self->mpz) > 1
1358 || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001359 PyErr_SetString(PyExc_ValueError,
1360 "mpz.int() arg too long to convert");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001361 return NULL;
1362 }
1363
1364 if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
1365 sli = -sli;
1366
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001367 return PyInt_FromLong(sli);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001368} /* mpz_int() */
1369
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001370static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001371#ifdef MPZ_CONVERSIONS_AS_METHODS
1372mpz_long(self, args)
1373 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001374 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001375#else /* def MPZ_CONVERSIONS_AS_METHODS */
1376mpz_long(self)
1377 mpzobject *self;
1378#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1379{
1380 int i, isnegative;
1381 unsigned long int uli;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001382 PyLongObject *longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001383 int ldcount;
1384 int bitpointer, newbitpointer;
1385 MP_INT mpzscratch;
1386
1387
1388#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001389 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001390 return NULL;
1391#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1392
1393 /* determine length of python-long to be allocated */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001394 if ((longobjp = _PyLong_New(i = (int)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001395 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
1396 + SHIFT - 1) /
1397 SHIFT))) == NULL)
1398 return NULL;
1399
1400 /* determine sign, and copy self to scratch var */
1401 mpz_init_set(&mpzscratch, &self->mpz);
Guido van Rossum272841c1996-08-19 23:06:45 +00001402 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001403 mpz_neg(&mpzscratch, &mpzscratch);
1404
1405 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001406 e.g. dismantle mpzscratch, build PyLongObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001407
1408 bitpointer = 0; /* the number of valid bits in stock */
1409 newbitpointer = 0;
1410 ldcount = 0; /* the python-long limb counter */
1411 uli = (unsigned long int)0;
1412 while (i--) {
1413 longobjp->ob_digit[ldcount] = uli & MASK;
1414
1415 /* check if we've had enough bits for this digit */
1416 if (bitpointer < SHIFT) {
1417 uli = mpz_get_ui(&mpzscratch);
1418 longobjp->ob_digit[ldcount] |=
1419 (uli << bitpointer) & MASK;
1420 uli >>= SHIFT-bitpointer;
1421 bitpointer += BITS_PER_MP_LIMB;
1422 mpz_div_2exp(&mpzscratch, &mpzscratch,
1423 BITS_PER_MP_LIMB);
1424 }
1425 else
1426 uli >>= SHIFT;
1427 bitpointer -= SHIFT;
1428 ldcount++;
1429 }
1430
1431 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1432 mpz_clear(&mpzscratch);
1433 assert(ldcount <= longobjp->ob_size);
1434
1435 /* long_normalize() is file-static */
1436 /* longobjp = long_normalize(longobjp); */
1437 while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
1438 ldcount--;
1439 longobjp->ob_size = ldcount;
1440
1441
1442 if (isnegative)
1443 longobjp->ob_size = -longobjp->ob_size;
1444
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001445 return (PyObject *)longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001446
1447} /* mpz_long() */
1448
1449
1450/* I would have avoided pow() anyways, so ... */
1451static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
1452
1453#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001454static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001455mpz_float(self, args)
1456 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001457 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001458#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001459static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001460mpz_float(self)
1461 mpzobject *self;
1462#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1463{
1464 int i, isnegative;
1465 double x;
1466 double mulstate;
1467 MP_INT mpzscratch;
1468
1469
1470#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001471 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001472 return NULL;
1473#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1474
1475 i = (int)mpz_size(&self->mpz);
1476
1477 /* determine sign, and copy abs(self) to scratch var */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001478 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
1479 {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001480 mpz_init(&mpzscratch);
1481 mpz_neg(&mpzscratch, &self->mpz);
1482 }
1483 else
1484 mpz_init_set(&mpzscratch, &self->mpz);
1485
1486 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001487 e.g. dismantle mpzscratch, build PyFloatObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001488
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001489 /* Can this overflow? Dunno, protect against that possibility. */
1490 PyFPE_START_PROTECT("mpz_float", return 0)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001491 x = 0.0;
1492 mulstate = 1.0;
1493 while (i--) {
1494 x += mulstate * mpz_get_ui(&mpzscratch);
1495 mulstate *= multiplier;
1496 mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
1497 }
Guido van Rossum45b83911997-03-14 04:32:50 +00001498 PyFPE_END_PROTECT(mulstate)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001499
1500 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1501 mpz_clear(&mpzscratch);
1502
1503 if (isnegative)
1504 x = -x;
1505
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001506 return PyFloat_FromDouble(x);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001507
1508} /* mpz_float() */
1509
1510#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001511static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001512mpz_hex(self, args)
1513 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001514 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001515#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001516static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001517mpz_hex(self)
1518 mpzobject *self;
1519#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1520{
1521#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001522 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001523 return NULL;
1524#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1525
1526 return mpz_format(self, 16, (unsigned char)1);
1527} /* mpz_hex() */
1528
1529#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001530static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001531mpz_oct(self, args)
1532 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001533 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001534#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001535static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001536mpz_oct(self)
1537 mpzobject *self;
1538#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1539{
1540#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001541 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001542 return NULL;
1543#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1544
1545 return mpz_format(self, 8, (unsigned char)1);
1546} /* mpz_oct() */
1547
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001548static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001549mpz_binary(self, args)
1550 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001551 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001552{
1553 int size;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001554 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001555 char *cp;
1556 MP_INT mp;
1557 unsigned long ldigit;
1558
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001559 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001560 return NULL;
1561
1562 if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001563 PyErr_SetString(PyExc_ValueError,
1564 "mpz.binary() arg must be >= 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001565 return NULL;
1566 }
1567
1568 mpz_init_set(&mp, &self->mpz);
1569 size = (int)mpz_size(&mp);
1570
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001571 if ((strobjp = (PyStringObject *)
1572 PyString_FromStringAndSize(
1573 (char *)0, size * sizeof (unsigned long int))) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001574 return NULL;
1575
1576 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001577 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001578
1579 /* this has been programmed using a (fairly) decent lib-i/f it could
1580 be must faster if we looked into the GMP lib */
1581 while (size--) {
1582 ldigit = mpz_get_ui(&mp);
1583 mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
1584 *cp++ = (unsigned char)(ldigit & 0xFF);
1585 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1586 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1587 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1588 }
1589
1590 while (strobjp->ob_size && !*--cp)
1591 strobjp->ob_size--;
1592
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001593 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001594} /* mpz_binary() */
1595
1596
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001597static PyMethodDef mpz_methods[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001598#ifdef MPZ_CONVERSIONS_AS_METHODS
1599 {"int", mpz_int},
1600 {"long", mpz_long},
1601 {"float", mpz_float},
1602 {"hex", mpz_hex},
1603 {"oct", mpz_oct},
1604#endif /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001605 {"binary", (PyCFunction)mpz_binary},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001606 {NULL, NULL} /* sentinel */
1607};
1608
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001609static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001610mpz_getattr(self, name)
1611 mpzobject *self;
1612 char *name;
1613{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001614 return Py_FindMethod(mpz_methods, (PyObject *)self, name);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001615} /* mpz_getattr() */
1616
1617
1618static int
1619mpz_coerce(pv, pw)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001620 PyObject **pv;
1621 PyObject **pw;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001622{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001623 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001624
1625#ifdef MPZ_DEBUG
1626 fputs("mpz_coerce() called...\n", stderr);
1627#endif /* def MPZ_DEBUG */
1628
1629 assert(is_mpzobject(*pv));
1630
1631 /* always convert other arg to mpz value, except for floats */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001632 if (!PyFloat_Check(*pw)) {
1633 if ((z = (PyObject *)mpz_mpzcoerce(*pw)) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001634 return -1; /* -1: an error always has been set */
1635
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001636 Py_INCREF(*pv);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001637 *pw = z;
1638 }
1639 else {
1640 if ((z = mpz_float(*pv, NULL)) == NULL)
1641 return -1;
1642
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001643 Py_INCREF(*pw);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001644 *pv = z;
1645 }
1646 return 0; /* coercion succeeded */
1647
1648} /* mpz_coerce() */
1649
1650
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001651static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001652mpz_repr(v)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001653 PyObject *v;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001654{
1655 return mpz_format(v, 10, (unsigned char)1);
1656} /* mpz_repr() */
1657
1658
1659
Guido van Rossumb6775db1994-08-01 11:34:53 +00001660#define UF (unaryfunc)
1661#define BF (binaryfunc)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001662#define TF (ternaryfunc)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001663#define IF (inquiry)
1664#define CF (coercion)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001665
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001666static PyNumberMethods mpz_as_number = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001667 BF mpz_addition, /*nb_add*/
1668 BF mpz_substract, /*nb_subtract*/
1669 BF mpz_multiply, /*nb_multiply*/
1670 BF mpz_divide, /*nb_divide*/
1671 BF mpz_remainder, /*nb_remainder*/
1672 BF mpz_div_and_mod, /*nb_divmod*/
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001673 TF mpz_power, /*nb_power*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001674 UF mpz_negative, /*nb_negative*/
1675 UF mpz_positive, /*tp_positive*/
1676 UF mpz_absolute, /*tp_absolute*/
1677 IF mpz_nonzero, /*tp_nonzero*/
Guido van Rossum272841c1996-08-19 23:06:45 +00001678 UF py_mpz_invert, /*nb_invert*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001679 BF mpz_lshift, /*nb_lshift*/
1680 BF mpz_rshift, /*nb_rshift*/
1681 BF mpz_andfunc, /*nb_and*/
1682 BF mpz_xorfunc, /*nb_xor*/
1683 BF mpz_orfunc, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001684 CF mpz_coerce, /*nb_coerce*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001685#ifndef MPZ_CONVERSIONS_AS_METHODS
1686 UF mpz_int, /*nb_int*/
1687 UF mpz_long, /*nb_long*/
1688 UF mpz_float, /*nb_float*/
1689 UF mpz_oct, /*nb_oct*/
1690 UF mpz_hex, /*nb_hex*/
1691#endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1692};
1693
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001694static PyTypeObject MPZtype = {
1695 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001696 0, /*ob_size*/
1697 "mpz", /*tp_name*/
1698 sizeof(mpzobject), /*tp_size*/
1699 0, /*tp_itemsize*/
1700 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001701 (destructor)mpz_dealloc, /*tp_dealloc*/
1702 0, /*tp_print*/
1703 (getattrfunc)mpz_getattr, /*tp_getattr*/
1704 0, /*tp_setattr*/
1705 (cmpfunc)mpz_compare, /*tp_compare*/
1706 (reprfunc)mpz_repr, /*tp_repr*/
1707 &mpz_as_number, /*tp_as_number*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001708};
1709
1710/* List of functions exported by this module */
1711
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001712static PyMethodDef mpz_functions[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001713#if 0
1714 {initialiser_name, MPZ_mpz},
1715#else /* 0 */
Barry Warsawabb7efe1996-12-09 23:22:35 +00001716 /* until guido ``fixes'' struct PyMethodDef */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001717 {(char *)initialiser_name, MPZ_mpz},
1718#endif /* 0 else */
1719 {"powm", MPZ_powm},
1720 {"gcd", MPZ_gcd},
1721 {"gcdext", MPZ_gcdext},
1722 {"sqrt", MPZ_sqrt},
1723 {"sqrtrem", MPZ_sqrtrem},
1724 {"divm", MPZ_divm},
1725 {NULL, NULL} /* Sentinel */
1726};
1727
1728
1729/* #define MP_TEST_ALLOC */
1730
1731#ifdef MP_TEST_ALLOC
1732#define MP_TEST_SIZE 4
1733static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
1734static mp_test_error( location )
1735 int *location;
1736{
1737 /* assumptions: *alloc returns address dividable by 4,
1738 mpz_* routines allocate in chunks dividable by four */
1739 fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001740 Py_FatalError("MP_TEST_ERROR");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001741} /* static mp_test_error() */
1742#define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1743#define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1744#define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1745 ; \
1746 else \
1747 mp_test_error((int *)((char *)(basep) + size))
1748#else /* def MP_TEST_ALLOC */
1749#define MP_EXTRA_ALLOC(size) (size)
1750#define MP_SET_TEST(basep,size)
1751#define MP_DO_TEST(basep,size)
1752#endif /* def MP_TEST_ALLOC else */
1753
1754void *mp_allocate( alloc_size )
1755 size_t alloc_size;
1756{
1757 void *res;
1758
1759#ifdef MPZ_DEBUG
1760 fprintf(stderr, "mp_allocate : size %ld\n",
1761 alloc_size);
1762#endif /* def MPZ_DEBUG */
1763
1764 if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001765 Py_FatalError("mp_allocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001766
1767#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001768 fprintf(stderr, "mp_allocate : address %08p\n", res);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001769#endif /* def MPZ_DEBUG */
1770
1771 MP_SET_TEST(res,alloc_size);
1772
1773 return res;
1774} /* mp_allocate() */
1775
1776
1777void *mp_reallocate( ptr, old_size, new_size )
1778 void *ptr;
1779 size_t old_size;
1780 size_t new_size;
1781{
1782 void *res;
1783
1784#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001785 fprintf(stderr, "mp_reallocate: old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001786 ptr, old_size);
1787#endif /* def MPZ_DEBUG */
1788
1789 MP_DO_TEST(ptr, old_size);
1790
1791 if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001792 Py_FatalError("mp_reallocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001793
1794#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001795 fprintf(stderr, "mp_reallocate: new address %08p, new size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001796 res, new_size);
1797#endif /* def MPZ_DEBUG */
1798
1799 MP_SET_TEST(res, new_size);
1800
1801 return res;
1802} /* mp_reallocate() */
1803
1804
1805void mp_free( ptr, size )
1806 void *ptr;
1807 size_t size;
1808{
1809
1810#ifdef MPZ_DEBUG
Fred Drakea44d3532000-06-30 15:01:00 +00001811 fprintf(stderr, "mp_free : old address %08p, old size %ld\n",
Guido van Rossum5f59d601992-12-14 16:59:51 +00001812 ptr, size);
1813#endif /* def MPZ_DEBUG */
1814
1815 MP_DO_TEST(ptr, size);
1816 free(ptr);
1817} /* mp_free() */
1818
1819
1820
1821/* Initialize this module. */
1822
Guido van Rossum3886bb61998-12-04 18:50:17 +00001823DL_EXPORT(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001824initmpz()
1825{
Fred Drakefcc6c681998-04-03 15:33:43 +00001826 PyObject *module;
1827 PyObject *dict;
1828
Guido van Rossum5f59d601992-12-14 16:59:51 +00001829#ifdef MPZ_DEBUG
1830 fputs( "initmpz() called...\n", stderr );
1831#endif /* def MPZ_DEBUG */
1832
1833 mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
Fred Drakefcc6c681998-04-03 15:33:43 +00001834 module = Py_InitModule("mpz", mpz_functions);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001835
1836 /* create some frequently used constants */
1837 if ((mpz_value_zero = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001838 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001839 mpz_set_ui(&mpz_value_zero->mpz, (unsigned long int)0);
1840
1841 if ((mpz_value_one = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001842 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001843 mpz_set_ui(&mpz_value_one->mpz, (unsigned long int)1);
1844
1845 if ((mpz_value_mone = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001846 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001847 mpz_set_si(&mpz_value_mone->mpz, (long)-1);
1848
Fred Drakefcc6c681998-04-03 15:33:43 +00001849 dict = PyModule_GetDict(module);
1850 if (dict != NULL) {
1851 PyDict_SetItemString(dict, "MPZType", (PyObject*)&MPZtype);
1852 }
1853
Guido van Rossum5f59d601992-12-14 16:59:51 +00001854} /* initmpz() */
1855#ifdef MAKEDUMMYINT
1856int _mpz_dummy_int; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1857#endif /* def MAKEDUMMYINT */