blob: 4299f454b71c97c80d231237e6328b2f0810e110 [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 Rossum97250cb1997-12-15 17:55:53 +000095#include "gmp-mparam.h"
Guido van Rossum272841c1996-08-19 23:06:45 +000096
Guido van Rossum57e846f1997-08-17 19:08:33 +000097#if __GNU_MP__ + 0 == 2
Guido van Rossum272841c1996-08-19 23:06:45 +000098#define GMP2
99#else
100#define MPZ_GET_STR_BUG
101#endif
102
Guido van Rossum5f59d601992-12-14 16:59:51 +0000103typedef struct {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000104 PyObject_HEAD
Guido van Rossum5f59d601992-12-14 16:59:51 +0000105 MP_INT mpz; /* the actual number */
106} mpzobject;
107
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000108staticforward PyTypeObject MPZtype;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000109
110#define is_mpzobject(v) ((v)->ob_type == &MPZtype)
111
112static const char initialiser_name[] = "mpz";
113
114/* #define MPZ_DEBUG */
115
116static mpzobject *
117newmpzobject()
118{
119 mpzobject *mpzp;
120
121
122#ifdef MPZ_DEBUG
123 fputs( "mpz_object() called...\n", stderr );
124#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000125 mpzp = PyObject_NEW(mpzobject, &MPZtype);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000126 if (mpzp == NULL)
127 return NULL;
128
129 mpz_init(&mpzp->mpz); /* actual initialisation */
130 return mpzp;
131} /* newmpzobject() */
132
133#ifdef MPZ_GET_STR_BUG
Guido van Rossum5f59d601992-12-14 16:59:51 +0000134#include "longlong.h"
135#endif /* def MPZ_GET_STR_BUG */
136
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000137static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000138mpz_format(objp, base, withname)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000139 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000140 int base;
141 unsigned char withname;
142{
143 mpzobject *mpzp = (mpzobject *)objp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000144 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000145 int i;
146 int cmpres;
147 int taglong;
148 char *cp;
149 char prefix[5], *tcp;
150
151
152 tcp = &prefix[0];
153
154 if (mpzp == NULL || !is_mpzobject(mpzp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000155 PyErr_BadInternalCall();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000156 return NULL;
157 }
158
159 assert(base >= 2 && base <= 36);
160
161 if (withname)
162 i = strlen(initialiser_name) + 2; /* e.g. 'mpz(' + ')' */
163 else
164 i = 0;
165
166 if ((cmpres = mpz_cmp_si(&mpzp->mpz, 0L)) == 0)
167 base = 10; /* '0' in every base, right */
168 else if (cmpres < 0) {
169 *tcp++ = '-';
170 i += 1; /* space to hold '-' */
171 }
172
173#ifdef MPZ_DEBUG
174 fprintf(stderr, "mpz_format: mpz_sizeinbase %d\n",
175 (int)mpz_sizeinbase(&mpzp->mpz, base));
176#endif /* def MPZ_DEBUG */
177#ifdef MPZ_GET_STR_BUG
Guido van Rossum272841c1996-08-19 23:06:45 +0000178#ifdef GMP2
179 i += ((size_t) abs(mpzp->mpz._mp_size) * BITS_PER_MP_LIMB
180 * __mp_bases[base].chars_per_bit_exactly) + 1;
181#else
Guido van Rossum5f59d601992-12-14 16:59:51 +0000182 i += ((size_t) abs(mpzp->mpz.size) * BITS_PER_MP_LIMB
183 * __mp_bases[base].chars_per_bit_exactly) + 1;
Guido van Rossum272841c1996-08-19 23:06:45 +0000184#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +0000185#else /* def MPZ_GET_STR_BUG */
186 i += (int)mpz_sizeinbase(&mpzp->mpz, base);
187#endif /* def MPZ_GET_STR_BUG else */
188
189 if (base == 16) {
190 *tcp++ = '0';
191 *tcp++ = 'x';
192 i += 2; /* space to hold '0x' */
193 }
194 else if (base == 8) {
195 *tcp++ = '0';
196 i += 1; /* space to hold the extra '0' */
197 }
198 else if (base > 10) {
199 *tcp++ = '0' + base / 10;
200 *tcp++ = '0' + base % 10;
201 *tcp++ = '#';
202 i += 3; /* space to hold e.g. '12#' */
203 }
204 else if (base < 10) {
205 *tcp++ = '0' + base;
206 *tcp++ = '#';
207 i += 2; /* space to hold e.g. '6#' */
208 }
209
210 /*
211 ** the following code looks if we need a 'L' attached to the number
212 ** it will also attach an 'L' to the value -0x80000000
213 */
214 taglong = 0;
215 if (mpz_size(&mpzp->mpz) > 1
216 || (long)mpz_get_ui(&mpzp->mpz) < 0L) {
217 taglong = 1;
218 i += 1; /* space to hold 'L' */
219 }
220
221#ifdef MPZ_DEBUG
222 fprintf(stderr, "mpz_format: requesting string size %d\n", i);
223#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000224 if ((strobjp =
225 (PyStringObject *)PyString_FromStringAndSize((char *)0, i))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000226 == NULL)
227 return NULL;
228
229 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000230 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000231 if (withname) {
232 strcpy(cp, initialiser_name);
233 cp += strlen(initialiser_name);
234 *cp++ = '('; /*')'*/
235 }
236
237 /* copy the already prepared prefix; e.g. sign and base indicator */
238 *tcp = '\0';
239 strcpy(cp, prefix);
240 cp += tcp - prefix;
241
242 /* since' we have the sign already, let the lib think it's a positive
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000243 number */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000244 if (cmpres < 0)
245 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
246 (void)mpz_get_str(cp, base, &mpzp->mpz);
247 if (cmpres < 0)
248 mpz_neg(&mpzp->mpz,&mpzp->mpz); /* hack Hack HAck HACk HACK */
249#ifdef MPZ_DEBUG
250 fprintf(stderr, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
251 base, cp);
252#endif /* def MPZ_DEBUG */
253 cp += strlen(cp);
254
255 if (taglong)
256 *cp++ = 'L';
257 if (withname)
258 *cp++ = /*'('*/ ')';
259
260 *cp = '\0';
261
262#ifdef MPZ_DEBUG
263 fprintf(stderr,
264 "mpz_format: cp (str end) 0x%x, begin 0x%x, diff %d, i %d\n",
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000265 cp, PyString_AS_STRING(strobjp),
266 cp - PyString_AS_STRING(strobjp), i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000267#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000268 assert(cp - PyString_AS_STRING(strobjp) <= i);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000269
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000270 if (cp - PyString_AS_STRING(strobjp) != i) {
271 strobjp->ob_size -= i - (cp - PyString_AS_STRING(strobjp));
Guido van Rossum5f59d601992-12-14 16:59:51 +0000272 }
273
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000274 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000275} /* mpz_format() */
276
277/* MPZ methods */
278
279static void
280mpz_dealloc(mpzp)
281 mpzobject *mpzp;
282{
283#ifdef MPZ_DEBUG
284 fputs( "mpz_dealloc() called...\n", stderr );
285#endif /* def MPZ_DEBUG */
286 mpz_clear(&mpzp->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000287 PyMem_DEL(mpzp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000288} /* mpz_dealloc() */
289
Guido van Rossum5f59d601992-12-14 16:59:51 +0000290
291/* pointers to frequently used values 0, 1 and -1 */
292static mpzobject *mpz_value_zero, *mpz_value_one, *mpz_value_mone;
293
294static int
295mpz_compare(a, b)
296 mpzobject *a, *b;
297{
298 int cmpres;
299
300
301 /* guido sez it's better to return -1, 0 or 1 */
302 return (cmpres = mpz_cmp( &a->mpz, &b->mpz )) == 0 ? 0
303 : cmpres > 0 ? 1 : -1;
304} /* mpz_compare() */
305
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000306static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000307mpz_addition(a, b)
308 mpzobject *a;
309 mpzobject *b;
310{
311 mpzobject *z;
312
313
314#ifdef MPZ_SPARE_MALLOC
315 if (mpz_cmp_ui(&a->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000316 Py_INCREF(b);
317 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000318 }
319
320 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000321 Py_INCREF(a);
322 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000323 }
324#endif /* def MPZ_SPARE_MALLOC */
325
326 if ((z = newmpzobject()) == NULL)
327 return NULL;
328
329 mpz_add(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000330 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000331} /* mpz_addition() */
332
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000333static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000334mpz_substract(a, b)
335 mpzobject *a;
336 mpzobject *b;
337{
338 mpzobject *z;
339
340
341#ifdef MPZ_SPARE_MALLOC
342 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000343 Py_INCREF(a);
344 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000345 }
346#endif /* MPZ_SPARE_MALLOC */
347
348 if ((z = newmpzobject()) == NULL)
349 return NULL;
350
351 mpz_sub(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000352 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000353} /* mpz_substract() */
354
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000355static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000356mpz_multiply(a, b)
357 mpzobject *a;
358 mpzobject *b;
359{
360#ifdef MPZ_SPARE_MALLOC
361 int cmpres;
362#endif /* def MPZ_SPARE_MALLOC */
363 mpzobject *z;
364
365
366#ifdef MPZ_SPARE_MALLOC
367 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000368 Py_INCREF(mpz_value_zero);
369 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000370 }
371 if (cmpres > 0 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000372 Py_INCREF(b);
373 return (PyObject *)b;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000374 }
375
376 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long_int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000377 Py_INCREF(mpz_value_zero);
378 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000379 }
380 if (cmpres > 0 && mpz_cmp_ui(&b->mpz, (unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000381 Py_INCREF(a);
382 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000383 }
384#endif /* MPZ_SPARE_MALLOC */
385
386 if ((z = newmpzobject()) == NULL)
387 return NULL;
388
389 mpz_mul( &z->mpz, &a->mpz, &b->mpz );
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000390 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000391
392} /* mpz_multiply() */
393
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000394static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000395mpz_divide(a, b)
396 mpzobject *a;
397 mpzobject *b;
398{
399#ifdef MPZ_SPARE_MALLOC
400 int cmpres;
401#endif /* def MPZ_SPARE_MALLOC */
402 mpzobject *z;
403
404
405 if ((
406#ifdef MPZ_SPARE_MALLOC
407 cmpres =
408#endif /* def MPZ_SPARE_MALLOC */
409 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000410 PyErr_SetString(PyExc_ZeroDivisionError, "mpz./ by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000411 return NULL;
412 }
413#ifdef MPZ_SPARE_MALLOC
414 if (cmpres > 0 && mpz_cmp_ui(&b->mpz(unsigned long int)1) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000415 Py_INCREF(a);
416 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000417 }
418#endif /* def MPZ_SPARE_MALLOC */
419
420 if ((z = newmpzobject()) == NULL)
421 return NULL;
422
423#ifdef MPZ_TEST_DIV
424 fputs("mpz_divide: div result", stderr);
425 mpz_div(&z->mpz, &a->mpz, &b->mpz);
426 mpz_out_str(stderr, 10, &z->mpz);
427 putc('\n', stderr);
428#endif /* def MPZ_TEST_DIV */
429#ifdef MPZ_MDIV_BUG
430 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
431 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)) {
432 /*
433 ** numerator has other sign than denominator: we have
434 ** to look at the remainder for a correction, since mpz_mdiv
435 ** also calls mpz_divmod, I can as well do it myself
436 */
437 MP_INT tmpmpz;
438
439
440 mpz_init(&tmpmpz);
441 mpz_divmod(&z->mpz, &tmpmpz, &a->mpz, &b->mpz);
442
443 if (mpz_cmp_ui(&tmpmpz, (unsigned long int)0) != 0)
444 mpz_sub_ui(&z->mpz, &z->mpz, (unsigned long int)1);
445
446 mpz_clear(&tmpmpz);
447 }
448 else
449 mpz_div(&z->mpz, &a->mpz, &b->mpz);
450 /* the ``naive'' implementation does it right for operands
451 having the same sign */
452
453#else /* def MPZ_MDIV_BUG */
454 mpz_mdiv(&z->mpz, &a->mpz, &b->mpz);
455#endif /* def MPZ_MDIV_BUG else */
456#ifdef MPZ_TEST_DIV
457 fputs("mpz_divide: mdiv result", stderr);
458 mpz_out_str(stderr, 10, &z->mpz);
459 putc('\n', stderr);
460#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000461 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000462
463} /* mpz_divide() */
464
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000465static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000466mpz_remainder(a, b)
467 mpzobject *a;
468 mpzobject *b;
469{
470#ifdef MPZ_SPARE_MALLOC
471 int cmpres;
472#endif /* def MPZ_SPARE_MALLOC */
473 mpzobject *z;
474
475
476 if ((
477#ifdef MPZ_SPARE_MALLOC
478 cmpres =
479#endif /* def MPZ_SPARE_MALLOC */
480 mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000481 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.% by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000482 return NULL;
483 }
484#ifdef MPZ_SPARE_MALLOC
485 if (cmpres > 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000486 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)2)) == 0)
487 {
488 Py_INCREF(mpz_value_one);
489 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000490 }
491 if (cmpres < 0) {
492 /* b must be 1 now */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000493 Py_INCREF(mpz_value_zero);
494 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000495 }
496 }
497#endif /* def MPZ_SPARE_MALLOC */
498
499 if ((z = newmpzobject()) == NULL)
500 return NULL;
501
502#ifdef MPZ_TEST_DIV
503 fputs("mpz_remain: mod result", stderr);
504 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
505 mpz_out_str(stderr, 10, &z->mpz);
506 putc('\n', stderr);
507#endif /* def MPZ_TEST_DIV */
508#ifdef MPZ_MDIV_BUG
509
510 /* the ``naive'' implementation does it right for operands
511 having the same sign */
512 mpz_mod(&z->mpz, &a->mpz, &b->mpz);
513
514 /* assumption: z, a and b all point to different locations */
515 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
516 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
517 && mpz_cmp_ui(&z->mpz, (unsigned long int)0) != 0)
518 mpz_add(&z->mpz, &z->mpz, &b->mpz);
519 /*
520 ** numerator has other sign than denominator: we have
521 ** to look at the remainder for a correction, since mpz_mdiv
522 ** also calls mpz_divmod, I can as well do it myself
523 */
524#else /* def MPZ_MDIV_BUG */
525 mpz_mmod(&z->mpz, &a->mpz, &b->mpz);
526#endif /* def MPZ_MDIV_BUG else */
527#ifdef MPZ_TEST_DIV
528 fputs("mpz_remain: mmod result", stderr);
529 mpz_out_str(stderr, 10, &z->mpz);
530 putc('\n', stderr);
531#endif /* def MPZ_TEST_DIV */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000532 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000533
534} /* mpz_remainder() */
535
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000536static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000537mpz_div_and_mod(a, b)
538 mpzobject *a;
539 mpzobject *b;
540{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000541 PyObject *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000542 mpzobject *x = NULL, *y = NULL;
543
544
545 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000546 PyErr_SetString(PyExc_ZeroDivisionError, "mpz.divmod by zero");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000547 return NULL;
548 }
549
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000550 if ((z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +0000551 || (x = newmpzobject()) == NULL
552 || (y = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000553 Py_XDECREF(z);
554 Py_XDECREF(x);
555 Py_XDECREF(y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000556 return NULL;
557 }
558
559#ifdef MPZ_TEST_DIV
560 fputs("mpz_divmod: dm result", stderr);
561 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
562 mpz_out_str(stderr, 10, &x->mpz);
563 putc('\n', stderr);
564 mpz_out_str(stderr, 10, &y->mpz);
565 putc('\n', stderr);
566#endif /* def MPZ_TEST_DIV */
567#ifdef MPZ_MDIV_BUG
568 mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
569 if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
570 != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
571 && mpz_cmp_ui(&y->mpz, (unsigned long int)0) != 0) {
572 /*
573 ** numerator has other sign than denominator: we have
574 ** to look at the remainder for a correction.
575 */
576 mpz_add(&y->mpz, &y->mpz, &b->mpz);
577 mpz_sub_ui(&x->mpz, &x->mpz, (unsigned long int)1);
578 }
579#else /* def MPZ_MDIV_BUG */
580 mpz_mdivmod( &x->mpz, &y->mpz, &a->mpz, &b->mpz );
581#endif /* def MPZ_MDIV_BUG else */
582#ifdef MPZ_TEST_DIV
583 fputs("mpz_divmod: mdm result", stderr);
584 mpz_out_str(stderr, 10, &x->mpz);
585 putc('\n', stderr);
586 mpz_out_str(stderr, 10, &y->mpz);
587 putc('\n', stderr);
588#endif /* def MPZ_TEST_DIV */
589
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000590 (void)PyTuple_SetItem(z, 0, (PyObject *)x);
591 (void)PyTuple_SetItem(z, 1, (PyObject *)y);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000592
593 return z;
594} /* mpz_div_and_mod() */
595
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000596static PyObject *
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000597mpz_power(a, b, m)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000598 mpzobject *a;
599 mpzobject *b;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000600 mpzobject *m;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000601{
602 mpzobject *z;
603 int cmpres;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000604
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000605 if ((PyObject *)m != Py_None) {
606 mpzobject *z2;
607 Py_INCREF(Py_None);
608 z=(mpzobject *)mpz_power(a, b, (mpzobject *)Py_None);
609 Py_DECREF(Py_None);
610 if (z==NULL) return((PyObject *)z);
611 z2=(mpzobject *)mpz_remainder(z, m);
612 Py_DECREF(z);
613 return((PyObject *)z2);
614 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000615
616 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
617 /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
618
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000619 Py_INCREF(mpz_value_one);
620 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000621 }
622
623 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000624 PyErr_SetString(PyExc_ValueError,
625 "mpz.pow to negative exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000626 return NULL;
627 }
628
629 if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
630 /* the base is 0 */
631
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000632 Py_INCREF(mpz_value_zero);
633 return (PyObject *)mpz_value_zero;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000634 }
635 else if (cmpres > 0
636 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
637 /* the base is 1 */
638
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000639 Py_INCREF(mpz_value_one);
640 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000641 }
642 else if (cmpres < 0
643 && mpz_cmp_si(&a->mpz, (long int)-1) == 0) {
644
645 MP_INT tmpmpz;
646 /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
647 /* XXX this code needs to be optimized: what's better?
648 mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
649 for *un*obvious reasons */
650
651 /* is the exponent even? */
652 mpz_init(&tmpmpz);
653
654 /* look to the remainder after a division by (1 << 1) */
655 mpz_mod_2exp(&tmpmpz, &b->mpz, (unsigned long int)1);
656
657 if (mpz_cmp_ui(&tmpmpz, (unsigned int)0) == 0) {
658 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000659 Py_INCREF(mpz_value_one);
660 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000661 }
662 mpz_clear(&tmpmpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000663 Py_INCREF(mpz_value_mone);
664 return (PyObject *)mpz_value_mone;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000665 }
666
667#ifdef MPZ_LIB_DOES_CHECKING
668 /* check if it's doable: sizeof(exp) > sizeof(long) &&
669 abs(base) > 1 ?? --> No Way */
670 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000671 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000672#else /* def MPZ_LIB_DOES_CHECKING */
673 /* wet finger method */
674 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000675 PyErr_SetString(PyExc_ValueError,
676 "mpz.pow outrageous exponent");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000677 return NULL;
678 }
679#endif /* def MPZ_LIB_DOES_CHECKING else */
680
681 if ((z = newmpzobject()) == NULL)
682 return NULL;
683
684 mpz_pow_ui(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
685
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000686 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000687} /* mpz_power() */
688
689
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000690static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000691mpz_negative(v)
692 mpzobject *v;
693{
694 mpzobject *z;
695
696
697#ifdef MPZ_SPARE_MALLOC
698 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) == 0) {
699 /* -0 == 0 */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000700 Py_INCREF(v);
701 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000702 }
703#endif /* def MPZ_SPARE_MALLOC */
704
705 if ((z = newmpzobject()) == NULL)
706 return NULL;
707
708 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000709 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000710} /* mpz_negative() */
711
712
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000713static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000714mpz_positive(v)
715 mpzobject *v;
716{
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000717 Py_INCREF(v);
718 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000719} /* mpz_positive() */
720
721
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000722static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000723mpz_absolute(v)
724 mpzobject *v;
725{
726 mpzobject *z;
727
728
729 if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000730 Py_INCREF(v);
731 return (PyObject *)v;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000732 }
733
734 if ((z = newmpzobject()) == NULL)
735 return NULL;
736
737 mpz_neg(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000738 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000739} /* mpz_absolute() */
740
741static int
742mpz_nonzero(v)
743 mpzobject *v;
744{
745 return mpz_cmp_ui(&v->mpz, (unsigned long int)0) != 0;
746} /* mpz_nonzero() */
747
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000748static PyObject *
Guido van Rossum272841c1996-08-19 23:06:45 +0000749py_mpz_invert(v)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000750 mpzobject *v;
751{
752 mpzobject *z;
753
754
755 /* I think mpz_com does exactly what needed */
756 if ((z = newmpzobject()) == NULL)
757 return NULL;
758
759 mpz_com(&z->mpz, &v->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000760 return (PyObject *)z;
Guido van Rossum272841c1996-08-19 23:06:45 +0000761} /* py_mpz_invert() */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000762
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000763static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000764mpz_lshift(a, b)
765 mpzobject *a;
766 mpzobject *b;
767{
768 int cmpres;
769 mpzobject *z;
770
771
772 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
773 /* a << 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000774 Py_INCREF(a);
775 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000776 }
777
778 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000779 PyErr_SetString(PyExc_ValueError,
780 "mpz.<< negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000781 return NULL;
782 }
783
784#ifdef MPZ_LIB_DOES_CHECKING
785 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000786 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000787#else /* def MPZ_LIB_DOES_CHECKING */
788 /* wet finger method */
789 if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000790 PyErr_SetString(PyExc_ValueError,
791 "mpz.<< outrageous shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000792 return NULL;
793 }
794#endif /* def MPZ_LIB_DOES_CHECKING else */
795
796 if ((z = newmpzobject()) == NULL)
797 return NULL;
798
799 mpz_mul_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000800 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000801} /* mpz_lshift() */
802
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000803static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000804mpz_rshift(a, b)
805 mpzobject *a;
806 mpzobject *b;
807{
808 int cmpres;
809 mpzobject *z;
810
811
812 if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
813 /* a >> 0 == a */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000814 Py_INCREF(a);
815 return (PyObject *)a;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000816 }
817
818 if (cmpres < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000819 PyErr_SetString(PyExc_ValueError,
820 "mpz.>> negative shift count");
Guido van Rossum5f59d601992-12-14 16:59:51 +0000821 return NULL;
822 }
823
824 if (mpz_size(&b->mpz) > 1)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000825 return (PyObject *)PyErr_NoMemory();
Guido van Rossum5f59d601992-12-14 16:59:51 +0000826
827 if ((z = newmpzobject()) == NULL)
828 return NULL;
829
830 mpz_div_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000831 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000832} /* mpz_rshift() */
833
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000834static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000835mpz_andfunc(a, b)
836 mpzobject *a;
837 mpzobject *b;
838{
839 mpzobject *z;
840
841
842 if ((z = newmpzobject()) == NULL)
843 return NULL;
844
845 mpz_and(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000846 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000847} /* mpz_andfunc() */
848
849/* hack Hack HAck HACk HACK, XXX this code is dead slow */
850void
851mpz_xor(res, op1, op2)
852 MP_INT *res;
853 const MP_INT *op1;
854 const MP_INT *op2;
855{
856 MP_INT tmpmpz;
857
858 mpz_init(&tmpmpz);
859
860 mpz_and(res, op1, op2);
861 mpz_com(&tmpmpz, res);
862 mpz_ior(res, op1, op2);
863 mpz_and(res, res, &tmpmpz);
864
865 mpz_clear(&tmpmpz);
866} /* mpz_xor() HACK */
867
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000868static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000869mpz_xorfunc(a, b)
870 mpzobject *a;
871 mpzobject *b;
872{
873 mpzobject *z;
874
875
876 if ((z = newmpzobject()) == NULL)
877 return NULL;
878
879 mpz_xor(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000880 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000881} /* mpz_xorfunc() */
882
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000883static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000884mpz_orfunc(a, b)
885 mpzobject *a;
886 mpzobject *b;
887{
888 mpzobject *z;
889
890
891 if ((z = newmpzobject()) == NULL)
892 return NULL;
893
894 mpz_ior(&z->mpz, &a->mpz, &b->mpz);
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000895 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000896} /* mpz_orfunc() */
897
898/* MPZ initialisation */
899
900#include "longintrepr.h"
901
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000902static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000903MPZ_mpz(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000904 PyObject *self;
905 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000906{
907 mpzobject *mpzp;
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000908 PyObject *objp;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000909
910
911#ifdef MPZ_DEBUG
912 fputs("MPZ_mpz() called...\n", stderr);
913#endif /* def MPZ_DEBUG */
914
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000915 if (!PyArg_Parse(args, "O", &objp))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000916 return NULL;
917
918 /* at least we know it's some object */
Barry Warsawabb7efe1996-12-09 23:22:35 +0000919 /* note DON't Py_DECREF args NEITHER objp */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000920
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000921 if (PyInt_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000922 long lval;
923
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000924 if (!PyArg_Parse(objp, "l", &lval))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000925 return NULL;
926
927 if (lval == (long)0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000928 Py_INCREF(mpz_value_zero);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000929 mpzp = mpz_value_zero;
930 }
931 else if (lval == (long)1) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000932 Py_INCREF(mpz_value_one);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000933 mpzp = mpz_value_one;
934 }
935 else if ((mpzp = newmpzobject()) == NULL)
936 return NULL;
937 else mpz_set_si(&mpzp->mpz, lval);
938 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000939 else if (PyLong_Check(objp)) {
Guido van Rossum5f59d601992-12-14 16:59:51 +0000940 MP_INT mplongdigit;
941 int i;
942 unsigned char isnegative;
943
944
945 if ((mpzp = newmpzobject()) == NULL)
946 return NULL;
947
948 mpz_set_si(&mpzp->mpz, 0L);
949 mpz_init(&mplongdigit);
950
951 /* how we're gonna handle this? */
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000952 if ((isnegative =
953 ((i = ((PyLongObject *)objp)->ob_size) < 0) ))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000954 i = -i;
955
956 while (i--) {
957 mpz_set_ui(&mplongdigit,
958 (unsigned long)
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000959 ((PyLongObject *)objp)->ob_digit[i]);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000960 mpz_mul_2exp(&mplongdigit,&mplongdigit,
961 (unsigned long int)i * SHIFT);
962 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
963 }
964
965 if (isnegative)
966 mpz_neg(&mpzp->mpz, &mpzp->mpz);
967
968 /* get rid of allocation for tmp variable */
969 mpz_clear(&mplongdigit);
970 }
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000971 else if (PyString_Check(objp)) {
Guido van Rossum7e488981998-10-08 02:25:24 +0000972 char *cp = PyString_AS_STRING(objp);
973 int len = PyString_GET_SIZE(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000974 MP_INT mplongdigit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000975
976 if ((mpzp = newmpzobject()) == NULL)
977 return NULL;
978
979 mpz_set_si(&mpzp->mpz, 0L);
980 mpz_init(&mplongdigit);
981
982 /* let's do it the same way as with the long conversion:
983 without thinking how it can be faster (-: :-) */
984
985 cp += len;
986 while (len--) {
987 mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
988 mpz_mul_2exp(&mplongdigit,&mplongdigit,
989 (unsigned long int)len * 8);
990 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
991 }
992
993 /* get rid of allocation for tmp variable */
994 mpz_clear(&mplongdigit);
995 }
996 else if (is_mpzobject(objp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000997 Py_INCREF(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000998 mpzp = (mpzobject *)objp;
999 }
1000 else {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001001 PyErr_SetString(PyExc_TypeError,
1002"mpz.mpz() expects integer, long, string or mpz object argument");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001003 return NULL;
1004 }
1005
1006
1007#ifdef MPZ_DEBUG
1008 fputs("MPZ_mpz: created mpz=", stderr);
1009 mpz_out_str(stderr, 10, &mpzp->mpz);
1010 putc('\n', stderr);
1011#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001012 return (PyObject *)mpzp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001013} /* MPZ_mpz() */
1014
1015static mpzobject *
1016mpz_mpzcoerce(z)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001017 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001018{
1019 /* shortcut: 9 out of 10 times the type is already ok */
1020 if (is_mpzobject(z)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001021 Py_INCREF(z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001022 return (mpzobject *)z; /* coercion succeeded */
1023 }
1024
1025 /* what types do we accept?: intobjects and longobjects */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001026 if (PyInt_Check(z) || PyLong_Check(z))
1027 return (mpzobject *)MPZ_mpz((PyObject *)NULL, z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001028
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001029 PyErr_SetString(PyExc_TypeError,
1030 "number coercion (to mpzobject) failed");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001031 return NULL;
1032} /* mpz_mpzcoerce() */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001033
1034/* Forward */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001035static void mpz_divm Py_PROTO((MP_INT *res, const MP_INT *num,
1036 const MP_INT *den, const MP_INT *mod));
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001037
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001038static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001039MPZ_powm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001040 PyObject *self;
1041 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001042{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001043 PyObject *base, *exp, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001044 mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
1045 mpzobject *z;
1046 int tstres;
1047
1048
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001049 if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001050 return NULL;
1051
1052 if ((mpzbase = mpz_mpzcoerce(base)) == NULL
1053 || (mpzexp = mpz_mpzcoerce(exp)) == NULL
1054 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1055 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001056 Py_XDECREF(mpzbase);
1057 Py_XDECREF(mpzexp);
1058 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001059 return NULL;
1060 }
1061
1062 if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001063 Py_INCREF(mpz_value_one);
1064 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001065 }
1066
1067 if (tstres < 0) {
1068 MP_INT absexp;
1069 /* negative exp */
1070
1071 mpz_init_set(&absexp, &mpzexp->mpz);
1072 mpz_abs(&absexp, &absexp);
1073 mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
1074
1075 mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
1076
1077 mpz_clear(&absexp);
1078 }
1079 else {
1080 mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
1081 }
1082
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001083 Py_DECREF(mpzbase);
1084 Py_DECREF(mpzexp);
1085 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001086
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001087 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001088} /* MPZ_powm() */
1089
1090
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001091static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001092MPZ_gcd(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001093 PyObject *self;
1094 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001095{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001096 PyObject *op1, *op2;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001097 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1098 mpzobject *z;
1099
1100
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001101 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001102 return NULL;
1103
1104 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1105 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
1106 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001107 Py_XDECREF(mpzop1);
1108 Py_XDECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001109 return NULL;
1110 }
1111
1112 /* ok, we have three mpzobjects, and an initialised result holder */
1113 mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
1114
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001115 Py_DECREF(mpzop1);
1116 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001117
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001118 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001119} /* MPZ_gcd() */
1120
1121
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001122static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001123MPZ_gcdext(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001124 PyObject *self;
1125 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001126{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001127 PyObject *op1, *op2, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001128 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1129 mpzobject *g = NULL, *s = NULL, *t = NULL;
1130
1131
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001132 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001133 return NULL;
1134
1135 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1136 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001137 || (z = PyTuple_New(3)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001138 || (g = newmpzobject()) == NULL
1139 || (s = newmpzobject()) == NULL
1140 || (t = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001141 Py_XDECREF(mpzop1);
1142 Py_XDECREF(mpzop2);
1143 Py_XDECREF(z);
1144 Py_XDECREF(g);
1145 Py_XDECREF(s);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001146 /*Py_XDECREF(t);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001147 return NULL;
1148 }
1149
1150 mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
1151
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001152 Py_DECREF(mpzop1);
1153 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001154
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001155 (void)PyTuple_SetItem(z, 0, (PyObject *)g);
1156 (void)PyTuple_SetItem(z, 1, (PyObject *)s);
1157 (void)PyTuple_SetItem(z, 2, (PyObject *)t);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001158
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001159 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001160} /* MPZ_gcdext() */
1161
1162
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001163static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001164MPZ_sqrt(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001165 PyObject *self;
1166 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001167{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001168 PyObject *op;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001169 mpzobject *mpzop = NULL;
1170 mpzobject *z;
1171
1172
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001173 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001174 return NULL;
1175
1176 if ((mpzop = mpz_mpzcoerce(op)) == NULL
1177 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001178 Py_XDECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001179 return NULL;
1180 }
1181
1182 mpz_sqrt(&z->mpz, &mpzop->mpz);
1183
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001184 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001185
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001186 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001187} /* MPZ_sqrt() */
1188
1189
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001190static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001191MPZ_sqrtrem(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001192 PyObject *self;
1193 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001194{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001195 PyObject *op, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001196 mpzobject *mpzop = NULL;
1197 mpzobject *root = NULL, *rem = NULL;
1198
1199
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001200 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001201 return NULL;
1202
1203 if ((mpzop = mpz_mpzcoerce(op)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001204 || (z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001205 || (root = newmpzobject()) == NULL
1206 || (rem = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001207 Py_XDECREF(mpzop);
1208 Py_XDECREF(z);
1209 Py_XDECREF(root);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001210 /*Py_XDECREF(rem);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001211 return NULL;
1212 }
1213
1214 mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
1215
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001216 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001217
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001218 (void)PyTuple_SetItem(z, 0, (PyObject *)root);
1219 (void)PyTuple_SetItem(z, 1, (PyObject *)rem);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001220
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001221 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001222} /* MPZ_sqrtrem() */
1223
1224
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001225static void
Guido van Rossum5f59d601992-12-14 16:59:51 +00001226#if __STDC__
1227mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
1228#else
1229mpz_divm(res, num, den, mod)
1230 MP_INT *res;
1231 const MP_INT *num;
1232 const MP_INT *den;
1233 const MP_INT *mod;
1234#endif
1235{
1236 MP_INT s0, s1, q, r, x, d0, d1;
1237
1238 mpz_init_set(&s0, num);
1239 mpz_init_set_ui(&s1, 0);
1240 mpz_init(&q);
1241 mpz_init(&r);
1242 mpz_init(&x);
1243 mpz_init_set(&d0, den);
1244 mpz_init_set(&d1, mod);
1245
Guido van Rossum272841c1996-08-19 23:06:45 +00001246#ifdef GMP2
1247 while (d1._mp_size != 0) {
1248#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001249 while (d1.size != 0) {
Guido van Rossum272841c1996-08-19 23:06:45 +00001250#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001251 mpz_divmod(&q, &r, &d0, &d1);
1252 mpz_set(&d0, &d1);
1253 mpz_set(&d1, &r);
1254
1255 mpz_mul(&x, &s1, &q);
1256 mpz_sub(&x, &s0, &x);
1257 mpz_set(&s0, &s1);
1258 mpz_set(&s1, &x);
1259 }
1260
Guido van Rossum272841c1996-08-19 23:06:45 +00001261#ifdef GMP2
1262 if (d0._mp_size != 1 || d0._mp_d[0] != 1)
1263 res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
1264#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001265 if (d0.size != 1 || d0.d[0] != 1)
1266 res->size = 0; /* trouble: the gcd != 1; set s to zero */
Guido van Rossum272841c1996-08-19 23:06:45 +00001267#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001268 else {
1269#ifdef MPZ_MDIV_BUG
1270 /* watch out here! first check the signs, and then perform
1271 the mpz_mod() since mod could point to res */
1272 if ((s0.size < 0) != (mod->size < 0)) {
1273 mpz_mod(res, &s0, mod);
1274
1275 if (res->size)
1276 mpz_add(res, res, mod);
1277 }
1278 else
1279 mpz_mod(res, &s0, mod);
1280
1281#else /* def MPZ_MDIV_BUG */
1282 mpz_mmod(res, &s0, mod);
1283#endif /* def MPZ_MDIV_BUG else */
1284 }
1285
1286 mpz_clear(&s0);
1287 mpz_clear(&s1);
1288 mpz_clear(&q);
1289 mpz_clear(&r);
1290 mpz_clear(&x);
1291 mpz_clear(&d0);
1292 mpz_clear(&d1);
1293} /* mpz_divm() */
1294
1295
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001296static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001297MPZ_divm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001298 PyObject *self;
1299 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001300{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001301 PyObject *num, *den, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001302 mpzobject *mpznum, *mpzden, *mpzmod = NULL;
1303 mpzobject *z = NULL;
1304
1305
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001306 if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001307 return NULL;
1308
1309 if ((mpznum = mpz_mpzcoerce(num)) == NULL
1310 || (mpzden = mpz_mpzcoerce(den)) == NULL
1311 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1312 || (z = newmpzobject()) == NULL ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001313 Py_XDECREF(mpznum);
1314 Py_XDECREF(mpzden);
1315 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001316 return NULL;
1317 }
1318
1319 mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
1320
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001321 Py_DECREF(mpznum);
1322 Py_DECREF(mpzden);
1323 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001324
1325 if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001326 Py_DECREF(z);
1327 PyErr_SetString(PyExc_ValueError,
1328 "gcd(den, mod) != 1 or num == 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001329 return NULL;
1330 }
1331
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001332 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001333} /* MPZ_divm() */
1334
1335
1336/* MPZ methods-as-attributes */
1337#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001338static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001339mpz_int(self, args)
1340 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001341 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001342#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001343static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001344mpz_int(self)
1345 mpzobject *self;
1346#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1347{
1348 long sli;
1349
1350
1351#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001352 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001353 return NULL;
1354#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1355
1356 if (mpz_size(&self->mpz) > 1
1357 || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001358 PyErr_SetString(PyExc_ValueError,
1359 "mpz.int() arg too long to convert");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001360 return NULL;
1361 }
1362
1363 if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
1364 sli = -sli;
1365
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001366 return PyInt_FromLong(sli);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001367} /* mpz_int() */
1368
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001369static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001370#ifdef MPZ_CONVERSIONS_AS_METHODS
1371mpz_long(self, args)
1372 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001373 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001374#else /* def MPZ_CONVERSIONS_AS_METHODS */
1375mpz_long(self)
1376 mpzobject *self;
1377#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1378{
1379 int i, isnegative;
1380 unsigned long int uli;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001381 PyLongObject *longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001382 int ldcount;
1383 int bitpointer, newbitpointer;
1384 MP_INT mpzscratch;
1385
1386
1387#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001388 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001389 return NULL;
1390#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1391
1392 /* determine length of python-long to be allocated */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001393 if ((longobjp = _PyLong_New(i = (int)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001394 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
1395 + SHIFT - 1) /
1396 SHIFT))) == NULL)
1397 return NULL;
1398
1399 /* determine sign, and copy self to scratch var */
1400 mpz_init_set(&mpzscratch, &self->mpz);
Guido van Rossum272841c1996-08-19 23:06:45 +00001401 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001402 mpz_neg(&mpzscratch, &mpzscratch);
1403
1404 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001405 e.g. dismantle mpzscratch, build PyLongObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001406
1407 bitpointer = 0; /* the number of valid bits in stock */
1408 newbitpointer = 0;
1409 ldcount = 0; /* the python-long limb counter */
1410 uli = (unsigned long int)0;
1411 while (i--) {
1412 longobjp->ob_digit[ldcount] = uli & MASK;
1413
1414 /* check if we've had enough bits for this digit */
1415 if (bitpointer < SHIFT) {
1416 uli = mpz_get_ui(&mpzscratch);
1417 longobjp->ob_digit[ldcount] |=
1418 (uli << bitpointer) & MASK;
1419 uli >>= SHIFT-bitpointer;
1420 bitpointer += BITS_PER_MP_LIMB;
1421 mpz_div_2exp(&mpzscratch, &mpzscratch,
1422 BITS_PER_MP_LIMB);
1423 }
1424 else
1425 uli >>= SHIFT;
1426 bitpointer -= SHIFT;
1427 ldcount++;
1428 }
1429
1430 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1431 mpz_clear(&mpzscratch);
1432 assert(ldcount <= longobjp->ob_size);
1433
1434 /* long_normalize() is file-static */
1435 /* longobjp = long_normalize(longobjp); */
1436 while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
1437 ldcount--;
1438 longobjp->ob_size = ldcount;
1439
1440
1441 if (isnegative)
1442 longobjp->ob_size = -longobjp->ob_size;
1443
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001444 return (PyObject *)longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001445
1446} /* mpz_long() */
1447
1448
1449/* I would have avoided pow() anyways, so ... */
1450static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
1451
1452#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001453static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001454mpz_float(self, args)
1455 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001456 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001457#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001458static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001459mpz_float(self)
1460 mpzobject *self;
1461#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1462{
1463 int i, isnegative;
1464 double x;
1465 double mulstate;
1466 MP_INT mpzscratch;
1467
1468
1469#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001470 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001471 return NULL;
1472#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1473
1474 i = (int)mpz_size(&self->mpz);
1475
1476 /* determine sign, and copy abs(self) to scratch var */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001477 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
1478 {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001479 mpz_init(&mpzscratch);
1480 mpz_neg(&mpzscratch, &self->mpz);
1481 }
1482 else
1483 mpz_init_set(&mpzscratch, &self->mpz);
1484
1485 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001486 e.g. dismantle mpzscratch, build PyFloatObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001487
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001488 /* Can this overflow? Dunno, protect against that possibility. */
1489 PyFPE_START_PROTECT("mpz_float", return 0)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001490 x = 0.0;
1491 mulstate = 1.0;
1492 while (i--) {
1493 x += mulstate * mpz_get_ui(&mpzscratch);
1494 mulstate *= multiplier;
1495 mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
1496 }
Guido van Rossum45b83911997-03-14 04:32:50 +00001497 PyFPE_END_PROTECT(mulstate)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001498
1499 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1500 mpz_clear(&mpzscratch);
1501
1502 if (isnegative)
1503 x = -x;
1504
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001505 return PyFloat_FromDouble(x);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001506
1507} /* mpz_float() */
1508
1509#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001510static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001511mpz_hex(self, args)
1512 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001513 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001514#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001515static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001516mpz_hex(self)
1517 mpzobject *self;
1518#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1519{
1520#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001521 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001522 return NULL;
1523#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1524
1525 return mpz_format(self, 16, (unsigned char)1);
1526} /* mpz_hex() */
1527
1528#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001529static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001530mpz_oct(self, args)
1531 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001532 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001533#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001534static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001535mpz_oct(self)
1536 mpzobject *self;
1537#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1538{
1539#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001540 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001541 return NULL;
1542#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1543
1544 return mpz_format(self, 8, (unsigned char)1);
1545} /* mpz_oct() */
1546
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001547static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001548mpz_binary(self, args)
1549 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001550 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001551{
1552 int size;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001553 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001554 char *cp;
1555 MP_INT mp;
1556 unsigned long ldigit;
1557
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001558 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001559 return NULL;
1560
1561 if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001562 PyErr_SetString(PyExc_ValueError,
1563 "mpz.binary() arg must be >= 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001564 return NULL;
1565 }
1566
1567 mpz_init_set(&mp, &self->mpz);
1568 size = (int)mpz_size(&mp);
1569
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001570 if ((strobjp = (PyStringObject *)
1571 PyString_FromStringAndSize(
1572 (char *)0, size * sizeof (unsigned long int))) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001573 return NULL;
1574
1575 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001576 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001577
1578 /* this has been programmed using a (fairly) decent lib-i/f it could
1579 be must faster if we looked into the GMP lib */
1580 while (size--) {
1581 ldigit = mpz_get_ui(&mp);
1582 mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
1583 *cp++ = (unsigned char)(ldigit & 0xFF);
1584 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1585 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1586 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1587 }
1588
1589 while (strobjp->ob_size && !*--cp)
1590 strobjp->ob_size--;
1591
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001592 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001593} /* mpz_binary() */
1594
1595
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001596static PyMethodDef mpz_methods[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001597#ifdef MPZ_CONVERSIONS_AS_METHODS
1598 {"int", mpz_int},
1599 {"long", mpz_long},
1600 {"float", mpz_float},
1601 {"hex", mpz_hex},
1602 {"oct", mpz_oct},
1603#endif /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001604 {"binary", (PyCFunction)mpz_binary},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001605 {NULL, NULL} /* sentinel */
1606};
1607
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001608static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001609mpz_getattr(self, name)
1610 mpzobject *self;
1611 char *name;
1612{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001613 return Py_FindMethod(mpz_methods, (PyObject *)self, name);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001614} /* mpz_getattr() */
1615
1616
1617static int
1618mpz_coerce(pv, pw)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001619 PyObject **pv;
1620 PyObject **pw;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001621{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001622 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001623
1624#ifdef MPZ_DEBUG
1625 fputs("mpz_coerce() called...\n", stderr);
1626#endif /* def MPZ_DEBUG */
1627
1628 assert(is_mpzobject(*pv));
1629
1630 /* always convert other arg to mpz value, except for floats */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001631 if (!PyFloat_Check(*pw)) {
1632 if ((z = (PyObject *)mpz_mpzcoerce(*pw)) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001633 return -1; /* -1: an error always has been set */
1634
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001635 Py_INCREF(*pv);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001636 *pw = z;
1637 }
1638 else {
1639 if ((z = mpz_float(*pv, NULL)) == NULL)
1640 return -1;
1641
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001642 Py_INCREF(*pw);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001643 *pv = z;
1644 }
1645 return 0; /* coercion succeeded */
1646
1647} /* mpz_coerce() */
1648
1649
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001650static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001651mpz_repr(v)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001652 PyObject *v;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001653{
1654 return mpz_format(v, 10, (unsigned char)1);
1655} /* mpz_repr() */
1656
1657
1658
Guido van Rossumb6775db1994-08-01 11:34:53 +00001659#define UF (unaryfunc)
1660#define BF (binaryfunc)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001661#define TF (ternaryfunc)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001662#define IF (inquiry)
1663#define CF (coercion)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001664
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001665static PyNumberMethods mpz_as_number = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001666 BF mpz_addition, /*nb_add*/
1667 BF mpz_substract, /*nb_subtract*/
1668 BF mpz_multiply, /*nb_multiply*/
1669 BF mpz_divide, /*nb_divide*/
1670 BF mpz_remainder, /*nb_remainder*/
1671 BF mpz_div_and_mod, /*nb_divmod*/
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001672 TF mpz_power, /*nb_power*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001673 UF mpz_negative, /*nb_negative*/
1674 UF mpz_positive, /*tp_positive*/
1675 UF mpz_absolute, /*tp_absolute*/
1676 IF mpz_nonzero, /*tp_nonzero*/
Guido van Rossum272841c1996-08-19 23:06:45 +00001677 UF py_mpz_invert, /*nb_invert*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001678 BF mpz_lshift, /*nb_lshift*/
1679 BF mpz_rshift, /*nb_rshift*/
1680 BF mpz_andfunc, /*nb_and*/
1681 BF mpz_xorfunc, /*nb_xor*/
1682 BF mpz_orfunc, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001683 CF mpz_coerce, /*nb_coerce*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001684#ifndef MPZ_CONVERSIONS_AS_METHODS
1685 UF mpz_int, /*nb_int*/
1686 UF mpz_long, /*nb_long*/
1687 UF mpz_float, /*nb_float*/
1688 UF mpz_oct, /*nb_oct*/
1689 UF mpz_hex, /*nb_hex*/
1690#endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1691};
1692
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001693static PyTypeObject MPZtype = {
1694 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001695 0, /*ob_size*/
1696 "mpz", /*tp_name*/
1697 sizeof(mpzobject), /*tp_size*/
1698 0, /*tp_itemsize*/
1699 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001700 (destructor)mpz_dealloc, /*tp_dealloc*/
1701 0, /*tp_print*/
1702 (getattrfunc)mpz_getattr, /*tp_getattr*/
1703 0, /*tp_setattr*/
1704 (cmpfunc)mpz_compare, /*tp_compare*/
1705 (reprfunc)mpz_repr, /*tp_repr*/
1706 &mpz_as_number, /*tp_as_number*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001707};
1708
1709/* List of functions exported by this module */
1710
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001711static PyMethodDef mpz_functions[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001712#if 0
1713 {initialiser_name, MPZ_mpz},
1714#else /* 0 */
Barry Warsawabb7efe1996-12-09 23:22:35 +00001715 /* until guido ``fixes'' struct PyMethodDef */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001716 {(char *)initialiser_name, MPZ_mpz},
1717#endif /* 0 else */
1718 {"powm", MPZ_powm},
1719 {"gcd", MPZ_gcd},
1720 {"gcdext", MPZ_gcdext},
1721 {"sqrt", MPZ_sqrt},
1722 {"sqrtrem", MPZ_sqrtrem},
1723 {"divm", MPZ_divm},
1724 {NULL, NULL} /* Sentinel */
1725};
1726
1727
1728/* #define MP_TEST_ALLOC */
1729
1730#ifdef MP_TEST_ALLOC
1731#define MP_TEST_SIZE 4
1732static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
1733static mp_test_error( location )
1734 int *location;
1735{
1736 /* assumptions: *alloc returns address dividable by 4,
1737 mpz_* routines allocate in chunks dividable by four */
1738 fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001739 Py_FatalError("MP_TEST_ERROR");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001740} /* static mp_test_error() */
1741#define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1742#define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1743#define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1744 ; \
1745 else \
1746 mp_test_error((int *)((char *)(basep) + size))
1747#else /* def MP_TEST_ALLOC */
1748#define MP_EXTRA_ALLOC(size) (size)
1749#define MP_SET_TEST(basep,size)
1750#define MP_DO_TEST(basep,size)
1751#endif /* def MP_TEST_ALLOC else */
1752
1753void *mp_allocate( alloc_size )
1754 size_t alloc_size;
1755{
1756 void *res;
1757
1758#ifdef MPZ_DEBUG
1759 fprintf(stderr, "mp_allocate : size %ld\n",
1760 alloc_size);
1761#endif /* def MPZ_DEBUG */
1762
1763 if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001764 Py_FatalError("mp_allocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001765
1766#ifdef MPZ_DEBUG
1767 fprintf(stderr, "mp_allocate : address 0x%08x\n", res);
1768#endif /* def MPZ_DEBUG */
1769
1770 MP_SET_TEST(res,alloc_size);
1771
1772 return res;
1773} /* mp_allocate() */
1774
1775
1776void *mp_reallocate( ptr, old_size, new_size )
1777 void *ptr;
1778 size_t old_size;
1779 size_t new_size;
1780{
1781 void *res;
1782
1783#ifdef MPZ_DEBUG
1784 fprintf(stderr, "mp_reallocate: old address 0x%08x, old size %ld\n",
1785 ptr, old_size);
1786#endif /* def MPZ_DEBUG */
1787
1788 MP_DO_TEST(ptr, old_size);
1789
1790 if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001791 Py_FatalError("mp_reallocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001792
1793#ifdef MPZ_DEBUG
1794 fprintf(stderr, "mp_reallocate: new address 0x%08x, new size %ld\n",
1795 res, new_size);
1796#endif /* def MPZ_DEBUG */
1797
1798 MP_SET_TEST(res, new_size);
1799
1800 return res;
1801} /* mp_reallocate() */
1802
1803
1804void mp_free( ptr, size )
1805 void *ptr;
1806 size_t size;
1807{
1808
1809#ifdef MPZ_DEBUG
1810 fprintf(stderr, "mp_free : old address 0x%08x, old size %ld\n",
1811 ptr, size);
1812#endif /* def MPZ_DEBUG */
1813
1814 MP_DO_TEST(ptr, size);
1815 free(ptr);
1816} /* mp_free() */
1817
1818
1819
1820/* Initialize this module. */
1821
1822void
1823initmpz()
1824{
Fred Drakefcc6c681998-04-03 15:33:43 +00001825 PyObject *module;
1826 PyObject *dict;
1827
Guido van Rossum5f59d601992-12-14 16:59:51 +00001828#ifdef MPZ_DEBUG
1829 fputs( "initmpz() called...\n", stderr );
1830#endif /* def MPZ_DEBUG */
1831
1832 mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
Fred Drakefcc6c681998-04-03 15:33:43 +00001833 module = Py_InitModule("mpz", mpz_functions);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001834
1835 /* create some frequently used constants */
1836 if ((mpz_value_zero = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001837 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001838 mpz_set_ui(&mpz_value_zero->mpz, (unsigned long int)0);
1839
1840 if ((mpz_value_one = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001841 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001842 mpz_set_ui(&mpz_value_one->mpz, (unsigned long int)1);
1843
1844 if ((mpz_value_mone = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001845 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001846 mpz_set_si(&mpz_value_mone->mpz, (long)-1);
1847
Fred Drakefcc6c681998-04-03 15:33:43 +00001848 dict = PyModule_GetDict(module);
1849 if (dict != NULL) {
1850 PyDict_SetItemString(dict, "MPZType", (PyObject*)&MPZtype);
1851 }
1852
Guido van Rossum5f59d601992-12-14 16:59:51 +00001853} /* initmpz() */
1854#ifdef MAKEDUMMYINT
1855int _mpz_dummy_int; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1856#endif /* def MAKEDUMMYINT */