4 /* This module provides an interface to an alternate Multi-Precision
5 library, GNU MP in this case */
7 /* XXX note: everywhere where mpz_size is called,
8 sizeof (limb) == sizeof (long) has been assumed. */
15 #include <sys/types.h> /* For size_t */
18 ** These are the cpp-flags used in this file...
21 ** MPZ_MDIV_BUG works around the mpz_m{div,mod,...} routines.
22 ** This bug has been fixed in a later release of
25 ** MPZ_GET_STR_BUG mpz_get_str corrupts memory, seems to be fixed
28 ** MPZ_DEBUG generates a bunch of diagnostic messages
30 ** MPZ_SPARE_MALLOC if set, results in extra code that tries to
31 ** minimize the creation of extra objects.
33 ** MPZ_TEST_DIV extra diagnostic output on stderr, when division
34 ** routines are involved
36 ** MPZ_LIB_DOES_CHECKING if set, assumes that mpz library doesn't call
37 ** alloca with arg < 0 (when casted to a signed
40 ** MPZ_CONVERSIONS_AS_METHODS if set, presents the conversions as
41 ** methods. e.g., `mpz(5).long() == 5L'
42 ** Later, Guido provided an interface to the
43 ** standard functions. So this flag has no been
44 ** cleared, and `long(mpz(5)) == 5L'
46 ** MP_TEST_ALLOC If set, you would discover why MPZ_GET_STR_BUG
49 ** MAKEDUMMYINT Must be set if dynamic linking will be used
54 ** IMHO, mpz_m{div,mod,divmod}() do the wrong things when the denominator < 0
55 ** This has been fixed with gmp release 2.0
57 /*#define MPZ_MDIV_BUG fixed the (for me) nexessary parts in libgmp.a */
59 ** IMO, mpz_get_str() assumes a bit too large target space, if he doesn't
60 ** allocate it himself
65 #if __GNU_MP__ + 0 >= 2
67 #define BITS_PER_MP_LIMB mp_bits_per_limb
69 #define MPZ_GET_STR_BUG
70 #include "gmp-mparam.h"
75 MP_INT mpz
; /* the actual number */
78 static PyTypeObject MPZtype
;
80 #define is_mpzobject(v) ((v)->ob_type == &MPZtype)
82 static const char initialiser_name
[] = "mpz";
84 /* #define MPZ_DEBUG */
93 fputs( "mpz_object() called...\n", stderr
);
94 #endif /* def MPZ_DEBUG */
95 mpzp
= PyObject_New(mpzobject
, &MPZtype
);
99 mpz_init(&mpzp
->mpz
); /* actual initialisation */
101 } /* newmpzobject() */
103 #ifdef MPZ_GET_STR_BUG
104 #include "longlong.h"
105 #endif /* def MPZ_GET_STR_BUG */
108 mpz_format(PyObject
*objp
, int base
, unsigned char withname
)
110 mpzobject
*mpzp
= (mpzobject
*)objp
;
111 PyStringObject
*strobjp
;
116 char prefix
[5], *tcp
;
121 if (mpzp
== NULL
|| !is_mpzobject(mpzp
)) {
122 PyErr_BadInternalCall();
126 assert(base
>= 2 && base
<= 36);
129 i
= strlen(initialiser_name
) + 2; /* e.g. 'mpz(' + ')' */
133 if ((cmpres
= mpz_cmp_si(&mpzp
->mpz
, 0L)) == 0)
134 base
= 10; /* '0' in every base, right */
135 else if (cmpres
< 0) {
137 i
+= 1; /* space to hold '-' */
141 fprintf(stderr
, "mpz_format: mpz_sizeinbase %d\n",
142 (int)mpz_sizeinbase(&mpzp
->mpz
, base
));
143 #endif /* def MPZ_DEBUG */
144 #ifdef MPZ_GET_STR_BUG
146 i
+= ((size_t) abs(mpzp
->mpz
._mp_size
) * BITS_PER_MP_LIMB
147 * __mp_bases
[base
].chars_per_bit_exactly
) + 1;
149 i
+= ((size_t) abs(mpzp
->mpz
.size
) * BITS_PER_MP_LIMB
150 * __mp_bases
[base
].chars_per_bit_exactly
) + 1;
152 #else /* def MPZ_GET_STR_BUG */
153 i
+= (int)mpz_sizeinbase(&mpzp
->mpz
, base
);
154 #endif /* def MPZ_GET_STR_BUG else */
159 i
+= 2; /* space to hold '0x' */
161 else if (base
== 8) {
163 i
+= 1; /* space to hold the extra '0' */
165 else if (base
> 10) {
166 *tcp
++ = '0' + base
/ 10;
167 *tcp
++ = '0' + base
% 10;
169 i
+= 3; /* space to hold e.g. '12#' */
171 else if (base
< 10) {
174 i
+= 2; /* space to hold e.g. '6#' */
178 ** the following code looks if we need a 'L' attached to the number
179 ** it will also attach an 'L' to the value -0x80000000
182 if (mpz_size(&mpzp
->mpz
) > 1
183 || (long)mpz_get_ui(&mpzp
->mpz
) < 0L) {
185 i
+= 1; /* space to hold 'L' */
189 fprintf(stderr
, "mpz_format: requesting string size %d\n", i
);
190 #endif /* def MPZ_DEBUG */
192 (PyStringObject
*)PyString_FromStringAndSize((char *)0, i
))
196 /* get the beginning of the string memory and start copying things */
197 cp
= PyString_AS_STRING(strobjp
);
199 strcpy(cp
, initialiser_name
);
200 cp
+= strlen(initialiser_name
);
204 /* copy the already prepared prefix; e.g. sign and base indicator */
209 /* since' we have the sign already, let the lib think it's a positive
212 mpz_neg(&mpzp
->mpz
,&mpzp
->mpz
); /* hack Hack HAck HACk HACK */
213 (void)mpz_get_str(cp
, base
, &mpzp
->mpz
);
215 mpz_neg(&mpzp
->mpz
,&mpzp
->mpz
); /* hack Hack HAck HACk HACK */
217 fprintf(stderr
, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
219 #endif /* def MPZ_DEBUG */
231 "mpz_format: cp (str end) %p, begin %p, diff %d, i %d\n",
232 cp
, PyString_AS_STRING(strobjp
),
233 cp
- PyString_AS_STRING(strobjp
), i
);
234 #endif /* def MPZ_DEBUG */
235 assert(cp
- PyString_AS_STRING(strobjp
) <= i
);
237 if (cp
- PyString_AS_STRING(strobjp
) != i
) {
238 strobjp
->ob_size
-= i
- (cp
- PyString_AS_STRING(strobjp
));
241 return (PyObject
*)strobjp
;
247 mpz_dealloc(mpzobject
*mpzp
)
250 fputs( "mpz_dealloc() called...\n", stderr
);
251 #endif /* def MPZ_DEBUG */
252 mpz_clear(&mpzp
->mpz
);
254 } /* mpz_dealloc() */
257 /* pointers to frequently used values 0, 1 and -1 */
258 static mpzobject
*mpz_value_zero
, *mpz_value_one
, *mpz_value_mone
;
261 mpz_compare(mpzobject
*a
, mpzobject
*b
)
266 /* guido sez it's better to return -1, 0 or 1 */
267 return (cmpres
= mpz_cmp( &a
->mpz
, &b
->mpz
)) == 0 ? 0
268 : cmpres
> 0 ? 1 : -1;
269 } /* mpz_compare() */
272 mpz_addition(mpzobject
*a
, mpzobject
*b
)
277 #ifdef MPZ_SPARE_MALLOC
278 if (mpz_cmp_ui(&a
->mpz
, (unsigned long int)0) == 0) {
280 return (PyObject
*)b
;
283 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) == 0) {
285 return (PyObject
*)a
;
287 #endif /* def MPZ_SPARE_MALLOC */
289 if ((z
= newmpzobject()) == NULL
)
292 mpz_add(&z
->mpz
, &a
->mpz
, &b
->mpz
);
293 return (PyObject
*)z
;
294 } /* mpz_addition() */
297 mpz_substract(mpzobject
*a
, mpzobject
*b
)
302 #ifdef MPZ_SPARE_MALLOC
303 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) == 0) {
305 return (PyObject
*)a
;
307 #endif /* MPZ_SPARE_MALLOC */
309 if ((z
= newmpzobject()) == NULL
)
312 mpz_sub(&z
->mpz
, &a
->mpz
, &b
->mpz
);
313 return (PyObject
*)z
;
314 } /* mpz_substract() */
317 mpz_multiply(mpzobject
*a
, mpzobject
*b
)
319 #ifdef MPZ_SPARE_MALLOC
321 #endif /* def MPZ_SPARE_MALLOC */
325 #ifdef MPZ_SPARE_MALLOC
326 if ((cmpres
= mpz_cmp_ui(&a
->mpz
, (unsigned long int)0)) == 0) {
327 Py_INCREF(mpz_value_zero
);
328 return (PyObject
*)mpz_value_zero
;
330 if (cmpres
> 0 && mpz_cmp_ui(&a
->mpz
, (unsigned long int)1) == 0) {
332 return (PyObject
*)b
;
335 if ((cmpres
= mpz_cmp_ui(&b
->mpz
, (unsigned long_int
)0)) == 0) {
336 Py_INCREF(mpz_value_zero
);
337 return (PyObject
*)mpz_value_zero
;
339 if (cmpres
> 0 && mpz_cmp_ui(&b
->mpz
, (unsigned long int)1) == 0) {
341 return (PyObject
*)a
;
343 #endif /* MPZ_SPARE_MALLOC */
345 if ((z
= newmpzobject()) == NULL
)
348 mpz_mul( &z
->mpz
, &a
->mpz
, &b
->mpz
);
349 return (PyObject
*)z
;
351 } /* mpz_multiply() */
354 mpz_divide(mpzobject
*a
, mpzobject
*b
)
356 #ifdef MPZ_SPARE_MALLOC
358 #endif /* def MPZ_SPARE_MALLOC */
363 #ifdef MPZ_SPARE_MALLOC
365 #endif /* def MPZ_SPARE_MALLOC */
366 mpz_cmp_ui(&b
->mpz
, (unsigned long int)0)) == 0) {
367 PyErr_SetString(PyExc_ZeroDivisionError
, "mpz./ by zero");
370 #ifdef MPZ_SPARE_MALLOC
371 if (cmpres
> 0 && mpz_cmp_ui(&b
->mpz(unsigned long int)1) == 0) {
373 return (PyObject
*)a
;
375 #endif /* def MPZ_SPARE_MALLOC */
377 if ((z
= newmpzobject()) == NULL
)
381 fputs("mpz_divide: div result", stderr
);
382 mpz_div(&z
->mpz
, &a
->mpz
, &b
->mpz
);
383 mpz_out_str(stderr
, 10, &z
->mpz
);
385 #endif /* def MPZ_TEST_DIV */
387 if ((mpz_cmp_ui(&a
->mpz
, (unsigned long int)0) < 0)
388 != (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) < 0)) {
390 ** numerator has other sign than denominator: we have
391 ** to look at the remainder for a correction, since mpz_mdiv
392 ** also calls mpz_divmod, I can as well do it myself
398 mpz_divmod(&z
->mpz
, &tmpmpz
, &a
->mpz
, &b
->mpz
);
400 if (mpz_cmp_ui(&tmpmpz
, (unsigned long int)0) != 0)
401 mpz_sub_ui(&z
->mpz
, &z
->mpz
, (unsigned long int)1);
406 mpz_div(&z
->mpz
, &a
->mpz
, &b
->mpz
);
407 /* the ``naive'' implementation does it right for operands
408 having the same sign */
410 #else /* def MPZ_MDIV_BUG */
411 mpz_mdiv(&z
->mpz
, &a
->mpz
, &b
->mpz
);
412 #endif /* def MPZ_MDIV_BUG else */
414 fputs("mpz_divide: mdiv result", stderr
);
415 mpz_out_str(stderr
, 10, &z
->mpz
);
417 #endif /* def MPZ_TEST_DIV */
418 return (PyObject
*)z
;
423 mpz_remainder(mpzobject
*a
, mpzobject
*b
)
425 #ifdef MPZ_SPARE_MALLOC
427 #endif /* def MPZ_SPARE_MALLOC */
432 #ifdef MPZ_SPARE_MALLOC
434 #endif /* def MPZ_SPARE_MALLOC */
435 mpz_cmp_ui(&b
->mpz
, (unsigned long int)0)) == 0) {
436 PyErr_SetString(PyExc_ZeroDivisionError
, "mpz.% by zero");
439 #ifdef MPZ_SPARE_MALLOC
441 if ((cmpres
= mpz_cmp_ui(&b
->mpz
, (unsigned long int)2)) == 0)
443 Py_INCREF(mpz_value_one
);
444 return (PyObject
*)mpz_value_one
;
447 /* b must be 1 now */
448 Py_INCREF(mpz_value_zero
);
449 return (PyObject
*)mpz_value_zero
;
452 #endif /* def MPZ_SPARE_MALLOC */
454 if ((z
= newmpzobject()) == NULL
)
458 fputs("mpz_remain: mod result", stderr
);
459 mpz_mod(&z
->mpz
, &a
->mpz
, &b
->mpz
);
460 mpz_out_str(stderr
, 10, &z
->mpz
);
462 #endif /* def MPZ_TEST_DIV */
465 /* the ``naive'' implementation does it right for operands
466 having the same sign */
467 mpz_mod(&z
->mpz
, &a
->mpz
, &b
->mpz
);
469 /* assumption: z, a and b all point to different locations */
470 if ((mpz_cmp_ui(&a
->mpz
, (unsigned long int)0) < 0)
471 != (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) < 0)
472 && mpz_cmp_ui(&z
->mpz
, (unsigned long int)0) != 0)
473 mpz_add(&z
->mpz
, &z
->mpz
, &b
->mpz
);
475 ** numerator has other sign than denominator: we have
476 ** to look at the remainder for a correction, since mpz_mdiv
477 ** also calls mpz_divmod, I can as well do it myself
479 #else /* def MPZ_MDIV_BUG */
480 mpz_mmod(&z
->mpz
, &a
->mpz
, &b
->mpz
);
481 #endif /* def MPZ_MDIV_BUG else */
483 fputs("mpz_remain: mmod result", stderr
);
484 mpz_out_str(stderr
, 10, &z
->mpz
);
486 #endif /* def MPZ_TEST_DIV */
487 return (PyObject
*)z
;
489 } /* mpz_remainder() */
492 mpz_div_and_mod(mpzobject
*a
, mpzobject
*b
)
495 mpzobject
*x
= NULL
, *y
= NULL
;
498 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) == 0) {
499 PyErr_SetString(PyExc_ZeroDivisionError
, "mpz.divmod by zero");
503 if ((z
= PyTuple_New(2)) == NULL
504 || (x
= newmpzobject()) == NULL
505 || (y
= newmpzobject()) == NULL
) {
513 fputs("mpz_divmod: dm result", stderr
);
514 mpz_divmod(&x
->mpz
, &y
->mpz
, &a
->mpz
, &b
->mpz
);
515 mpz_out_str(stderr
, 10, &x
->mpz
);
517 mpz_out_str(stderr
, 10, &y
->mpz
);
519 #endif /* def MPZ_TEST_DIV */
521 mpz_divmod(&x
->mpz
, &y
->mpz
, &a
->mpz
, &b
->mpz
);
522 if ((mpz_cmp_ui(&a
->mpz
, (unsigned long int)0) < 0)
523 != (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) < 0)
524 && mpz_cmp_ui(&y
->mpz
, (unsigned long int)0) != 0) {
526 ** numerator has other sign than denominator: we have
527 ** to look at the remainder for a correction.
529 mpz_add(&y
->mpz
, &y
->mpz
, &b
->mpz
);
530 mpz_sub_ui(&x
->mpz
, &x
->mpz
, (unsigned long int)1);
532 #else /* def MPZ_MDIV_BUG */
533 mpz_mdivmod( &x
->mpz
, &y
->mpz
, &a
->mpz
, &b
->mpz
);
534 #endif /* def MPZ_MDIV_BUG else */
536 fputs("mpz_divmod: mdm result", stderr
);
537 mpz_out_str(stderr
, 10, &x
->mpz
);
539 mpz_out_str(stderr
, 10, &y
->mpz
);
541 #endif /* def MPZ_TEST_DIV */
543 (void)PyTuple_SetItem(z
, 0, (PyObject
*)x
);
544 (void)PyTuple_SetItem(z
, 1, (PyObject
*)y
);
547 } /* mpz_div_and_mod() */
550 mpz_power(mpzobject
*a
, mpzobject
*b
, mpzobject
*m
)
555 if ((PyObject
*)m
!= Py_None
) {
558 z
=(mpzobject
*)mpz_power(a
, b
, (mpzobject
*)Py_None
);
560 if (z
==NULL
) return((PyObject
*)z
);
561 z2
=(mpzobject
*)mpz_remainder(z
, m
);
563 return((PyObject
*)z2
);
566 if ((cmpres
= mpz_cmp_ui(&b
->mpz
, (unsigned long int)0)) == 0) {
567 /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
569 Py_INCREF(mpz_value_one
);
570 return (PyObject
*)mpz_value_one
;
574 PyErr_SetString(PyExc_ValueError
,
575 "mpz.pow to negative exponent");
579 if ((cmpres
= mpz_cmp_ui(&a
->mpz
, (unsigned long int)0)) == 0) {
582 Py_INCREF(mpz_value_zero
);
583 return (PyObject
*)mpz_value_zero
;
586 && mpz_cmp_ui(&a
->mpz
, (unsigned long int)1) == 0) {
589 Py_INCREF(mpz_value_one
);
590 return (PyObject
*)mpz_value_one
;
593 && mpz_cmp_si(&a
->mpz
, (long int)-1) == 0) {
596 /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
597 /* XXX this code needs to be optimized: what's better?
598 mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
599 for *un*obvious reasons */
601 /* is the exponent even? */
604 /* look to the remainder after a division by (1 << 1) */
605 mpz_mod_2exp(&tmpmpz
, &b
->mpz
, (unsigned long int)1);
607 if (mpz_cmp_ui(&tmpmpz
, (unsigned int)0) == 0) {
609 Py_INCREF(mpz_value_one
);
610 return (PyObject
*)mpz_value_one
;
613 Py_INCREF(mpz_value_mone
);
614 return (PyObject
*)mpz_value_mone
;
617 #ifdef MPZ_LIB_DOES_CHECKING
618 /* check if it's doable: sizeof(exp) > sizeof(long) &&
619 abs(base) > 1 ?? --> No Way */
620 if (mpz_size(&b
->mpz
) > 1)
621 return (PyObject
*)PyErr_NoMemory();
622 #else /* def MPZ_LIB_DOES_CHECKING */
623 /* wet finger method */
624 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0x10000) >= 0) {
625 PyErr_SetString(PyExc_ValueError
,
626 "mpz.pow outrageous exponent");
629 #endif /* def MPZ_LIB_DOES_CHECKING else */
631 if ((z
= newmpzobject()) == NULL
)
634 mpz_pow_ui(&z
->mpz
, &a
->mpz
, mpz_get_ui(&b
->mpz
));
636 return (PyObject
*)z
;
641 mpz_negative(mpzobject
*v
)
646 #ifdef MPZ_SPARE_MALLOC
647 if (mpz_cmp_ui(&v
->mpz
, (unsigned long int)0) == 0) {
650 return (PyObject
*)v
;
652 #endif /* def MPZ_SPARE_MALLOC */
654 if ((z
= newmpzobject()) == NULL
)
657 mpz_neg(&z
->mpz
, &v
->mpz
);
658 return (PyObject
*)z
;
659 } /* mpz_negative() */
663 mpz_positive(mpzobject
*v
)
666 return (PyObject
*)v
;
667 } /* mpz_positive() */
671 mpz_absolute(mpzobject
*v
)
676 if (mpz_cmp_ui(&v
->mpz
, (unsigned long int)0) >= 0) {
678 return (PyObject
*)v
;
681 if ((z
= newmpzobject()) == NULL
)
684 mpz_neg(&z
->mpz
, &v
->mpz
);
685 return (PyObject
*)z
;
686 } /* mpz_absolute() */
689 mpz_nonzero(mpzobject
*v
)
691 return mpz_cmp_ui(&v
->mpz
, (unsigned long int)0) != 0;
692 } /* mpz_nonzero() */
695 py_mpz_invert(mpzobject
*v
)
700 /* I think mpz_com does exactly what needed */
701 if ((z
= newmpzobject()) == NULL
)
704 mpz_com(&z
->mpz
, &v
->mpz
);
705 return (PyObject
*)z
;
706 } /* py_mpz_invert() */
709 mpz_lshift(mpzobject
*a
, mpzobject
*b
)
715 if ((cmpres
= mpz_cmp_ui(&b
->mpz
, (unsigned long int)0)) == 0) {
718 return (PyObject
*)a
;
722 PyErr_SetString(PyExc_ValueError
,
723 "mpz.<< negative shift count");
727 #ifdef MPZ_LIB_DOES_CHECKING
728 if (mpz_size(&b
->mpz
) > 1)
729 return (PyObject
*)PyErr_NoMemory();
730 #else /* def MPZ_LIB_DOES_CHECKING */
731 /* wet finger method */
732 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0x10000) >= 0) {
733 PyErr_SetString(PyExc_ValueError
,
734 "mpz.<< outrageous shift count");
737 #endif /* def MPZ_LIB_DOES_CHECKING else */
739 if ((z
= newmpzobject()) == NULL
)
742 mpz_mul_2exp(&z
->mpz
, &a
->mpz
, mpz_get_ui(&b
->mpz
));
743 return (PyObject
*)z
;
747 mpz_rshift(mpzobject
*a
, mpzobject
*b
)
753 if ((cmpres
= mpz_cmp_ui(&b
->mpz
, (unsigned long int)0)) == 0) {
756 return (PyObject
*)a
;
760 PyErr_SetString(PyExc_ValueError
,
761 "mpz.>> negative shift count");
765 if (mpz_size(&b
->mpz
) > 1)
766 return (PyObject
*)PyErr_NoMemory();
768 if ((z
= newmpzobject()) == NULL
)
771 mpz_div_2exp(&z
->mpz
, &a
->mpz
, mpz_get_ui(&b
->mpz
));
772 return (PyObject
*)z
;
776 mpz_andfunc(mpzobject
*a
, mpzobject
*b
)
781 if ((z
= newmpzobject()) == NULL
)
784 mpz_and(&z
->mpz
, &a
->mpz
, &b
->mpz
);
785 return (PyObject
*)z
;
786 } /* mpz_andfunc() */
788 /* hack Hack HAck HACk HACK, XXX this code is dead slow */
790 mpz_xor(MP_INT
*res
, const MP_INT
*op1
, const MP_INT
*op2
)
796 mpz_and(res
, op1
, op2
);
797 mpz_com(&tmpmpz
, res
);
798 mpz_ior(res
, op1
, op2
);
799 mpz_and(res
, res
, &tmpmpz
);
802 } /* mpz_xor() HACK */
805 mpz_xorfunc(mpzobject
*a
, mpzobject
*b
)
810 if ((z
= newmpzobject()) == NULL
)
813 mpz_xor(&z
->mpz
, &a
->mpz
, &b
->mpz
);
814 return (PyObject
*)z
;
815 } /* mpz_xorfunc() */
818 mpz_orfunc(mpzobject
*a
, mpzobject
*b
)
823 if ((z
= newmpzobject()) == NULL
)
826 mpz_ior(&z
->mpz
, &a
->mpz
, &b
->mpz
);
827 return (PyObject
*)z
;
830 /* MPZ initialisation */
832 #include "longintrepr.h"
835 MPZ_mpz(PyObject
*self
, PyObject
*args
)
841 fputs("MPZ_mpz() called...\n", stderr
);
842 #endif /* def MPZ_DEBUG */
844 /* at least we know it's some object */
845 /* note DON't Py_DECREF args */
847 if (PyInt_Check(args
)) {
848 long lval
= PyInt_AS_LONG(args
);
849 if (lval
== (long)0) {
850 Py_INCREF(mpz_value_zero
);
851 mpzp
= mpz_value_zero
;
853 else if (lval
== (long)1) {
854 Py_INCREF(mpz_value_one
);
855 mpzp
= mpz_value_one
;
857 else if ((mpzp
= newmpzobject()) == NULL
)
859 else mpz_set_si(&mpzp
->mpz
, lval
);
861 else if (PyLong_Check(args
)) {
864 unsigned char isnegative
;
867 if ((mpzp
= newmpzobject()) == NULL
)
870 mpz_set_si(&mpzp
->mpz
, 0L);
871 mpz_init(&mplongdigit
);
873 /* how we're gonna handle this? */
875 ((i
= ((PyLongObject
*)args
)->ob_size
) < 0) ))
879 mpz_set_ui(&mplongdigit
,
881 ((PyLongObject
*)args
)->ob_digit
[i
]);
882 mpz_mul_2exp(&mplongdigit
,&mplongdigit
,
883 (unsigned long int)i
* SHIFT
);
884 mpz_ior(&mpzp
->mpz
, &mpzp
->mpz
, &mplongdigit
);
888 mpz_neg(&mpzp
->mpz
, &mpzp
->mpz
);
890 /* get rid of allocation for tmp variable */
891 mpz_clear(&mplongdigit
);
893 else if (PyString_Check(args
)) {
894 unsigned char *cp
= (unsigned char *)PyString_AS_STRING(args
);
895 int len
= PyString_GET_SIZE(args
);
898 if ((mpzp
= newmpzobject()) == NULL
)
901 mpz_set_si(&mpzp
->mpz
, 0L);
902 mpz_init(&mplongdigit
);
904 /* let's do it the same way as with the long conversion:
905 without thinking how it can be faster (-: :-) */
909 mpz_set_ui(&mplongdigit
, (unsigned long)*--cp
);
910 mpz_mul_2exp(&mplongdigit
,&mplongdigit
,
911 (unsigned long int)len
* 8);
912 mpz_ior(&mpzp
->mpz
, &mpzp
->mpz
, &mplongdigit
);
915 /* get rid of allocation for tmp variable */
916 mpz_clear(&mplongdigit
);
918 else if (is_mpzobject(args
)) {
920 mpzp
= (mpzobject
*)args
;
923 PyErr_SetString(PyExc_TypeError
,
924 "mpz.mpz() expects integer, long, string or mpz object argument");
930 fputs("MPZ_mpz: created mpz=", stderr
);
931 mpz_out_str(stderr
, 10, &mpzp
->mpz
);
933 #endif /* def MPZ_DEBUG */
934 return (PyObject
*)mpzp
;
938 mpz_mpzcoerce(PyObject
*z
)
940 /* shortcut: 9 out of 10 times the type is already ok */
941 if (is_mpzobject(z
)) {
943 return (mpzobject
*)z
; /* coercion succeeded */
946 /* what types do we accept?: intobjects and longobjects */
947 if (PyInt_Check(z
) || PyLong_Check(z
))
948 return (mpzobject
*)MPZ_mpz((PyObject
*)NULL
, z
);
950 PyErr_SetString(PyExc_TypeError
,
951 "number coercion (to mpzobject) failed");
953 } /* mpz_mpzcoerce() */
956 static void mpz_divm(MP_INT
*res
, const MP_INT
*num
,
957 const MP_INT
*den
, const MP_INT
*mod
);
960 MPZ_powm(PyObject
*self
, PyObject
*args
)
962 PyObject
*base
, *exp
, *mod
;
963 mpzobject
*mpzbase
= NULL
, *mpzexp
= NULL
, *mpzmod
= NULL
;
968 if (!PyArg_ParseTuple(args
, "OOO", &base
, &exp
, &mod
))
971 if ((mpzbase
= mpz_mpzcoerce(base
)) == NULL
972 || (mpzexp
= mpz_mpzcoerce(exp
)) == NULL
973 || (mpzmod
= mpz_mpzcoerce(mod
)) == NULL
974 || (z
= newmpzobject()) == NULL
) {
982 if ((tstres
=mpz_cmp_ui(&mpzexp
->mpz
, (unsigned long int)0)) == 0) {
987 Py_INCREF(mpz_value_one
);
988 return (PyObject
*)mpz_value_one
;
991 if (mpz_cmp_ui(&mpzmod
->mpz
, 0) == 0) {
996 PyErr_SetString(PyExc_ValueError
, "modulus cannot be 0");
1004 mpz_init_set(&absexp
, &mpzexp
->mpz
);
1005 mpz_abs(&absexp
, &absexp
);
1006 mpz_powm(&z
->mpz
, &mpzbase
->mpz
, &absexp
, &mpzmod
->mpz
);
1008 mpz_divm(&z
->mpz
, &mpz_value_one
->mpz
, &z
->mpz
, &mpzmod
->mpz
);
1013 mpz_powm(&z
->mpz
, &mpzbase
->mpz
, &mpzexp
->mpz
, &mpzmod
->mpz
);
1020 return (PyObject
*)z
;
1025 MPZ_gcd(PyObject
*self
, PyObject
*args
)
1027 PyObject
*op1
, *op2
;
1028 mpzobject
*mpzop1
= NULL
, *mpzop2
= NULL
;
1032 if (!PyArg_ParseTuple(args
, "OO", &op1
, &op2
))
1035 if ((mpzop1
= mpz_mpzcoerce(op1
)) == NULL
1036 || (mpzop2
= mpz_mpzcoerce(op2
)) == NULL
1037 || (z
= newmpzobject()) == NULL
) {
1043 /* ok, we have three mpzobjects, and an initialised result holder */
1044 mpz_gcd(&z
->mpz
, &mpzop1
->mpz
, &mpzop2
->mpz
);
1049 return (PyObject
*)z
;
1054 MPZ_gcdext(PyObject
*self
, PyObject
*args
)
1056 PyObject
*op1
, *op2
, *z
= NULL
;
1057 mpzobject
*mpzop1
= NULL
, *mpzop2
= NULL
;
1058 mpzobject
*g
= NULL
, *s
= NULL
, *t
= NULL
;
1061 if (!PyArg_ParseTuple(args
, "OO", &op1
, &op2
))
1064 if ((mpzop1
= mpz_mpzcoerce(op1
)) == NULL
1065 || (mpzop2
= mpz_mpzcoerce(op2
)) == NULL
1066 || (z
= PyTuple_New(3)) == NULL
1067 || (g
= newmpzobject()) == NULL
1068 || (s
= newmpzobject()) == NULL
1069 || (t
= newmpzobject()) == NULL
) {
1079 mpz_gcdext(&g
->mpz
, &s
->mpz
, &t
->mpz
, &mpzop1
->mpz
, &mpzop2
->mpz
);
1084 (void)PyTuple_SetItem(z
, 0, (PyObject
*)g
);
1085 (void)PyTuple_SetItem(z
, 1, (PyObject
*)s
);
1086 (void)PyTuple_SetItem(z
, 2, (PyObject
*)t
);
1088 return (PyObject
*)z
;
1089 } /* MPZ_gcdext() */
1093 MPZ_sqrt(PyObject
*self
, PyObject
*args
)
1095 mpzobject
*mpzop
= NULL
;
1099 if ((mpzop
= mpz_mpzcoerce(args
)) == NULL
1100 || (z
= newmpzobject()) == NULL
) {
1105 mpz_sqrt(&z
->mpz
, &mpzop
->mpz
);
1109 return (PyObject
*)z
;
1114 MPZ_sqrtrem(PyObject
*self
, PyObject
*args
)
1117 mpzobject
*mpzop
= NULL
;
1118 mpzobject
*root
= NULL
, *rem
= NULL
;
1120 if ((mpzop
= mpz_mpzcoerce(args
)) == NULL
1121 || (z
= PyTuple_New(2)) == NULL
1122 || (root
= newmpzobject()) == NULL
1123 || (rem
= newmpzobject()) == NULL
) {
1127 /*Py_XDECREF(rem);*/
1131 mpz_sqrtrem(&root
->mpz
, &rem
->mpz
, &mpzop
->mpz
);
1135 (void)PyTuple_SetItem(z
, 0, (PyObject
*)root
);
1136 (void)PyTuple_SetItem(z
, 1, (PyObject
*)rem
);
1138 return (PyObject
*)z
;
1139 } /* MPZ_sqrtrem() */
1143 mpz_divm(MP_INT
*res
, const MP_INT
*num
, const MP_INT
*den
, const MP_INT
*mod
)
1145 MP_INT s0
, s1
, q
, r
, x
, d0
, d1
;
1147 mpz_init_set(&s0
, num
);
1148 mpz_init_set_ui(&s1
, 0);
1152 mpz_init_set(&d0
, den
);
1153 mpz_init_set(&d1
, mod
);
1156 while (d1
._mp_size
!= 0) {
1158 while (d1
.size
!= 0) {
1160 mpz_divmod(&q
, &r
, &d0
, &d1
);
1164 mpz_mul(&x
, &s1
, &q
);
1165 mpz_sub(&x
, &s0
, &x
);
1171 if (d0
._mp_size
!= 1 || d0
._mp_d
[0] != 1)
1172 res
->_mp_size
= 0; /* trouble: the gcd != 1; set s to zero */
1174 if (d0
.size
!= 1 || d0
.d
[0] != 1)
1175 res
->size
= 0; /* trouble: the gcd != 1; set s to zero */
1179 /* watch out here! first check the signs, and then perform
1180 the mpz_mod() since mod could point to res */
1181 if ((s0
.size
< 0) != (mod
->size
< 0)) {
1182 mpz_mod(res
, &s0
, mod
);
1185 mpz_add(res
, res
, mod
);
1188 mpz_mod(res
, &s0
, mod
);
1190 #else /* def MPZ_MDIV_BUG */
1191 mpz_mmod(res
, &s0
, mod
);
1192 #endif /* def MPZ_MDIV_BUG else */
1206 MPZ_divm(PyObject
*self
, PyObject
*args
)
1208 PyObject
*num
, *den
, *mod
;
1209 mpzobject
*mpznum
, *mpzden
= NULL
, *mpzmod
= NULL
;
1210 mpzobject
*z
= NULL
;
1213 if (!PyArg_ParseTuple(args
, "OOO", &num
, &den
, &mod
))
1216 if ((mpznum
= mpz_mpzcoerce(num
)) == NULL
1217 || (mpzden
= mpz_mpzcoerce(den
)) == NULL
1218 || (mpzmod
= mpz_mpzcoerce(mod
)) == NULL
1219 || (z
= newmpzobject()) == NULL
) {
1226 mpz_divm(&z
->mpz
, &mpznum
->mpz
, &mpzden
->mpz
, &mpzmod
->mpz
);
1232 if (mpz_cmp_ui(&z
->mpz
, (unsigned long int)0) == 0) {
1234 PyErr_SetString(PyExc_ValueError
,
1235 "gcd(den, mod) != 1 or num == 0");
1239 return (PyObject
*)z
;
1244 mpz_int(mpzobject
*self
)
1249 if (mpz_size(&self
->mpz
) > 1
1250 || (sli
= (long)mpz_get_ui(&self
->mpz
)) < (long)0 ) {
1251 PyErr_SetString(PyExc_ValueError
,
1252 "mpz.int() arg too long to convert");
1256 if (mpz_cmp_ui(&self
->mpz
, (unsigned long)0) < 0)
1259 return PyInt_FromLong(sli
);
1263 mpz_long(mpzobject
*self
)
1266 unsigned long int uli
;
1267 PyLongObject
*longobjp
;
1269 int bitpointer
, newbitpointer
;
1273 /* determine length of python-long to be allocated */
1274 if ((longobjp
= _PyLong_New(i
= (int)
1275 ((mpz_size(&self
->mpz
) * BITS_PER_MP_LIMB
1280 /* determine sign, and copy self to scratch var */
1281 mpz_init_set(&mpzscratch
, &self
->mpz
);
1282 if ((isnegative
= (mpz_cmp_ui(&self
->mpz
, (unsigned long int)0) < 0)))
1283 mpz_neg(&mpzscratch
, &mpzscratch
);
1285 /* let those bits come, let those bits go,
1286 e.g. dismantle mpzscratch, build PyLongObject */
1288 bitpointer
= 0; /* the number of valid bits in stock */
1290 ldcount
= 0; /* the python-long limb counter */
1291 uli
= (unsigned long int)0;
1293 longobjp
->ob_digit
[ldcount
] = uli
& MASK
;
1295 /* check if we've had enough bits for this digit */
1296 if (bitpointer
< SHIFT
) {
1297 uli
= mpz_get_ui(&mpzscratch
);
1298 longobjp
->ob_digit
[ldcount
] |=
1299 (uli
<< bitpointer
) & MASK
;
1300 uli
>>= SHIFT
-bitpointer
;
1301 bitpointer
+= BITS_PER_MP_LIMB
;
1302 mpz_div_2exp(&mpzscratch
, &mpzscratch
,
1307 bitpointer
-= SHIFT
;
1311 assert(mpz_cmp_ui(&mpzscratch
, (unsigned long int)0) == 0);
1312 mpz_clear(&mpzscratch
);
1313 assert(ldcount
<= longobjp
->ob_size
);
1315 /* long_normalize() is file-static */
1316 /* longobjp = long_normalize(longobjp); */
1317 while (ldcount
> 0 && longobjp
->ob_digit
[ldcount
-1] == 0)
1319 longobjp
->ob_size
= ldcount
;
1323 longobjp
->ob_size
= -longobjp
->ob_size
;
1325 return (PyObject
*)longobjp
;
1330 /* I would have avoided pow() anyways, so ... */
1331 static const double multiplier
= 256.0 * 256.0 * 256.0 * 256.0;
1334 mpz_float(mpzobject
*self
)
1342 i
= (int)mpz_size(&self
->mpz
);
1344 /* determine sign, and copy abs(self) to scratch var */
1345 if ((isnegative
= (mpz_cmp_ui(&self
->mpz
, (unsigned long int)0) < 0)))
1347 mpz_init(&mpzscratch
);
1348 mpz_neg(&mpzscratch
, &self
->mpz
);
1351 mpz_init_set(&mpzscratch
, &self
->mpz
);
1353 /* let those bits come, let those bits go,
1354 e.g. dismantle mpzscratch, build PyFloatObject */
1356 /* Can this overflow? Dunno, protect against that possibility. */
1357 PyFPE_START_PROTECT("mpz_float", return 0)
1361 x
+= mulstate
* mpz_get_ui(&mpzscratch
);
1362 mulstate
*= multiplier
;
1363 mpz_div_2exp(&mpzscratch
, &mpzscratch
, BITS_PER_MP_LIMB
);
1365 PyFPE_END_PROTECT(mulstate
)
1367 assert(mpz_cmp_ui(&mpzscratch
, (unsigned long int)0) == 0);
1368 mpz_clear(&mpzscratch
);
1373 return PyFloat_FromDouble(x
);
1378 mpz_hex(mpzobject
*self
)
1380 return mpz_format((PyObject
*)self
, 16, (unsigned char)1);
1384 mpz_oct(mpzobject
*self
)
1386 return mpz_format((PyObject
*)self
, 8, (unsigned char)1);
1390 mpz_binary(mpzobject
*self
)
1393 PyStringObject
*strobjp
;
1396 unsigned long ldigit
;
1398 if (mpz_cmp_ui(&self
->mpz
, (unsigned long int)0) < 0) {
1399 PyErr_SetString(PyExc_ValueError
,
1400 "mpz.binary() arg must be >= 0");
1404 mpz_init_set(&mp
, &self
->mpz
);
1405 size
= (int)mpz_size(&mp
);
1407 if ((strobjp
= (PyStringObject
*)
1408 PyString_FromStringAndSize(
1409 (char *)0, size
* sizeof (unsigned long int))) == NULL
)
1412 /* get the beginning of the string memory and start copying things */
1413 cp
= PyString_AS_STRING(strobjp
);
1415 /* this has been programmed using a (fairly) decent lib-i/f it could
1416 be must faster if we looked into the GMP lib */
1418 ldigit
= mpz_get_ui(&mp
);
1419 mpz_div_2exp(&mp
, &mp
, BITS_PER_MP_LIMB
);
1420 *cp
++ = (unsigned char)(ldigit
& 0xFF);
1421 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1422 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1423 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1424 if (sizeof(ldigit
) == 8 && BITS_PER_MP_LIMB
== 64) {
1425 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1426 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1427 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1428 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1432 while (strobjp
->ob_size
&& !*--cp
)
1435 return (PyObject
*)strobjp
;
1436 } /* mpz_binary() */
1439 static PyMethodDef mpz_methods
[] = {
1440 #ifdef MPZ_CONVERSIONS_AS_METHODS
1441 {"int", mpz_int
, METH_NOARGS
},
1442 {"long", mpz_long
, METH_NOARGS
},
1443 {"float", mpz_float
, METH_NOARGS
},
1444 {"hex", mpz_hex
, METH_NOARGS
},
1445 {"oct", mpz_oct
, METH_NOARGS
},
1446 #endif /* def MPZ_CONVERSIONS_AS_METHODS */
1447 {"binary", (PyCFunction
)mpz_binary
, METH_NOARGS
},
1448 {NULL
, NULL
} /* sentinel */
1452 mpz_getattr(mpzobject
*self
, char *name
)
1454 return Py_FindMethod(mpz_methods
, (PyObject
*)self
, name
);
1455 } /* mpz_getattr() */
1459 mpz_coerce(PyObject
**pv
, PyObject
**pw
)
1464 fputs("mpz_coerce() called...\n", stderr
);
1465 #endif /* def MPZ_DEBUG */
1467 assert(is_mpzobject(*pv
));
1469 /* always convert other arg to mpz value, except for floats */
1470 if (!PyFloat_Check(*pw
)) {
1471 if ((z
= (PyObject
*)mpz_mpzcoerce(*pw
)) == NULL
)
1472 return -1; /* -1: an error always has been set */
1478 if ((z
= mpz_float((mpzobject
*)(*pv
))) == NULL
)
1484 return 0; /* coercion succeeded */
1486 } /* mpz_coerce() */
1490 mpz_repr(PyObject
*v
)
1492 return mpz_format(v
, 10, (unsigned char)1);
1497 #define UF (unaryfunc)
1498 #define BF (binaryfunc)
1499 #define TF (ternaryfunc)
1500 #define IF (inquiry)
1501 #define CF (coercion)
1503 static PyNumberMethods mpz_as_number
= {
1504 BF mpz_addition
, /*nb_add*/
1505 BF mpz_substract
, /*nb_subtract*/
1506 BF mpz_multiply
, /*nb_multiply*/
1507 BF mpz_divide
, /*nb_divide*/
1508 BF mpz_remainder
, /*nb_remainder*/
1509 BF mpz_div_and_mod
, /*nb_divmod*/
1510 TF mpz_power
, /*nb_power*/
1511 UF mpz_negative
, /*nb_negative*/
1512 UF mpz_positive
, /*tp_positive*/
1513 UF mpz_absolute
, /*tp_absolute*/
1514 IF mpz_nonzero
, /*tp_nonzero*/
1515 UF py_mpz_invert
, /*nb_invert*/
1516 BF mpz_lshift
, /*nb_lshift*/
1517 BF mpz_rshift
, /*nb_rshift*/
1518 BF mpz_andfunc
, /*nb_and*/
1519 BF mpz_xorfunc
, /*nb_xor*/
1520 BF mpz_orfunc
, /*nb_or*/
1521 CF mpz_coerce
, /*nb_coerce*/
1522 #ifndef MPZ_CONVERSIONS_AS_METHODS
1523 UF mpz_int
, /*nb_int*/
1524 UF mpz_long
, /*nb_long*/
1525 UF mpz_float
, /*nb_float*/
1526 UF mpz_oct
, /*nb_oct*/
1527 UF mpz_hex
, /*nb_hex*/
1528 #endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1531 static PyTypeObject MPZtype
= {
1532 PyObject_HEAD_INIT(NULL
)
1534 "mpz.mpz", /*tp_name*/
1535 sizeof(mpzobject
), /*tp_size*/
1538 (destructor
)mpz_dealloc
, /*tp_dealloc*/
1540 (getattrfunc
)mpz_getattr
, /*tp_getattr*/
1542 (cmpfunc
)mpz_compare
, /*tp_compare*/
1543 (reprfunc
)mpz_repr
, /*tp_repr*/
1544 &mpz_as_number
, /*tp_as_number*/
1547 /* List of functions exported by this module */
1549 static PyMethodDef mpz_functions
[] = {
1551 {initialiser_name
, MPZ_mpz
, METH_O
},
1553 /* until guido ``fixes'' struct PyMethodDef */
1554 {(char *)initialiser_name
, MPZ_mpz
, METH_O
},
1556 {"powm", MPZ_powm
, METH_VARARGS
},
1557 {"gcd", MPZ_gcd
, METH_VARARGS
},
1558 {"gcdext", MPZ_gcdext
, METH_VARARGS
},
1559 {"sqrt", MPZ_sqrt
, METH_O
},
1560 {"sqrtrem", MPZ_sqrtrem
, METH_O
},
1561 {"divm", MPZ_divm
, METH_VARARGS
},
1562 {NULL
, NULL
} /* Sentinel */
1566 /* #define MP_TEST_ALLOC */
1568 #ifdef MP_TEST_ALLOC
1569 #define MP_TEST_SIZE 4
1570 static const char mp_test_magic
[MP_TEST_SIZE
] = {'\xAA','\xAA','\xAA','\xAA'};
1571 static mp_test_error(int *location
)
1573 /* assumptions: *alloc returns address divisible by 4,
1574 mpz_* routines allocate in chunks divisible by four */
1575 fprintf(stderr
, "MP_TEST_ERROR: location holds 0x%08d\n", *location
);
1576 Py_FatalError("MP_TEST_ERROR");
1577 } /* static mp_test_error() */
1578 #define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1579 #define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1580 #define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1583 mp_test_error((int *)((char *)(basep) + size))
1584 #else /* def MP_TEST_ALLOC */
1585 #define MP_EXTRA_ALLOC(size) (size)
1586 #define MP_SET_TEST(basep,size)
1587 #define MP_DO_TEST(basep,size)
1588 #endif /* def MP_TEST_ALLOC else */
1590 void *mp_allocate(size_t alloc_size
)
1595 fprintf(stderr
, "mp_allocate : size %ld\n",
1597 #endif /* def MPZ_DEBUG */
1599 if ( (res
= malloc(MP_EXTRA_ALLOC(alloc_size
))) == NULL
)
1600 Py_FatalError("mp_allocate failure");
1603 fprintf(stderr
, "mp_allocate : address %08p\n", res
);
1604 #endif /* def MPZ_DEBUG */
1606 MP_SET_TEST(res
,alloc_size
);
1609 } /* mp_allocate() */
1612 void *mp_reallocate(void *ptr
, size_t old_size
, size_t new_size
)
1617 fprintf(stderr
, "mp_reallocate: old address %08p, old size %ld\n",
1619 #endif /* def MPZ_DEBUG */
1621 MP_DO_TEST(ptr
, old_size
);
1623 if ( (res
= realloc(ptr
, MP_EXTRA_ALLOC(new_size
))) == NULL
)
1624 Py_FatalError("mp_reallocate failure");
1627 fprintf(stderr
, "mp_reallocate: new address %08p, new size %ld\n",
1629 #endif /* def MPZ_DEBUG */
1631 MP_SET_TEST(res
, new_size
);
1634 } /* mp_reallocate() */
1637 void mp_free(void *ptr
, size_t size
)
1641 fprintf(stderr
, "mp_free : old address %08p, old size %ld\n",
1643 #endif /* def MPZ_DEBUG */
1645 MP_DO_TEST(ptr
, size
);
1651 /* Initialize this module. */
1660 fputs( "initmpz() called...\n", stderr
);
1661 #endif /* def MPZ_DEBUG */
1663 mp_set_memory_functions( mp_allocate
, mp_reallocate
, mp_free
);
1664 MPZtype
.ob_type
= &PyType_Type
;
1665 module
= Py_InitModule("mpz", mpz_functions
);
1667 /* create some frequently used constants */
1668 if ((mpz_value_zero
= newmpzobject()) == NULL
)
1670 mpz_set_ui(&mpz_value_zero
->mpz
, (unsigned long int)0);
1672 if ((mpz_value_one
= newmpzobject()) == NULL
)
1674 mpz_set_ui(&mpz_value_one
->mpz
, (unsigned long int)1);
1676 if ((mpz_value_mone
= newmpzobject()) == NULL
)
1678 mpz_set_si(&mpz_value_mone
->mpz
, (long)-1);
1680 dict
= PyModule_GetDict(module
);
1682 PyDict_SetItemString(dict
, "MPZType", (PyObject
*)&MPZtype
);
1689 int _mpz_dummy_int
; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1690 #endif /* def MAKEDUMMYINT */