blob: 2653a95b0e57f1ab5e7fbb53e6a9f3e4117f86fe [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
96#if defined __GLIBC__ && __GLIBC__ >= 2 /*aid building on Linux distributions*/
97#define BITS_PER_MP_LIMB mp_bits_per_limb
98#else
Guido van Rossum97250cb1997-12-15 17:55:53 +000099#include "gmp-mparam.h"
Guido van Rossume7ef74d2000-02-24 15:26:30 +0000100#endif
Guido van Rossum272841c1996-08-19 23:06:45 +0000101
Guido van Rossum57e846f1997-08-17 19:08:33 +0000102#if __GNU_MP__ + 0 == 2
Guido van Rossum272841c1996-08-19 23:06:45 +0000103#define GMP2
104#else
105#define MPZ_GET_STR_BUG
106#endif
107
Guido van Rossum5f59d601992-12-14 16:59:51 +0000108typedef struct {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000109 PyObject_HEAD
Guido van Rossum5f59d601992-12-14 16:59:51 +0000110 MP_INT mpz; /* the actual number */
111} mpzobject;
112
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000113staticforward PyTypeObject MPZtype;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000114
115#define is_mpzobject(v) ((v)->ob_type == &MPZtype)
116
117static const char initialiser_name[] = "mpz";
118
119/* #define MPZ_DEBUG */
120
121static mpzobject *
122newmpzobject()
123{
124 mpzobject *mpzp;
125
126
127#ifdef MPZ_DEBUG
128 fputs( "mpz_object() called...\n", stderr );
129#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000130 mpzp = PyObject_NEW(mpzobject, &MPZtype);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000131 if (mpzp == NULL)
132 return NULL;
133
134 mpz_init(&mpzp->mpz); /* actual initialisation */
135 return mpzp;
136} /* newmpzobject() */
137
138#ifdef MPZ_GET_STR_BUG
Guido van Rossum5f59d601992-12-14 16:59:51 +0000139#include "longlong.h"
140#endif /* def MPZ_GET_STR_BUG */
141
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000142static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000143mpz_format(objp, base, withname)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000144 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000145 int base;
146 unsigned char withname;
147{
148 mpzobject *mpzp = (mpzobject *)objp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000149 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000150 int i;
151 int cmpres;
152 int taglong;
153 char *cp;
154 char prefix[5], *tcp;
155
156
157 tcp = &prefix[0];
158
159 if (mpzp == NULL || !is_mpzobject(mpzp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000160 PyErr_BadInternalCall();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000161 return NULL;
162 }
163
164 assert(base >= 2 && base <= 36);
165
166 if (withname)
167 i = strlen(initialiser_name) + 2; /* e.g. 'mpz(' + ')' */
168 else
169 i = 0;
170
171 if ((cmpres = mpz_cmp_si(&mpzp->mpz, 0L)) == 0)
172 base = 10; /* '0' in every base, right */
173 else if (cmpres < 0) {
174 *tcp++ = '-';
175 i += 1; /* space to hold '-' */
176 }
177
178#ifdef MPZ_DEBUG
179 fprintf(stderr, "mpz_format: mpz_sizeinbase %d\n",
180 (int)mpz_sizeinbase(&mpzp->mpz, base));
181#endif /* def MPZ_DEBUG */
182#ifdef MPZ_GET_STR_BUG
Guido van Rossum272841c1996-08-19 23:06:45 +0000183#ifdef GMP2
184 i += ((size_t) abs(mpzp->mpz._mp_size) * BITS_PER_MP_LIMB
185 * __mp_bases[base].chars_per_bit_exactly) + 1;
186#else
Guido van Rossum5f59d601992-12-14 16:59:51 +0000187 i += ((size_t) abs(mpzp->mpz.size) * BITS_PER_MP_LIMB
188 * __mp_bases[base].chars_per_bit_exactly) + 1;
Guido van Rossum272841c1996-08-19 23:06:45 +0000189#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +0000190#else /* def MPZ_GET_STR_BUG */
191 i += (int)mpz_sizeinbase(&mpzp->mpz, base);
192#endif /* def MPZ_GET_STR_BUG else */
193
194 if (base == 16) {
195 *tcp++ = '0';
196 *tcp++ = 'x';
197 i += 2; /* space to hold '0x' */
198 }
199 else if (base == 8) {
200 *tcp++ = '0';
201 i += 1; /* space to hold the extra '0' */
202 }
203 else if (base > 10) {
204 *tcp++ = '0' + base / 10;
205 *tcp++ = '0' + base % 10;
206 *tcp++ = '#';
207 i += 3; /* space to hold e.g. '12#' */
208 }
209 else if (base < 10) {
210 *tcp++ = '0' + base;
211 *tcp++ = '#';
212 i += 2; /* space to hold e.g. '6#' */
213 }
214
215 /*
216 ** the following code looks if we need a 'L' attached to the number
217 ** it will also attach an 'L' to the value -0x80000000
218 */
219 taglong = 0;
220 if (mpz_size(&mpzp->mpz) > 1
221 || (long)mpz_get_ui(&mpzp->mpz) < 0L) {
222 taglong = 1;
223 i += 1; /* space to hold 'L' */
224 }
225
226#ifdef MPZ_DEBUG
227 fprintf(stderr, "mpz_format: requesting string size %d\n", i);
228#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000229 if ((strobjp =
230 (PyStringObject *)PyString_FromStringAndSize((char *)0, i))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000231 == NULL)
232 return NULL;
233
234 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000235 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000236 if (withname) {
237 strcpy(cp, initialiser_name);
238 cp += strlen(initialiser_name);
239 *cp++ = '('; /*')'*/
240 }
241
242 /* copy the already prepared prefix; e.g. sign and base indicator */
243 *tcp = '\0';
244 strcpy(cp, prefix);
245 cp += tcp - prefix;
246
247 /* since' we have the sign already, let the lib think it's a positive
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000248 number */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000249 if (cmpres < 0)
250 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
251 (void)mpz_get_str(cp, base, &mpzp->mpz);
252 if (cmpres < 0)
253 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
254#ifdef MPZ_DEBUG
255 fprintf(stderr, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
256 base, cp);
257#endif /* def MPZ_DEBUG */
258 cp += strlen(cp);
259
260 if (taglong)
261 *cp++ = 'L';
262 if (withname)
263 *cp++ = /*'('*/ ')';
264
265 *cp = '\0';
266
267#ifdef MPZ_DEBUG
268 fprintf(stderr,
269 "mpz_format: cp (str end) 0x%x, begin 0x%x, diff %d, i %d\n",
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000270 cp, PyString_AS_STRING(strobjp),
271 cp - PyString_AS_STRING(strobjp), i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000272#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000273 assert(cp - PyString_AS_STRING(strobjp) <= i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000274
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000275 if (cp - PyString_AS_STRING(strobjp) != i) {
276 strobjp->ob_size -= i - (cp - PyString_AS_STRING(strobjp));
Guido van Rossum5f59d601992-12-14 16:59:51 +0000277 }
278
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000279 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000280} /* mpz_format() */
281
282/* MPZ methods */
283
284static void
285mpz_dealloc(mpzp)
286 mpzobject *mpzp;
287{
288#ifdef MPZ_DEBUG
289 fputs( "mpz_dealloc() called...\n", stderr );
290#endif /* def MPZ_DEBUG */
291 mpz_clear(&mpzp->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000292 PyMem_DEL(mpzp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000293} /* mpz_dealloc() */
294
Guido van Rossum5f59d601992-12-14 16:59:51 +0000295
296/* pointers to frequently used values 0, 1 and -1 */
297static mpzobject *mpz_value_zero, *mpz_value_one, *mpz_value_mone;
298
299static int
300mpz_compare(a, b)
301 mpzobject *a, *b;
302{
303 int cmpres;
304
305
306 /* guido sez it's better to return -1, 0 or 1 */
307 return (cmpres = mpz_cmp( &a->mpz, &b->mpz )) == 0 ? 0
308 : cmpres > 0 ? 1 : -1;
309} /* mpz_compare() */
310
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000311static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000312mpz_addition(a, b)
313 mpzobject *a;
314 mpzobject *b;
315{
316 mpzobject *z;
317
318
319#ifdef MPZ_SPARE_MALLOC
320 if (mpz_cmp_ui(&a->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000321 Py_INCREF(b);
322 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000323 }
324
325 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000326 Py_INCREF(a);
327 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000328 }
329#endif /* def MPZ_SPARE_MALLOC */
330
331 if ((z = newmpzobject()) == NULL)
332 return NULL;
333
334 mpz_add(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000335 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000336} /* mpz_addition() */
337
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000338static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000339mpz_substract(a, b)
340 mpzobject *a;
341 mpzobject *b;
342{
343 mpzobject *z;
344
345
346#ifdef MPZ_SPARE_MALLOC
347 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000348 Py_INCREF(a);
349 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000350 }
351#endif /* MPZ_SPARE_MALLOC */
352
353 if ((z = newmpzobject()) == NULL)
354 return NULL;
355
356 mpz_sub(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000357 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000358} /* mpz_substract() */
359
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000360static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000361mpz_multiply(a, b)
362 mpzobject *a;
363 mpzobject *b;
364{
365#ifdef MPZ_SPARE_MALLOC
366 int cmpres;
367#endif /* def MPZ_SPARE_MALLOC */
368 mpzobject *z;
369
370
371#ifdef MPZ_SPARE_MALLOC
372 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000373 Py_INCREF(mpz_value_zero);
374 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000375 }
376 if (cmpres > 0 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000377 Py_INCREF(b);
378 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000379 }
380
381 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long_int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000382 Py_INCREF(mpz_value_zero);
383 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000384 }
385 if (cmpres > 0 && mpz_cmp_ui(&b->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000386 Py_INCREF(a);
387 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000388 }
389#endif /* MPZ_SPARE_MALLOC */
390
391 if ((z = newmpzobject()) == NULL)
392 return NULL;
393
394 mpz_mul( &z->mpz, &a->mpz, &b->mpz );
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000395 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000396
397} /* mpz_multiply() */
398
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000399static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000400mpz_divide(a, b)
401 mpzobject *a;
402 mpzobject *b;
403{
404#ifdef MPZ_SPARE_MALLOC
405 int cmpres;
406#endif /* def MPZ_SPARE_MALLOC */
407 mpzobject *z;
408
409
410 if ((
411#ifdef MPZ_SPARE_MALLOC
412 cmpres =
413#endif /* def MPZ_SPARE_MALLOC */
414 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000415 PyErr_SetString(PyExc_ZeroDivisionError, "mpz./ by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000416 return NULL;
417 }
418#ifdef MPZ_SPARE_MALLOC
419 if (cmpres > 0 && mpz_cmp_ui(&b->mpz(unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000420 Py_INCREF(a);
421 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000422 }
423#endif /* def MPZ_SPARE_MALLOC */
424
425 if ((z = newmpzobject()) == NULL)
426 return NULL;
427
428#ifdef MPZ_TEST_DIV
429 fputs("mpz_divide: div result", stderr);
430 mpz_div(&z->mpz, &a->mpz, &b->mpz);
431 mpz_out_str(stderr, 10, &z->mpz);
432 putc('\n', stderr);
433#endif /* def MPZ_TEST_DIV */
434#ifdef MPZ_MDIV_BUG
435 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
436 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)) {
437 /*
438 ** numerator has other sign than denominator: we have
439 ** to look at the remainder for a correction, since mpz_mdiv
440 ** also calls mpz_divmod, I can as well do it myself
441 */
442 MP_INT tmpmpz;
443
444
445 mpz_init(&tmpmpz);
446 mpz_divmod(&z->mpz, &tmpmpz, &a->mpz, &b->mpz);
447
448 if (mpz_cmp_ui(&tmpmpz, (unsigned long int)0) != 0)
449 mpz_sub_ui(&z->mpz, &z->mpz, (unsigned long int)1);
450
451 mpz_clear(&tmpmpz);
452 }
453 else
454 mpz_div(&z->mpz, &a->mpz, &b->mpz);
455 /* the ``naive'' implementation does it right for operands
456 having the same sign */
457
458#else /* def MPZ_MDIV_BUG */
459 mpz_mdiv(&z->mpz, &a->mpz, &b->mpz);
460#endif /* def MPZ_MDIV_BUG else */
461#ifdef MPZ_TEST_DIV
462 fputs("mpz_divide: mdiv result", stderr);
463 mpz_out_str(stderr, 10, &z->mpz);
464 putc('\n', stderr);
465#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000466 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000467
468} /* mpz_divide() */
469
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000470static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000471mpz_remainder(a, b)
472 mpzobject *a;
473 mpzobject *b;
474{
475#ifdef MPZ_SPARE_MALLOC
476 int cmpres;
477#endif /* def MPZ_SPARE_MALLOC */
478 mpzobject *z;
479
480
481 if ((
482#ifdef MPZ_SPARE_MALLOC
483 cmpres =
484#endif /* def MPZ_SPARE_MALLOC */
485 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000486 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.% by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000487 return NULL;
488 }
489#ifdef MPZ_SPARE_MALLOC
490 if (cmpres > 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000491 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)2)) == 0)
492 {
493 Py_INCREF(mpz_value_one);
494 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000495 }
496 if (cmpres < 0) {
497 /* b must be 1 now */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000498 Py_INCREF(mpz_value_zero);
499 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000500 }
501 }
502#endif /* def MPZ_SPARE_MALLOC */
503
504 if ((z = newmpzobject()) == NULL)
505 return NULL;
506
507#ifdef MPZ_TEST_DIV
508 fputs("mpz_remain: mod result", stderr);
509 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
510 mpz_out_str(stderr, 10, &z->mpz);
511 putc('\n', stderr);
512#endif /* def MPZ_TEST_DIV */
513#ifdef MPZ_MDIV_BUG
514
515 /* the ``naive'' implementation does it right for operands
516 having the same sign */
517 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
518
519 /* assumption: z, a and b all point to different locations */
520 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
521 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
522 && mpz_cmp_ui(&z->mpz, (unsigned long int)0) != 0)
523 mpz_add(&z->mpz, &z->mpz, &b->mpz);
524 /*
525 ** numerator has other sign than denominator: we have
526 ** to look at the remainder for a correction, since mpz_mdiv
527 ** also calls mpz_divmod, I can as well do it myself
528 */
529#else /* def MPZ_MDIV_BUG */
530 mpz_mmod(&z->mpz, &a->mpz, &b->mpz);
531#endif /* def MPZ_MDIV_BUG else */
532#ifdef MPZ_TEST_DIV
533 fputs("mpz_remain: mmod result", stderr);
534 mpz_out_str(stderr, 10, &z->mpz);
535 putc('\n', stderr);
536#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000537 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000538
539} /* mpz_remainder() */
540
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000541static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000542mpz_div_and_mod(a, b)
543 mpzobject *a;
544 mpzobject *b;
545{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000546 PyObject *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000547 mpzobject *x = NULL, *y = NULL;
548
549
550 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000551 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.divmod by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000552 return NULL;
553 }
554
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000555 if ((z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +0000556 || (x = newmpzobject()) == NULL
557 || (y = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000558 Py_XDECREF(z);
559 Py_XDECREF(x);
560 Py_XDECREF(y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000561 return NULL;
562 }
563
564#ifdef MPZ_TEST_DIV
565 fputs("mpz_divmod: dm result", stderr);
566 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
567 mpz_out_str(stderr, 10, &x->mpz);
568 putc('\n', stderr);
569 mpz_out_str(stderr, 10, &y->mpz);
570 putc('\n', stderr);
571#endif /* def MPZ_TEST_DIV */
572#ifdef MPZ_MDIV_BUG
573 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
574 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
575 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
576 && mpz_cmp_ui(&y->mpz, (unsigned long int)0) != 0) {
577 /*
578 ** numerator has other sign than denominator: we have
579 ** to look at the remainder for a correction.
580 */
581 mpz_add(&y->mpz, &y->mpz, &b->mpz);
582 mpz_sub_ui(&x->mpz, &x->mpz, (unsigned long int)1);
583 }
584#else /* def MPZ_MDIV_BUG */
585 mpz_mdivmod( &x->mpz, &y->mpz, &a->mpz, &b->mpz );
586#endif /* def MPZ_MDIV_BUG else */
587#ifdef MPZ_TEST_DIV
588 fputs("mpz_divmod: mdm result", stderr);
589 mpz_out_str(stderr, 10, &x->mpz);
590 putc('\n', stderr);
591 mpz_out_str(stderr, 10, &y->mpz);
592 putc('\n', stderr);
593#endif /* def MPZ_TEST_DIV */
594
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000595 (void)PyTuple_SetItem(z, 0, (PyObject *)x);
596 (void)PyTuple_SetItem(z, 1, (PyObject *)y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000597
598 return z;
599} /* mpz_div_and_mod() */
600
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000601static PyObject *
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000602mpz_power(a, b, m)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000603 mpzobject *a;
604 mpzobject *b;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000605 mpzobject *m;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000606{
607 mpzobject *z;
608 int cmpres;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000609
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000610 if ((PyObject *)m != Py_None) {
611 mpzobject *z2;
612 Py_INCREF(Py_None);
613 z=(mpzobject *)mpz_power(a, b, (mpzobject *)Py_None);
614 Py_DECREF(Py_None);
615 if (z==NULL) return((PyObject *)z);
616 z2=(mpzobject *)mpz_remainder(z, m);
617 Py_DECREF(z);
618 return((PyObject *)z2);
619 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000620
621 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
622 /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
623
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000624 Py_INCREF(mpz_value_one);
625 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000626 }
627
628 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000629 PyErr_SetString(PyExc_ValueError,
630 "mpz.pow to negative exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000631 return NULL;
632 }
633
634 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
635 /* the base is 0 */
636
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000637 Py_INCREF(mpz_value_zero);
638 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000639 }
640 else if (cmpres > 0
641 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
642 /* the base is 1 */
643
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000644 Py_INCREF(mpz_value_one);
645 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000646 }
647 else if (cmpres < 0
648 && mpz_cmp_si(&a->mpz, (long int)-1) == 0) {
649
650 MP_INT tmpmpz;
651 /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
652 /* XXX this code needs to be optimized: what's better?
653 mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
654 for *un*obvious reasons */
655
656 /* is the exponent even? */
657 mpz_init(&tmpmpz);
658
659 /* look to the remainder after a division by (1 << 1) */
660 mpz_mod_2exp(&tmpmpz, &b->mpz, (unsigned long int)1);
661
662 if (mpz_cmp_ui(&tmpmpz, (unsigned int)0) == 0) {
663 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000664 Py_INCREF(mpz_value_one);
665 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000666 }
667 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000668 Py_INCREF(mpz_value_mone);
669 return (PyObject *)mpz_value_mone;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000670 }
671
672#ifdef MPZ_LIB_DOES_CHECKING
673 /* check if it's doable: sizeof(exp) > sizeof(long) &&
674 abs(base) > 1 ?? --> No Way */
675 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000676 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000677#else /* def MPZ_LIB_DOES_CHECKING */
678 /* wet finger method */
679 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000680 PyErr_SetString(PyExc_ValueError,
681 "mpz.pow outrageous exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000682 return NULL;
683 }
684#endif /* def MPZ_LIB_DOES_CHECKING else */
685
686 if ((z = newmpzobject()) == NULL)
687 return NULL;
688
689 mpz_pow_ui(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
690
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000691 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000692} /* mpz_power() */
693
694
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000695static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000696mpz_negative(v)
697 mpzobject *v;
698{
699 mpzobject *z;
700
701
702#ifdef MPZ_SPARE_MALLOC
703 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) == 0) {
704 /* -0 == 0 */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000705 Py_INCREF(v);
706 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000707 }
708#endif /* def MPZ_SPARE_MALLOC */
709
710 if ((z = newmpzobject()) == NULL)
711 return NULL;
712
713 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000714 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000715} /* mpz_negative() */
716
717
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000718static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000719mpz_positive(v)
720 mpzobject *v;
721{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000722 Py_INCREF(v);
723 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000724} /* mpz_positive() */
725
726
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000727static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000728mpz_absolute(v)
729 mpzobject *v;
730{
731 mpzobject *z;
732
733
734 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000735 Py_INCREF(v);
736 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000737 }
738
739 if ((z = newmpzobject()) == NULL)
740 return NULL;
741
742 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000743 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000744} /* mpz_absolute() */
745
746static int
747mpz_nonzero(v)
748 mpzobject *v;
749{
750 return mpz_cmp_ui(&v->mpz, (unsigned long int)0) != 0;
751} /* mpz_nonzero() */
752
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000753static PyObject *
Guido van Rossum272841c1996-08-19 23:06:45 +0000754py_mpz_invert(v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000755 mpzobject *v;
756{
757 mpzobject *z;
758
759
760 /* I think mpz_com does exactly what needed */
761 if ((z = newmpzobject()) == NULL)
762 return NULL;
763
764 mpz_com(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000765 return (PyObject *)z;
Guido van Rossum272841c1996-08-19 23:06:45 +0000766} /* py_mpz_invert() */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000767
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000768static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000769mpz_lshift(a, b)
770 mpzobject *a;
771 mpzobject *b;
772{
773 int cmpres;
774 mpzobject *z;
775
776
777 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
778 /* a << 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000779 Py_INCREF(a);
780 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000781 }
782
783 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000784 PyErr_SetString(PyExc_ValueError,
785 "mpz.<< negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000786 return NULL;
787 }
788
789#ifdef MPZ_LIB_DOES_CHECKING
790 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000791 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000792#else /* def MPZ_LIB_DOES_CHECKING */
793 /* wet finger method */
794 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000795 PyErr_SetString(PyExc_ValueError,
796 "mpz.<< outrageous shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000797 return NULL;
798 }
799#endif /* def MPZ_LIB_DOES_CHECKING else */
800
801 if ((z = newmpzobject()) == NULL)
802 return NULL;
803
804 mpz_mul_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000805 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000806} /* mpz_lshift() */
807
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000808static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000809mpz_rshift(a, b)
810 mpzobject *a;
811 mpzobject *b;
812{
813 int cmpres;
814 mpzobject *z;
815
816
817 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
818 /* a >> 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000819 Py_INCREF(a);
820 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000821 }
822
823 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000824 PyErr_SetString(PyExc_ValueError,
825 "mpz.>> negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000826 return NULL;
827 }
828
829 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000830 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000831
832 if ((z = newmpzobject()) == NULL)
833 return NULL;
834
835 mpz_div_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000836 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000837} /* mpz_rshift() */
838
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000839static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000840mpz_andfunc(a, b)
841 mpzobject *a;
842 mpzobject *b;
843{
844 mpzobject *z;
845
846
847 if ((z = newmpzobject()) == NULL)
848 return NULL;
849
850 mpz_and(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000851 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000852} /* mpz_andfunc() */
853
854/* hack Hack HAck HACk HACK, XXX this code is dead slow */
855void
856mpz_xor(res, op1, op2)
857 MP_INT *res;
858 const MP_INT *op1;
859 const MP_INT *op2;
860{
861 MP_INT tmpmpz;
862
863 mpz_init(&tmpmpz);
864
865 mpz_and(res, op1, op2);
866 mpz_com(&tmpmpz, res);
867 mpz_ior(res, op1, op2);
868 mpz_and(res, res, &tmpmpz);
869
870 mpz_clear(&tmpmpz);
871} /* mpz_xor() HACK */
872
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000873static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000874mpz_xorfunc(a, b)
875 mpzobject *a;
876 mpzobject *b;
877{
878 mpzobject *z;
879
880
881 if ((z = newmpzobject()) == NULL)
882 return NULL;
883
884 mpz_xor(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000885 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000886} /* mpz_xorfunc() */
887
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000888static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000889mpz_orfunc(a, b)
890 mpzobject *a;
891 mpzobject *b;
892{
893 mpzobject *z;
894
895
896 if ((z = newmpzobject()) == NULL)
897 return NULL;
898
899 mpz_ior(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000900 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000901} /* mpz_orfunc() */
902
903/* MPZ initialisation */
904
905#include "longintrepr.h"
906
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000907static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000908MPZ_mpz(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000909 PyObject *self;
910 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000911{
912 mpzobject *mpzp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000913 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000914
915
916#ifdef MPZ_DEBUG
917 fputs("MPZ_mpz() called...\n", stderr);
918#endif /* def MPZ_DEBUG */
919
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000920 if (!PyArg_Parse(args, "O", &objp))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000921 return NULL;
922
923 /* at least we know it's some object */
Barry Warsawabb7efe1996-12-09 23:22:35 +0000924 /* note DON't Py_DECREF args NEITHER objp */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000925
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000926 if (PyInt_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000927 long lval;
928
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000929 if (!PyArg_Parse(objp, "l", &lval))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000930 return NULL;
931
932 if (lval == (long)0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000933 Py_INCREF(mpz_value_zero);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000934 mpzp = mpz_value_zero;
935 }
936 else if (lval == (long)1) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000937 Py_INCREF(mpz_value_one);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000938 mpzp = mpz_value_one;
939 }
940 else if ((mpzp = newmpzobject()) == NULL)
941 return NULL;
942 else mpz_set_si(&mpzp->mpz, lval);
943 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000944 else if (PyLong_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000945 MP_INT mplongdigit;
946 int i;
947 unsigned char isnegative;
948
949
950 if ((mpzp = newmpzobject()) == NULL)
951 return NULL;
952
953 mpz_set_si(&mpzp->mpz, 0L);
954 mpz_init(&mplongdigit);
955
956 /* how we're gonna handle this? */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000957 if ((isnegative =
958 ((i = ((PyLongObject *)objp)->ob_size) < 0) ))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000959 i = -i;
960
961 while (i--) {
962 mpz_set_ui(&mplongdigit,
963 (unsigned long)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000964 ((PyLongObject *)objp)->ob_digit[i]);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000965 mpz_mul_2exp(&mplongdigit,&mplongdigit,
966 (unsigned long int)i * SHIFT);
967 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
968 }
969
970 if (isnegative)
971 mpz_neg(&mpzp->mpz, &mpzp->mpz);
972
973 /* get rid of allocation for tmp variable */
974 mpz_clear(&mplongdigit);
975 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000976 else if (PyString_Check(objp)) {
Andrew M. Kuchling4c07f811998-12-14 19:36:14 +0000977 unsigned char *cp = (unsigned char *)PyString_AS_STRING(objp);
Guido van Rossum7e488981998-10-08 02:25:24 +0000978 int len = PyString_GET_SIZE(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000979 MP_INT mplongdigit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000980
981 if ((mpzp = newmpzobject()) == NULL)
982 return NULL;
983
984 mpz_set_si(&mpzp->mpz, 0L);
985 mpz_init(&mplongdigit);
986
987 /* let's do it the same way as with the long conversion:
988 without thinking how it can be faster (-: :-) */
989
990 cp += len;
991 while (len--) {
992 mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
993 mpz_mul_2exp(&mplongdigit,&mplongdigit,
994 (unsigned long int)len * 8);
995 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
996 }
997
998 /* get rid of allocation for tmp variable */
999 mpz_clear(&mplongdigit);
1000 }
1001 else if (is_mpzobject(objp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001002 Py_INCREF(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001003 mpzp = (mpzobject *)objp;
1004 }
1005 else {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001006 PyErr_SetString(PyExc_TypeError,
1007"mpz.mpz() expects integer, long, string or mpz object argument");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001008 return NULL;
1009 }
1010
1011
1012#ifdef MPZ_DEBUG
1013 fputs("MPZ_mpz: created mpz=", stderr);
1014 mpz_out_str(stderr, 10, &mpzp->mpz);
1015 putc('\n', stderr);
1016#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001017 return (PyObject *)mpzp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001018} /* MPZ_mpz() */
1019
1020static mpzobject *
1021mpz_mpzcoerce(z)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001022 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001023{
1024 /* shortcut: 9 out of 10 times the type is already ok */
1025 if (is_mpzobject(z)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001026 Py_INCREF(z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001027 return (mpzobject *)z; /* coercion succeeded */
1028 }
1029
1030 /* what types do we accept?: intobjects and longobjects */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001031 if (PyInt_Check(z) || PyLong_Check(z))
1032 return (mpzobject *)MPZ_mpz((PyObject *)NULL, z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001033
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001034 PyErr_SetString(PyExc_TypeError,
1035 "number coercion (to mpzobject) failed");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001036 return NULL;
1037} /* mpz_mpzcoerce() */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001038
1039/* Forward */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001040static void mpz_divm Py_PROTO((MP_INT *res, const MP_INT *num,
1041 const MP_INT *den, const MP_INT *mod));
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001042
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001043static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001044MPZ_powm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001045 PyObject *self;
1046 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001047{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001048 PyObject *base, *exp, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001049 mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
1050 mpzobject *z;
1051 int tstres;
1052
1053
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001054 if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001055 return NULL;
1056
1057 if ((mpzbase = mpz_mpzcoerce(base)) == NULL
1058 || (mpzexp = mpz_mpzcoerce(exp)) == NULL
1059 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1060 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001061 Py_XDECREF(mpzbase);
1062 Py_XDECREF(mpzexp);
1063 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001064 return NULL;
1065 }
1066
1067 if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001068 Py_INCREF(mpz_value_one);
1069 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001070 }
1071
1072 if (tstres < 0) {
1073 MP_INT absexp;
1074 /* negative exp */
1075
1076 mpz_init_set(&absexp, &mpzexp->mpz);
1077 mpz_abs(&absexp, &absexp);
1078 mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
1079
1080 mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
1081
1082 mpz_clear(&absexp);
1083 }
1084 else {
1085 mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
1086 }
1087
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001088 Py_DECREF(mpzbase);
1089 Py_DECREF(mpzexp);
1090 Py_DECREF(mpzmod);
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_powm() */
1094
1095
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001096static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001097MPZ_gcd(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001098 PyObject *self;
1099 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001100{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001101 PyObject *op1, *op2;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001102 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1103 mpzobject *z;
1104
1105
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001106 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001107 return NULL;
1108
1109 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1110 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
1111 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001112 Py_XDECREF(mpzop1);
1113 Py_XDECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001114 return NULL;
1115 }
1116
1117 /* ok, we have three mpzobjects, and an initialised result holder */
1118 mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
1119
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001120 Py_DECREF(mpzop1);
1121 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001122
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001123 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001124} /* MPZ_gcd() */
1125
1126
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001127static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001128MPZ_gcdext(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001129 PyObject *self;
1130 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001131{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001132 PyObject *op1, *op2, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001133 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1134 mpzobject *g = NULL, *s = NULL, *t = NULL;
1135
1136
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001137 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001138 return NULL;
1139
1140 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1141 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001142 || (z = PyTuple_New(3)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001143 || (g = newmpzobject()) == NULL
1144 || (s = newmpzobject()) == NULL
1145 || (t = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001146 Py_XDECREF(mpzop1);
1147 Py_XDECREF(mpzop2);
1148 Py_XDECREF(z);
1149 Py_XDECREF(g);
1150 Py_XDECREF(s);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001151 /*Py_XDECREF(t);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001152 return NULL;
1153 }
1154
1155 mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
1156
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001157 Py_DECREF(mpzop1);
1158 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001159
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001160 (void)PyTuple_SetItem(z, 0, (PyObject *)g);
1161 (void)PyTuple_SetItem(z, 1, (PyObject *)s);
1162 (void)PyTuple_SetItem(z, 2, (PyObject *)t);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001163
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001164 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001165} /* MPZ_gcdext() */
1166
1167
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001168static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001169MPZ_sqrt(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001170 PyObject *self;
1171 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001172{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001173 PyObject *op;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001174 mpzobject *mpzop = NULL;
1175 mpzobject *z;
1176
1177
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001178 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001179 return NULL;
1180
1181 if ((mpzop = mpz_mpzcoerce(op)) == NULL
1182 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001183 Py_XDECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001184 return NULL;
1185 }
1186
1187 mpz_sqrt(&z->mpz, &mpzop->mpz);
1188
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001189 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001190
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001191 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001192} /* MPZ_sqrt() */
1193
1194
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001195static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001196MPZ_sqrtrem(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001197 PyObject *self;
1198 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001199{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001200 PyObject *op, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001201 mpzobject *mpzop = NULL;
1202 mpzobject *root = NULL, *rem = NULL;
1203
1204
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001205 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001206 return NULL;
1207
1208 if ((mpzop = mpz_mpzcoerce(op)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001209 || (z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001210 || (root = newmpzobject()) == NULL
1211 || (rem = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001212 Py_XDECREF(mpzop);
1213 Py_XDECREF(z);
1214 Py_XDECREF(root);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001215 /*Py_XDECREF(rem);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001216 return NULL;
1217 }
1218
1219 mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
1220
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001221 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001222
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001223 (void)PyTuple_SetItem(z, 0, (PyObject *)root);
1224 (void)PyTuple_SetItem(z, 1, (PyObject *)rem);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001225
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001226 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001227} /* MPZ_sqrtrem() */
1228
1229
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001230static void
Guido van Rossum5f59d601992-12-14 16:59:51 +00001231#if __STDC__
1232mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
1233#else
1234mpz_divm(res, num, den, mod)
1235 MP_INT *res;
1236 const MP_INT *num;
1237 const MP_INT *den;
1238 const MP_INT *mod;
1239#endif
1240{
1241 MP_INT s0, s1, q, r, x, d0, d1;
1242
1243 mpz_init_set(&s0, num);
1244 mpz_init_set_ui(&s1, 0);
1245 mpz_init(&q);
1246 mpz_init(&r);
1247 mpz_init(&x);
1248 mpz_init_set(&d0, den);
1249 mpz_init_set(&d1, mod);
1250
Guido van Rossum272841c1996-08-19 23:06:45 +00001251#ifdef GMP2
1252 while (d1._mp_size != 0) {
1253#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001254 while (d1.size != 0) {
Guido van Rossum272841c1996-08-19 23:06:45 +00001255#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001256 mpz_divmod(&q, &r, &d0, &d1);
1257 mpz_set(&d0, &d1);
1258 mpz_set(&d1, &r);
1259
1260 mpz_mul(&x, &s1, &q);
1261 mpz_sub(&x, &s0, &x);
1262 mpz_set(&s0, &s1);
1263 mpz_set(&s1, &x);
1264 }
1265
Guido van Rossum272841c1996-08-19 23:06:45 +00001266#ifdef GMP2
1267 if (d0._mp_size != 1 || d0._mp_d[0] != 1)
1268 res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
1269#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001270 if (d0.size != 1 || d0.d[0] != 1)
1271 res->size = 0; /* trouble: the gcd != 1; set s to zero */
Guido van Rossum272841c1996-08-19 23:06:45 +00001272#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001273 else {
1274#ifdef MPZ_MDIV_BUG
1275 /* watch out here! first check the signs, and then perform
1276 the mpz_mod() since mod could point to res */
1277 if ((s0.size < 0) != (mod->size < 0)) {
1278 mpz_mod(res, &s0, mod);
1279
1280 if (res->size)
1281 mpz_add(res, res, mod);
1282 }
1283 else
1284 mpz_mod(res, &s0, mod);
1285
1286#else /* def MPZ_MDIV_BUG */
1287 mpz_mmod(res, &s0, mod);
1288#endif /* def MPZ_MDIV_BUG else */
1289 }
1290
1291 mpz_clear(&s0);
1292 mpz_clear(&s1);
1293 mpz_clear(&q);
1294 mpz_clear(&r);
1295 mpz_clear(&x);
1296 mpz_clear(&d0);
1297 mpz_clear(&d1);
1298} /* mpz_divm() */
1299
1300
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001301static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001302MPZ_divm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001303 PyObject *self;
1304 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001305{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001306 PyObject *num, *den, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001307 mpzobject *mpznum, *mpzden, *mpzmod = NULL;
1308 mpzobject *z = NULL;
1309
1310
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001311 if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001312 return NULL;
1313
1314 if ((mpznum = mpz_mpzcoerce(num)) == NULL
1315 || (mpzden = mpz_mpzcoerce(den)) == NULL
1316 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1317 || (z = newmpzobject()) == NULL ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001318 Py_XDECREF(mpznum);
1319 Py_XDECREF(mpzden);
1320 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001321 return NULL;
1322 }
1323
1324 mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
1325
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001326 Py_DECREF(mpznum);
1327 Py_DECREF(mpzden);
1328 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001329
1330 if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001331 Py_DECREF(z);
1332 PyErr_SetString(PyExc_ValueError,
1333 "gcd(den, mod) != 1 or num == 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001334 return NULL;
1335 }
1336
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001337 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001338} /* MPZ_divm() */
1339
1340
1341/* MPZ methods-as-attributes */
1342#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001343static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001344mpz_int(self, args)
1345 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001346 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001347#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001348static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001349mpz_int(self)
1350 mpzobject *self;
1351#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1352{
1353 long sli;
1354
1355
1356#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001357 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001358 return NULL;
1359#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1360
1361 if (mpz_size(&self->mpz) > 1
1362 || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001363 PyErr_SetString(PyExc_ValueError,
1364 "mpz.int() arg too long to convert");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001365 return NULL;
1366 }
1367
1368 if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
1369 sli = -sli;
1370
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001371 return PyInt_FromLong(sli);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001372} /* mpz_int() */
1373
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001374static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001375#ifdef MPZ_CONVERSIONS_AS_METHODS
1376mpz_long(self, args)
1377 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001378 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001379#else /* def MPZ_CONVERSIONS_AS_METHODS */
1380mpz_long(self)
1381 mpzobject *self;
1382#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1383{
1384 int i, isnegative;
1385 unsigned long int uli;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001386 PyLongObject *longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001387 int ldcount;
1388 int bitpointer, newbitpointer;
1389 MP_INT mpzscratch;
1390
1391
1392#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001393 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001394 return NULL;
1395#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1396
1397 /* determine length of python-long to be allocated */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001398 if ((longobjp = _PyLong_New(i = (int)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001399 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
1400 + SHIFT - 1) /
1401 SHIFT))) == NULL)
1402 return NULL;
1403
1404 /* determine sign, and copy self to scratch var */
1405 mpz_init_set(&mpzscratch, &self->mpz);
Guido van Rossum272841c1996-08-19 23:06:45 +00001406 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001407 mpz_neg(&mpzscratch, &mpzscratch);
1408
1409 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001410 e.g. dismantle mpzscratch, build PyLongObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001411
1412 bitpointer = 0; /* the number of valid bits in stock */
1413 newbitpointer = 0;
1414 ldcount = 0; /* the python-long limb counter */
1415 uli = (unsigned long int)0;
1416 while (i--) {
1417 longobjp->ob_digit[ldcount] = uli & MASK;
1418
1419 /* check if we've had enough bits for this digit */
1420 if (bitpointer < SHIFT) {
1421 uli = mpz_get_ui(&mpzscratch);
1422 longobjp->ob_digit[ldcount] |=
1423 (uli << bitpointer) & MASK;
1424 uli >>= SHIFT-bitpointer;
1425 bitpointer += BITS_PER_MP_LIMB;
1426 mpz_div_2exp(&mpzscratch, &mpzscratch,
1427 BITS_PER_MP_LIMB);
1428 }
1429 else
1430 uli >>= SHIFT;
1431 bitpointer -= SHIFT;
1432 ldcount++;
1433 }
1434
1435 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1436 mpz_clear(&mpzscratch);
1437 assert(ldcount <= longobjp->ob_size);
1438
1439 /* long_normalize() is file-static */
1440 /* longobjp = long_normalize(longobjp); */
1441 while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
1442 ldcount--;
1443 longobjp->ob_size = ldcount;
1444
1445
1446 if (isnegative)
1447 longobjp->ob_size = -longobjp->ob_size;
1448
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001449 return (PyObject *)longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001450
1451} /* mpz_long() */
1452
1453
1454/* I would have avoided pow() anyways, so ... */
1455static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
1456
1457#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001458static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001459mpz_float(self, args)
1460 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001461 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001462#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001463static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001464mpz_float(self)
1465 mpzobject *self;
1466#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1467{
1468 int i, isnegative;
1469 double x;
1470 double mulstate;
1471 MP_INT mpzscratch;
1472
1473
1474#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001475 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001476 return NULL;
1477#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1478
1479 i = (int)mpz_size(&self->mpz);
1480
1481 /* determine sign, and copy abs(self) to scratch var */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001482 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
1483 {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001484 mpz_init(&mpzscratch);
1485 mpz_neg(&mpzscratch, &self->mpz);
1486 }
1487 else
1488 mpz_init_set(&mpzscratch, &self->mpz);
1489
1490 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001491 e.g. dismantle mpzscratch, build PyFloatObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001492
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001493 /* Can this overflow? Dunno, protect against that possibility. */
1494 PyFPE_START_PROTECT("mpz_float", return 0)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001495 x = 0.0;
1496 mulstate = 1.0;
1497 while (i--) {
1498 x += mulstate * mpz_get_ui(&mpzscratch);
1499 mulstate *= multiplier;
1500 mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
1501 }
Guido van Rossum45b83911997-03-14 04:32:50 +00001502 PyFPE_END_PROTECT(mulstate)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001503
1504 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1505 mpz_clear(&mpzscratch);
1506
1507 if (isnegative)
1508 x = -x;
1509
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001510 return PyFloat_FromDouble(x);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001511
1512} /* mpz_float() */
1513
1514#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001515static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001516mpz_hex(self, args)
1517 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001518 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001519#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001520static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001521mpz_hex(self)
1522 mpzobject *self;
1523#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1524{
1525#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001526 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001527 return NULL;
1528#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1529
1530 return mpz_format(self, 16, (unsigned char)1);
1531} /* mpz_hex() */
1532
1533#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001534static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001535mpz_oct(self, args)
1536 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001537 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001538#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001539static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001540mpz_oct(self)
1541 mpzobject *self;
1542#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1543{
1544#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001545 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001546 return NULL;
1547#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1548
1549 return mpz_format(self, 8, (unsigned char)1);
1550} /* mpz_oct() */
1551
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001552static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001553mpz_binary(self, args)
1554 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001555 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001556{
1557 int size;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001558 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001559 char *cp;
1560 MP_INT mp;
1561 unsigned long ldigit;
1562
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001563 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001564 return NULL;
1565
1566 if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001567 PyErr_SetString(PyExc_ValueError,
1568 "mpz.binary() arg must be >= 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001569 return NULL;
1570 }
1571
1572 mpz_init_set(&mp, &self->mpz);
1573 size = (int)mpz_size(&mp);
1574
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001575 if ((strobjp = (PyStringObject *)
1576 PyString_FromStringAndSize(
1577 (char *)0, size * sizeof (unsigned long int))) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001578 return NULL;
1579
1580 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001581 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001582
1583 /* this has been programmed using a (fairly) decent lib-i/f it could
1584 be must faster if we looked into the GMP lib */
1585 while (size--) {
1586 ldigit = mpz_get_ui(&mp);
1587 mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
1588 *cp++ = (unsigned char)(ldigit & 0xFF);
1589 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1590 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1591 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1592 }
1593
1594 while (strobjp->ob_size && !*--cp)
1595 strobjp->ob_size--;
1596
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001597 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001598} /* mpz_binary() */
1599
1600
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001601static PyMethodDef mpz_methods[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001602#ifdef MPZ_CONVERSIONS_AS_METHODS
1603 {"int", mpz_int},
1604 {"long", mpz_long},
1605 {"float", mpz_float},
1606 {"hex", mpz_hex},
1607 {"oct", mpz_oct},
1608#endif /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001609 {"binary", (PyCFunction)mpz_binary},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001610 {NULL, NULL} /* sentinel */
1611};
1612
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001613static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001614mpz_getattr(self, name)
1615 mpzobject *self;
1616 char *name;
1617{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001618 return Py_FindMethod(mpz_methods, (PyObject *)self, name);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001619} /* mpz_getattr() */
1620
1621
1622static int
1623mpz_coerce(pv, pw)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001624 PyObject **pv;
1625 PyObject **pw;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001626{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001627 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001628
1629#ifdef MPZ_DEBUG
1630 fputs("mpz_coerce() called...\n", stderr);
1631#endif /* def MPZ_DEBUG */
1632
1633 assert(is_mpzobject(*pv));
1634
1635 /* always convert other arg to mpz value, except for floats */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001636 if (!PyFloat_Check(*pw)) {
1637 if ((z = (PyObject *)mpz_mpzcoerce(*pw)) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001638 return -1; /* -1: an error always has been set */
1639
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001640 Py_INCREF(*pv);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001641 *pw = z;
1642 }
1643 else {
1644 if ((z = mpz_float(*pv, NULL)) == NULL)
1645 return -1;
1646
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001647 Py_INCREF(*pw);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001648 *pv = z;
1649 }
1650 return 0; /* coercion succeeded */
1651
1652} /* mpz_coerce() */
1653
1654
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001655static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001656mpz_repr(v)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001657 PyObject *v;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001658{
1659 return mpz_format(v, 10, (unsigned char)1);
1660} /* mpz_repr() */
1661
1662
1663
Guido van Rossumb6775db1994-08-01 11:34:53 +00001664#define UF (unaryfunc)
1665#define BF (binaryfunc)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001666#define TF (ternaryfunc)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001667#define IF (inquiry)
1668#define CF (coercion)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001669
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001670static PyNumberMethods mpz_as_number = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001671 BF mpz_addition, /*nb_add*/
1672 BF mpz_substract, /*nb_subtract*/
1673 BF mpz_multiply, /*nb_multiply*/
1674 BF mpz_divide, /*nb_divide*/
1675 BF mpz_remainder, /*nb_remainder*/
1676 BF mpz_div_and_mod, /*nb_divmod*/
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001677 TF mpz_power, /*nb_power*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001678 UF mpz_negative, /*nb_negative*/
1679 UF mpz_positive, /*tp_positive*/
1680 UF mpz_absolute, /*tp_absolute*/
1681 IF mpz_nonzero, /*tp_nonzero*/
Guido van Rossum272841c1996-08-19 23:06:45 +00001682 UF py_mpz_invert, /*nb_invert*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001683 BF mpz_lshift, /*nb_lshift*/
1684 BF mpz_rshift, /*nb_rshift*/
1685 BF mpz_andfunc, /*nb_and*/
1686 BF mpz_xorfunc, /*nb_xor*/
1687 BF mpz_orfunc, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001688 CF mpz_coerce, /*nb_coerce*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001689#ifndef MPZ_CONVERSIONS_AS_METHODS
1690 UF mpz_int, /*nb_int*/
1691 UF mpz_long, /*nb_long*/
1692 UF mpz_float, /*nb_float*/
1693 UF mpz_oct, /*nb_oct*/
1694 UF mpz_hex, /*nb_hex*/
1695#endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1696};
1697
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001698static PyTypeObject MPZtype = {
1699 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001700 0, /*ob_size*/
1701 "mpz", /*tp_name*/
1702 sizeof(mpzobject), /*tp_size*/
1703 0, /*tp_itemsize*/
1704 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001705 (destructor)mpz_dealloc, /*tp_dealloc*/
1706 0, /*tp_print*/
1707 (getattrfunc)mpz_getattr, /*tp_getattr*/
1708 0, /*tp_setattr*/
1709 (cmpfunc)mpz_compare, /*tp_compare*/
1710 (reprfunc)mpz_repr, /*tp_repr*/
1711 &mpz_as_number, /*tp_as_number*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001712};
1713
1714/* List of functions exported by this module */
1715
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001716static PyMethodDef mpz_functions[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001717#if 0
1718 {initialiser_name, MPZ_mpz},
1719#else /* 0 */
Barry Warsawabb7efe1996-12-09 23:22:35 +00001720 /* until guido ``fixes'' struct PyMethodDef */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001721 {(char *)initialiser_name, MPZ_mpz},
1722#endif /* 0 else */
1723 {"powm", MPZ_powm},
1724 {"gcd", MPZ_gcd},
1725 {"gcdext", MPZ_gcdext},
1726 {"sqrt", MPZ_sqrt},
1727 {"sqrtrem", MPZ_sqrtrem},
1728 {"divm", MPZ_divm},
1729 {NULL, NULL} /* Sentinel */
1730};
1731
1732
1733/* #define MP_TEST_ALLOC */
1734
1735#ifdef MP_TEST_ALLOC
1736#define MP_TEST_SIZE 4
1737static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
1738static mp_test_error( location )
1739 int *location;
1740{
1741 /* assumptions: *alloc returns address dividable by 4,
1742 mpz_* routines allocate in chunks dividable by four */
1743 fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001744 Py_FatalError("MP_TEST_ERROR");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001745} /* static mp_test_error() */
1746#define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1747#define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1748#define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1749 ; \
1750 else \
1751 mp_test_error((int *)((char *)(basep) + size))
1752#else /* def MP_TEST_ALLOC */
1753#define MP_EXTRA_ALLOC(size) (size)
1754#define MP_SET_TEST(basep,size)
1755#define MP_DO_TEST(basep,size)
1756#endif /* def MP_TEST_ALLOC else */
1757
1758void *mp_allocate( alloc_size )
1759 size_t alloc_size;
1760{
1761 void *res;
1762
1763#ifdef MPZ_DEBUG
1764 fprintf(stderr, "mp_allocate : size %ld\n",
1765 alloc_size);
1766#endif /* def MPZ_DEBUG */
1767
1768 if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001769 Py_FatalError("mp_allocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001770
1771#ifdef MPZ_DEBUG
1772 fprintf(stderr, "mp_allocate : address 0x%08x\n", res);
1773#endif /* def MPZ_DEBUG */
1774
1775 MP_SET_TEST(res,alloc_size);
1776
1777 return res;
1778} /* mp_allocate() */
1779
1780
1781void *mp_reallocate( ptr, old_size, new_size )
1782 void *ptr;
1783 size_t old_size;
1784 size_t new_size;
1785{
1786 void *res;
1787
1788#ifdef MPZ_DEBUG
1789 fprintf(stderr, "mp_reallocate: old address 0x%08x, old size %ld\n",
1790 ptr, old_size);
1791#endif /* def MPZ_DEBUG */
1792
1793 MP_DO_TEST(ptr, old_size);
1794
1795 if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001796 Py_FatalError("mp_reallocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001797
1798#ifdef MPZ_DEBUG
1799 fprintf(stderr, "mp_reallocate: new address 0x%08x, new size %ld\n",
1800 res, new_size);
1801#endif /* def MPZ_DEBUG */
1802
1803 MP_SET_TEST(res, new_size);
1804
1805 return res;
1806} /* mp_reallocate() */
1807
1808
1809void mp_free( ptr, size )
1810 void *ptr;
1811 size_t size;
1812{
1813
1814#ifdef MPZ_DEBUG
1815 fprintf(stderr, "mp_free : old address 0x%08x, old size %ld\n",
1816 ptr, size);
1817#endif /* def MPZ_DEBUG */
1818
1819 MP_DO_TEST(ptr, size);
1820 free(ptr);
1821} /* mp_free() */
1822
1823
1824
1825/* Initialize this module. */
1826
Guido van Rossum3886bb61998-12-04 18:50:17 +00001827DL_EXPORT(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001828initmpz()
1829{
Fred Drakefcc6c681998-04-03 15:33:43 +00001830 PyObject *module;
1831 PyObject *dict;
1832
Guido van Rossum5f59d601992-12-14 16:59:51 +00001833#ifdef MPZ_DEBUG
1834 fputs( "initmpz() called...\n", stderr );
1835#endif /* def MPZ_DEBUG */
1836
1837 mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
Fred Drakefcc6c681998-04-03 15:33:43 +00001838 module = Py_InitModule("mpz", mpz_functions);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001839
1840 /* create some frequently used constants */
1841 if ((mpz_value_zero = 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_zero->mpz, (unsigned long int)0);
1844
1845 if ((mpz_value_one = 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_ui(&mpz_value_one->mpz, (unsigned long int)1);
1848
1849 if ((mpz_value_mone = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001850 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001851 mpz_set_si(&mpz_value_mone->mpz, (long)-1);
1852
Fred Drakefcc6c681998-04-03 15:33:43 +00001853 dict = PyModule_GetDict(module);
1854 if (dict != NULL) {
1855 PyDict_SetItemString(dict, "MPZType", (PyObject*)&MPZtype);
1856 }
1857
Guido van Rossum5f59d601992-12-14 16:59:51 +00001858} /* initmpz() */
1859#ifdef MAKEDUMMYINT
1860int _mpz_dummy_int; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1861#endif /* def MAKEDUMMYINT */