blob: 0400605ed662da56702f1cb49d01123260153f29 [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 Rossum5f59d601992-12-14 16:59:51 +0000972 char *cp;
973 int len;
974 MP_INT mplongdigit;
975
Barry Warsaw3bdf7461996-12-09 23:16:31 +0000976 if (!PyArg_Parse(objp, "s#", &cp, &len))
Guido van Rossum5f59d601992-12-14 16:59:51 +0000977 return NULL;
978
979 if ((mpzp = newmpzobject()) == NULL)
980 return NULL;
981
982 mpz_set_si(&mpzp->mpz, 0L);
983 mpz_init(&mplongdigit);
984
985 /* let's do it the same way as with the long conversion:
986 without thinking how it can be faster (-: :-) */
987
988 cp += len;
989 while (len--) {
990 mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
991 mpz_mul_2exp(&mplongdigit,&mplongdigit,
992 (unsigned long int)len * 8);
993 mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
994 }
995
996 /* get rid of allocation for tmp variable */
997 mpz_clear(&mplongdigit);
998 }
999 else if (is_mpzobject(objp)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001000 Py_INCREF(objp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001001 mpzp = (mpzobject *)objp;
1002 }
1003 else {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001004 PyErr_SetString(PyExc_TypeError,
1005"mpz.mpz() expects integer, long, string or mpz object argument");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001006 return NULL;
1007 }
1008
1009
1010#ifdef MPZ_DEBUG
1011 fputs("MPZ_mpz: created mpz=", stderr);
1012 mpz_out_str(stderr, 10, &mpzp->mpz);
1013 putc('\n', stderr);
1014#endif /* def MPZ_DEBUG */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001015 return (PyObject *)mpzp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001016} /* MPZ_mpz() */
1017
1018static mpzobject *
1019mpz_mpzcoerce(z)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001020 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001021{
1022 /* shortcut: 9 out of 10 times the type is already ok */
1023 if (is_mpzobject(z)) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001024 Py_INCREF(z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001025 return (mpzobject *)z; /* coercion succeeded */
1026 }
1027
1028 /* what types do we accept?: intobjects and longobjects */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001029 if (PyInt_Check(z) || PyLong_Check(z))
1030 return (mpzobject *)MPZ_mpz((PyObject *)NULL, z);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001031
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001032 PyErr_SetString(PyExc_TypeError,
1033 "number coercion (to mpzobject) failed");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001034 return NULL;
1035} /* mpz_mpzcoerce() */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001036
1037/* Forward */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001038static void mpz_divm Py_PROTO((MP_INT *res, const MP_INT *num,
1039 const MP_INT *den, const MP_INT *mod));
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001040
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001041static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001042MPZ_powm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001043 PyObject *self;
1044 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001045{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001046 PyObject *base, *exp, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001047 mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
1048 mpzobject *z;
1049 int tstres;
1050
1051
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001052 if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001053 return NULL;
1054
1055 if ((mpzbase = mpz_mpzcoerce(base)) == NULL
1056 || (mpzexp = mpz_mpzcoerce(exp)) == NULL
1057 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1058 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001059 Py_XDECREF(mpzbase);
1060 Py_XDECREF(mpzexp);
1061 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001062 return NULL;
1063 }
1064
1065 if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001066 Py_INCREF(mpz_value_one);
1067 return (PyObject *)mpz_value_one;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001068 }
1069
1070 if (tstres < 0) {
1071 MP_INT absexp;
1072 /* negative exp */
1073
1074 mpz_init_set(&absexp, &mpzexp->mpz);
1075 mpz_abs(&absexp, &absexp);
1076 mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
1077
1078 mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
1079
1080 mpz_clear(&absexp);
1081 }
1082 else {
1083 mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
1084 }
1085
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001086 Py_DECREF(mpzbase);
1087 Py_DECREF(mpzexp);
1088 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001089
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001090 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001091} /* MPZ_powm() */
1092
1093
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001094static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001095MPZ_gcd(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001096 PyObject *self;
1097 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001098{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001099 PyObject *op1, *op2;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001100 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1101 mpzobject *z;
1102
1103
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001104 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001105 return NULL;
1106
1107 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1108 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
1109 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001110 Py_XDECREF(mpzop1);
1111 Py_XDECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001112 return NULL;
1113 }
1114
1115 /* ok, we have three mpzobjects, and an initialised result holder */
1116 mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
1117
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001118 Py_DECREF(mpzop1);
1119 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001120
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001121 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001122} /* MPZ_gcd() */
1123
1124
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001125static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001126MPZ_gcdext(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001127 PyObject *self;
1128 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001129{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001130 PyObject *op1, *op2, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001131 mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
1132 mpzobject *g = NULL, *s = NULL, *t = NULL;
1133
1134
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001135 if (!PyArg_Parse(args, "(OO)", &op1, &op2))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001136 return NULL;
1137
1138 if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
1139 || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001140 || (z = PyTuple_New(3)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001141 || (g = newmpzobject()) == NULL
1142 || (s = newmpzobject()) == NULL
1143 || (t = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001144 Py_XDECREF(mpzop1);
1145 Py_XDECREF(mpzop2);
1146 Py_XDECREF(z);
1147 Py_XDECREF(g);
1148 Py_XDECREF(s);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001149 /*Py_XDECREF(t);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001150 return NULL;
1151 }
1152
1153 mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
1154
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001155 Py_DECREF(mpzop1);
1156 Py_DECREF(mpzop2);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001157
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001158 (void)PyTuple_SetItem(z, 0, (PyObject *)g);
1159 (void)PyTuple_SetItem(z, 1, (PyObject *)s);
1160 (void)PyTuple_SetItem(z, 2, (PyObject *)t);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001161
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001162 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001163} /* MPZ_gcdext() */
1164
1165
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001166static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001167MPZ_sqrt(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001168 PyObject *self;
1169 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001170{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001171 PyObject *op;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001172 mpzobject *mpzop = NULL;
1173 mpzobject *z;
1174
1175
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001176 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001177 return NULL;
1178
1179 if ((mpzop = mpz_mpzcoerce(op)) == NULL
1180 || (z = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001181 Py_XDECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001182 return NULL;
1183 }
1184
1185 mpz_sqrt(&z->mpz, &mpzop->mpz);
1186
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001187 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001188
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001189 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001190} /* MPZ_sqrt() */
1191
1192
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001193static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001194MPZ_sqrtrem(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001195 PyObject *self;
1196 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001197{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001198 PyObject *op, *z = NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001199 mpzobject *mpzop = NULL;
1200 mpzobject *root = NULL, *rem = NULL;
1201
1202
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001203 if (!PyArg_Parse(args, "O", &op))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001204 return NULL;
1205
1206 if ((mpzop = mpz_mpzcoerce(op)) == NULL
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001207 || (z = PyTuple_New(2)) == NULL
Guido van Rossum5f59d601992-12-14 16:59:51 +00001208 || (root = newmpzobject()) == NULL
1209 || (rem = newmpzobject()) == NULL) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001210 Py_XDECREF(mpzop);
1211 Py_XDECREF(z);
1212 Py_XDECREF(root);
Barry Warsawabb7efe1996-12-09 23:22:35 +00001213 /*Py_XDECREF(rem);*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001214 return NULL;
1215 }
1216
1217 mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
1218
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001219 Py_DECREF(mpzop);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001220
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001221 (void)PyTuple_SetItem(z, 0, (PyObject *)root);
1222 (void)PyTuple_SetItem(z, 1, (PyObject *)rem);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001223
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001224 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001225} /* MPZ_sqrtrem() */
1226
1227
Guido van Rossum67a5fdb1993-12-17 12:09:14 +00001228static void
Guido van Rossum5f59d601992-12-14 16:59:51 +00001229#if __STDC__
1230mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
1231#else
1232mpz_divm(res, num, den, mod)
1233 MP_INT *res;
1234 const MP_INT *num;
1235 const MP_INT *den;
1236 const MP_INT *mod;
1237#endif
1238{
1239 MP_INT s0, s1, q, r, x, d0, d1;
1240
1241 mpz_init_set(&s0, num);
1242 mpz_init_set_ui(&s1, 0);
1243 mpz_init(&q);
1244 mpz_init(&r);
1245 mpz_init(&x);
1246 mpz_init_set(&d0, den);
1247 mpz_init_set(&d1, mod);
1248
Guido van Rossum272841c1996-08-19 23:06:45 +00001249#ifdef GMP2
1250 while (d1._mp_size != 0) {
1251#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001252 while (d1.size != 0) {
Guido van Rossum272841c1996-08-19 23:06:45 +00001253#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001254 mpz_divmod(&q, &r, &d0, &d1);
1255 mpz_set(&d0, &d1);
1256 mpz_set(&d1, &r);
1257
1258 mpz_mul(&x, &s1, &q);
1259 mpz_sub(&x, &s0, &x);
1260 mpz_set(&s0, &s1);
1261 mpz_set(&s1, &x);
1262 }
1263
Guido van Rossum272841c1996-08-19 23:06:45 +00001264#ifdef GMP2
1265 if (d0._mp_size != 1 || d0._mp_d[0] != 1)
1266 res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
1267#else
Guido van Rossum5f59d601992-12-14 16:59:51 +00001268 if (d0.size != 1 || d0.d[0] != 1)
1269 res->size = 0; /* trouble: the gcd != 1; set s to zero */
Guido van Rossum272841c1996-08-19 23:06:45 +00001270#endif
Guido van Rossum5f59d601992-12-14 16:59:51 +00001271 else {
1272#ifdef MPZ_MDIV_BUG
1273 /* watch out here! first check the signs, and then perform
1274 the mpz_mod() since mod could point to res */
1275 if ((s0.size < 0) != (mod->size < 0)) {
1276 mpz_mod(res, &s0, mod);
1277
1278 if (res->size)
1279 mpz_add(res, res, mod);
1280 }
1281 else
1282 mpz_mod(res, &s0, mod);
1283
1284#else /* def MPZ_MDIV_BUG */
1285 mpz_mmod(res, &s0, mod);
1286#endif /* def MPZ_MDIV_BUG else */
1287 }
1288
1289 mpz_clear(&s0);
1290 mpz_clear(&s1);
1291 mpz_clear(&q);
1292 mpz_clear(&r);
1293 mpz_clear(&x);
1294 mpz_clear(&d0);
1295 mpz_clear(&d1);
1296} /* mpz_divm() */
1297
1298
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001299static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001300MPZ_divm(self, args)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001301 PyObject *self;
1302 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001303{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001304 PyObject *num, *den, *mod;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001305 mpzobject *mpznum, *mpzden, *mpzmod = NULL;
1306 mpzobject *z = NULL;
1307
1308
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001309 if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001310 return NULL;
1311
1312 if ((mpznum = mpz_mpzcoerce(num)) == NULL
1313 || (mpzden = mpz_mpzcoerce(den)) == NULL
1314 || (mpzmod = mpz_mpzcoerce(mod)) == NULL
1315 || (z = newmpzobject()) == NULL ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001316 Py_XDECREF(mpznum);
1317 Py_XDECREF(mpzden);
1318 Py_XDECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001319 return NULL;
1320 }
1321
1322 mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
1323
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001324 Py_DECREF(mpznum);
1325 Py_DECREF(mpzden);
1326 Py_DECREF(mpzmod);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001327
1328 if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001329 Py_DECREF(z);
1330 PyErr_SetString(PyExc_ValueError,
1331 "gcd(den, mod) != 1 or num == 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001332 return NULL;
1333 }
1334
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001335 return (PyObject *)z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001336} /* MPZ_divm() */
1337
1338
1339/* MPZ methods-as-attributes */
1340#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001341static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001342mpz_int(self, args)
1343 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001344 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001345#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001346static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001347mpz_int(self)
1348 mpzobject *self;
1349#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1350{
1351 long sli;
1352
1353
1354#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001355 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001356 return NULL;
1357#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1358
1359 if (mpz_size(&self->mpz) > 1
1360 || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001361 PyErr_SetString(PyExc_ValueError,
1362 "mpz.int() arg too long to convert");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001363 return NULL;
1364 }
1365
1366 if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
1367 sli = -sli;
1368
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001369 return PyInt_FromLong(sli);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001370} /* mpz_int() */
1371
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001372static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001373#ifdef MPZ_CONVERSIONS_AS_METHODS
1374mpz_long(self, args)
1375 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001376 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001377#else /* def MPZ_CONVERSIONS_AS_METHODS */
1378mpz_long(self)
1379 mpzobject *self;
1380#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1381{
1382 int i, isnegative;
1383 unsigned long int uli;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001384 PyLongObject *longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001385 int ldcount;
1386 int bitpointer, newbitpointer;
1387 MP_INT mpzscratch;
1388
1389
1390#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001391 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001392 return NULL;
1393#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1394
1395 /* determine length of python-long to be allocated */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001396 if ((longobjp = _PyLong_New(i = (int)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001397 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
1398 + SHIFT - 1) /
1399 SHIFT))) == NULL)
1400 return NULL;
1401
1402 /* determine sign, and copy self to scratch var */
1403 mpz_init_set(&mpzscratch, &self->mpz);
Guido van Rossum272841c1996-08-19 23:06:45 +00001404 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001405 mpz_neg(&mpzscratch, &mpzscratch);
1406
1407 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001408 e.g. dismantle mpzscratch, build PyLongObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001409
1410 bitpointer = 0; /* the number of valid bits in stock */
1411 newbitpointer = 0;
1412 ldcount = 0; /* the python-long limb counter */
1413 uli = (unsigned long int)0;
1414 while (i--) {
1415 longobjp->ob_digit[ldcount] = uli & MASK;
1416
1417 /* check if we've had enough bits for this digit */
1418 if (bitpointer < SHIFT) {
1419 uli = mpz_get_ui(&mpzscratch);
1420 longobjp->ob_digit[ldcount] |=
1421 (uli << bitpointer) & MASK;
1422 uli >>= SHIFT-bitpointer;
1423 bitpointer += BITS_PER_MP_LIMB;
1424 mpz_div_2exp(&mpzscratch, &mpzscratch,
1425 BITS_PER_MP_LIMB);
1426 }
1427 else
1428 uli >>= SHIFT;
1429 bitpointer -= SHIFT;
1430 ldcount++;
1431 }
1432
1433 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1434 mpz_clear(&mpzscratch);
1435 assert(ldcount <= longobjp->ob_size);
1436
1437 /* long_normalize() is file-static */
1438 /* longobjp = long_normalize(longobjp); */
1439 while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
1440 ldcount--;
1441 longobjp->ob_size = ldcount;
1442
1443
1444 if (isnegative)
1445 longobjp->ob_size = -longobjp->ob_size;
1446
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001447 return (PyObject *)longobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001448
1449} /* mpz_long() */
1450
1451
1452/* I would have avoided pow() anyways, so ... */
1453static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
1454
1455#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001456static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001457mpz_float(self, args)
1458 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001459 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001460#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001461static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001462mpz_float(self)
1463 mpzobject *self;
1464#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1465{
1466 int i, isnegative;
1467 double x;
1468 double mulstate;
1469 MP_INT mpzscratch;
1470
1471
1472#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001473 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001474 return NULL;
1475#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1476
1477 i = (int)mpz_size(&self->mpz);
1478
1479 /* determine sign, and copy abs(self) to scratch var */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001480 if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
1481 {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001482 mpz_init(&mpzscratch);
1483 mpz_neg(&mpzscratch, &self->mpz);
1484 }
1485 else
1486 mpz_init_set(&mpzscratch, &self->mpz);
1487
1488 /* let those bits come, let those bits go,
Barry Warsawabb7efe1996-12-09 23:22:35 +00001489 e.g. dismantle mpzscratch, build PyFloatObject */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001490
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001491 /* Can this overflow? Dunno, protect against that possibility. */
1492 PyFPE_START_PROTECT("mpz_float", return 0)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001493 x = 0.0;
1494 mulstate = 1.0;
1495 while (i--) {
1496 x += mulstate * mpz_get_ui(&mpzscratch);
1497 mulstate *= multiplier;
1498 mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
1499 }
Guido van Rossum45b83911997-03-14 04:32:50 +00001500 PyFPE_END_PROTECT(mulstate)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001501
1502 assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
1503 mpz_clear(&mpzscratch);
1504
1505 if (isnegative)
1506 x = -x;
1507
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001508 return PyFloat_FromDouble(x);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001509
1510} /* mpz_float() */
1511
1512#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001513static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001514mpz_hex(self, args)
1515 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001516 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001517#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001518static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001519mpz_hex(self)
1520 mpzobject *self;
1521#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1522{
1523#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001524 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001525 return NULL;
1526#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1527
1528 return mpz_format(self, 16, (unsigned char)1);
1529} /* mpz_hex() */
1530
1531#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001532static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001533mpz_oct(self, args)
1534 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001535 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001536#else /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001537static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001538mpz_oct(self)
1539 mpzobject *self;
1540#endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1541{
1542#ifdef MPZ_CONVERSIONS_AS_METHODS
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001543 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001544 return NULL;
1545#endif /* def MPZ_CONVERSIONS_AS_METHODS */
1546
1547 return mpz_format(self, 8, (unsigned char)1);
1548} /* mpz_oct() */
1549
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001550static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001551mpz_binary(self, args)
1552 mpzobject *self;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001553 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001554{
1555 int size;
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001556 PyStringObject *strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001557 char *cp;
1558 MP_INT mp;
1559 unsigned long ldigit;
1560
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001561 if (!PyArg_NoArgs(args))
Guido van Rossum5f59d601992-12-14 16:59:51 +00001562 return NULL;
1563
1564 if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001565 PyErr_SetString(PyExc_ValueError,
1566 "mpz.binary() arg must be >= 0");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001567 return NULL;
1568 }
1569
1570 mpz_init_set(&mp, &self->mpz);
1571 size = (int)mpz_size(&mp);
1572
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001573 if ((strobjp = (PyStringObject *)
1574 PyString_FromStringAndSize(
1575 (char *)0, size * sizeof (unsigned long int))) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001576 return NULL;
1577
1578 /* get the beginning of the string memory and start copying things */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001579 cp = PyString_AS_STRING(strobjp);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001580
1581 /* this has been programmed using a (fairly) decent lib-i/f it could
1582 be must faster if we looked into the GMP lib */
1583 while (size--) {
1584 ldigit = mpz_get_ui(&mp);
1585 mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
1586 *cp++ = (unsigned char)(ldigit & 0xFF);
1587 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1588 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1589 *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
1590 }
1591
1592 while (strobjp->ob_size && !*--cp)
1593 strobjp->ob_size--;
1594
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001595 return (PyObject *)strobjp;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001596} /* mpz_binary() */
1597
1598
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001599static PyMethodDef mpz_methods[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001600#ifdef MPZ_CONVERSIONS_AS_METHODS
1601 {"int", mpz_int},
1602 {"long", mpz_long},
1603 {"float", mpz_float},
1604 {"hex", mpz_hex},
1605 {"oct", mpz_oct},
1606#endif /* def MPZ_CONVERSIONS_AS_METHODS */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001607 {"binary", (PyCFunction)mpz_binary},
Guido van Rossum5f59d601992-12-14 16:59:51 +00001608 {NULL, NULL} /* sentinel */
1609};
1610
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001611static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001612mpz_getattr(self, name)
1613 mpzobject *self;
1614 char *name;
1615{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001616 return Py_FindMethod(mpz_methods, (PyObject *)self, name);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001617} /* mpz_getattr() */
1618
1619
1620static int
1621mpz_coerce(pv, pw)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001622 PyObject **pv;
1623 PyObject **pw;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001624{
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001625 PyObject *z;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001626
1627#ifdef MPZ_DEBUG
1628 fputs("mpz_coerce() called...\n", stderr);
1629#endif /* def MPZ_DEBUG */
1630
1631 assert(is_mpzobject(*pv));
1632
1633 /* always convert other arg to mpz value, except for floats */
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001634 if (!PyFloat_Check(*pw)) {
1635 if ((z = (PyObject *)mpz_mpzcoerce(*pw)) == NULL)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001636 return -1; /* -1: an error always has been set */
1637
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001638 Py_INCREF(*pv);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001639 *pw = z;
1640 }
1641 else {
1642 if ((z = mpz_float(*pv, NULL)) == NULL)
1643 return -1;
1644
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001645 Py_INCREF(*pw);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001646 *pv = z;
1647 }
1648 return 0; /* coercion succeeded */
1649
1650} /* mpz_coerce() */
1651
1652
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001653static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +00001654mpz_repr(v)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001655 PyObject *v;
Guido van Rossum5f59d601992-12-14 16:59:51 +00001656{
1657 return mpz_format(v, 10, (unsigned char)1);
1658} /* mpz_repr() */
1659
1660
1661
Guido van Rossumb6775db1994-08-01 11:34:53 +00001662#define UF (unaryfunc)
1663#define BF (binaryfunc)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001664#define TF (ternaryfunc)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001665#define IF (inquiry)
1666#define CF (coercion)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001667
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001668static PyNumberMethods mpz_as_number = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001669 BF mpz_addition, /*nb_add*/
1670 BF mpz_substract, /*nb_subtract*/
1671 BF mpz_multiply, /*nb_multiply*/
1672 BF mpz_divide, /*nb_divide*/
1673 BF mpz_remainder, /*nb_remainder*/
1674 BF mpz_div_and_mod, /*nb_divmod*/
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001675 TF mpz_power, /*nb_power*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001676 UF mpz_negative, /*nb_negative*/
1677 UF mpz_positive, /*tp_positive*/
1678 UF mpz_absolute, /*tp_absolute*/
1679 IF mpz_nonzero, /*tp_nonzero*/
Guido van Rossum272841c1996-08-19 23:06:45 +00001680 UF py_mpz_invert, /*nb_invert*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001681 BF mpz_lshift, /*nb_lshift*/
1682 BF mpz_rshift, /*nb_rshift*/
1683 BF mpz_andfunc, /*nb_and*/
1684 BF mpz_xorfunc, /*nb_xor*/
1685 BF mpz_orfunc, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001686 CF mpz_coerce, /*nb_coerce*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001687#ifndef MPZ_CONVERSIONS_AS_METHODS
1688 UF mpz_int, /*nb_int*/
1689 UF mpz_long, /*nb_long*/
1690 UF mpz_float, /*nb_float*/
1691 UF mpz_oct, /*nb_oct*/
1692 UF mpz_hex, /*nb_hex*/
1693#endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1694};
1695
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001696static PyTypeObject MPZtype = {
1697 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum5f59d601992-12-14 16:59:51 +00001698 0, /*ob_size*/
1699 "mpz", /*tp_name*/
1700 sizeof(mpzobject), /*tp_size*/
1701 0, /*tp_itemsize*/
1702 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001703 (destructor)mpz_dealloc, /*tp_dealloc*/
1704 0, /*tp_print*/
1705 (getattrfunc)mpz_getattr, /*tp_getattr*/
1706 0, /*tp_setattr*/
1707 (cmpfunc)mpz_compare, /*tp_compare*/
1708 (reprfunc)mpz_repr, /*tp_repr*/
1709 &mpz_as_number, /*tp_as_number*/
Guido van Rossum5f59d601992-12-14 16:59:51 +00001710};
1711
1712/* List of functions exported by this module */
1713
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001714static PyMethodDef mpz_functions[] = {
Guido van Rossum5f59d601992-12-14 16:59:51 +00001715#if 0
1716 {initialiser_name, MPZ_mpz},
1717#else /* 0 */
Barry Warsawabb7efe1996-12-09 23:22:35 +00001718 /* until guido ``fixes'' struct PyMethodDef */
Guido van Rossum5f59d601992-12-14 16:59:51 +00001719 {(char *)initialiser_name, MPZ_mpz},
1720#endif /* 0 else */
1721 {"powm", MPZ_powm},
1722 {"gcd", MPZ_gcd},
1723 {"gcdext", MPZ_gcdext},
1724 {"sqrt", MPZ_sqrt},
1725 {"sqrtrem", MPZ_sqrtrem},
1726 {"divm", MPZ_divm},
1727 {NULL, NULL} /* Sentinel */
1728};
1729
1730
1731/* #define MP_TEST_ALLOC */
1732
1733#ifdef MP_TEST_ALLOC
1734#define MP_TEST_SIZE 4
1735static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
1736static mp_test_error( location )
1737 int *location;
1738{
1739 /* assumptions: *alloc returns address dividable by 4,
1740 mpz_* routines allocate in chunks dividable by four */
1741 fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001742 Py_FatalError("MP_TEST_ERROR");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001743} /* static mp_test_error() */
1744#define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1745#define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1746#define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1747 ; \
1748 else \
1749 mp_test_error((int *)((char *)(basep) + size))
1750#else /* def MP_TEST_ALLOC */
1751#define MP_EXTRA_ALLOC(size) (size)
1752#define MP_SET_TEST(basep,size)
1753#define MP_DO_TEST(basep,size)
1754#endif /* def MP_TEST_ALLOC else */
1755
1756void *mp_allocate( alloc_size )
1757 size_t alloc_size;
1758{
1759 void *res;
1760
1761#ifdef MPZ_DEBUG
1762 fprintf(stderr, "mp_allocate : size %ld\n",
1763 alloc_size);
1764#endif /* def MPZ_DEBUG */
1765
1766 if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001767 Py_FatalError("mp_allocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001768
1769#ifdef MPZ_DEBUG
1770 fprintf(stderr, "mp_allocate : address 0x%08x\n", res);
1771#endif /* def MPZ_DEBUG */
1772
1773 MP_SET_TEST(res,alloc_size);
1774
1775 return res;
1776} /* mp_allocate() */
1777
1778
1779void *mp_reallocate( ptr, old_size, new_size )
1780 void *ptr;
1781 size_t old_size;
1782 size_t new_size;
1783{
1784 void *res;
1785
1786#ifdef MPZ_DEBUG
1787 fprintf(stderr, "mp_reallocate: old address 0x%08x, old size %ld\n",
1788 ptr, old_size);
1789#endif /* def MPZ_DEBUG */
1790
1791 MP_DO_TEST(ptr, old_size);
1792
1793 if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001794 Py_FatalError("mp_reallocate failure");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001795
1796#ifdef MPZ_DEBUG
1797 fprintf(stderr, "mp_reallocate: new address 0x%08x, new size %ld\n",
1798 res, new_size);
1799#endif /* def MPZ_DEBUG */
1800
1801 MP_SET_TEST(res, new_size);
1802
1803 return res;
1804} /* mp_reallocate() */
1805
1806
1807void mp_free( ptr, size )
1808 void *ptr;
1809 size_t size;
1810{
1811
1812#ifdef MPZ_DEBUG
1813 fprintf(stderr, "mp_free : old address 0x%08x, old size %ld\n",
1814 ptr, size);
1815#endif /* def MPZ_DEBUG */
1816
1817 MP_DO_TEST(ptr, size);
1818 free(ptr);
1819} /* mp_free() */
1820
1821
1822
1823/* Initialize this module. */
1824
1825void
1826initmpz()
1827{
Fred Drakefcc6c681998-04-03 15:33:43 +00001828 PyObject *module;
1829 PyObject *dict;
1830
Guido van Rossum5f59d601992-12-14 16:59:51 +00001831#ifdef MPZ_DEBUG
1832 fputs( "initmpz() called...\n", stderr );
1833#endif /* def MPZ_DEBUG */
1834
1835 mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
Fred Drakefcc6c681998-04-03 15:33:43 +00001836 module = Py_InitModule("mpz", mpz_functions);
Guido van Rossum5f59d601992-12-14 16:59:51 +00001837
1838 /* create some frequently used constants */
1839 if ((mpz_value_zero = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001840 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001841 mpz_set_ui(&mpz_value_zero->mpz, (unsigned long int)0);
1842
1843 if ((mpz_value_one = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001844 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001845 mpz_set_ui(&mpz_value_one->mpz, (unsigned long int)1);
1846
1847 if ((mpz_value_mone = newmpzobject()) == NULL)
Barry Warsaw3bdf7461996-12-09 23:16:31 +00001848 Py_FatalError("initmpz: can't initialize mpz constants");
Guido van Rossum5f59d601992-12-14 16:59:51 +00001849 mpz_set_si(&mpz_value_mone->mpz, (long)-1);
1850
Fred Drakefcc6c681998-04-03 15:33:43 +00001851 dict = PyModule_GetDict(module);
1852 if (dict != NULL) {
1853 PyDict_SetItemString(dict, "MPZType", (PyObject*)&MPZtype);
1854 }
1855
Guido van Rossum5f59d601992-12-14 16:59:51 +00001856} /* initmpz() */
1857#ifdef MAKEDUMMYINT
1858int _mpz_dummy_int; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1859#endif /* def MAKEDUMMYINT */