1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
34 /* This module provides an interface to an alternate Multi-Precision
35 library, GNU MP in this case */
37 /* XXX note: everywhere where mpz_size is called,
38 sizeof (limb) == sizeof (long) has been assumed. */
46 #include <sys/types.h> /* For size_t */
49 ** These are the cpp-flags used in this file...
52 ** MPZ_MDIV_BUG works around the mpz_m{div,mod,...} routines.
53 ** This bug has been fixed in a later release of
56 ** MPZ_GET_STR_BUG mpz_get_str corrupts memory, seems to be fixed
59 ** MPZ_DEBUG generates a bunch of diagnostic messages
61 ** MPZ_SPARE_MALLOC if set, results in extra code that tries to
62 ** minimize the creation of extra objects.
64 ** MPZ_TEST_DIV extra diagnostic output on stderr, when division
65 ** routines are involved
67 ** MPZ_LIB_DOES_CHECKING if set, assumes that mpz library doesn't call
68 ** alloca with arg < 0 (when casted to a signed
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'
77 ** MP_TEST_ALLOC If set, you would discover why MPZ_GET_STR_BUG
80 ** MAKEDUMMYINT Must be set if dynamic linking will be used
85 ** IMHO, mpz_m{div,mod,divmod}() do the wrong things when the denominator < 0
86 ** This has been fixed with gmp release 2.0
88 /*#define MPZ_MDIV_BUG fixed the (for me) nexessary parts in libgmp.a */
90 ** IMO, mpz_get_str() assumes a bit too large target space, if he doesn't
91 ** allocate it himself
95 #include "gmp-mparam.h"
97 #if __GNU_MP__ + 0 == 2
100 #define MPZ_GET_STR_BUG
105 MP_INT mpz
; /* the actual number */
108 staticforward PyTypeObject MPZtype
;
110 #define is_mpzobject(v) ((v)->ob_type == &MPZtype)
112 static const char initialiser_name
[] = "mpz";
114 /* #define MPZ_DEBUG */
123 fputs( "mpz_object() called...\n", stderr
);
124 #endif /* def MPZ_DEBUG */
125 mpzp
= PyObject_NEW(mpzobject
, &MPZtype
);
129 mpz_init(&mpzp
->mpz
); /* actual initialisation */
131 } /* newmpzobject() */
133 #ifdef MPZ_GET_STR_BUG
134 #include "longlong.h"
135 #endif /* def MPZ_GET_STR_BUG */
138 mpz_format(objp
, base
, withname
)
141 unsigned char withname
;
143 mpzobject
*mpzp
= (mpzobject
*)objp
;
144 PyStringObject
*strobjp
;
149 char prefix
[5], *tcp
;
154 if (mpzp
== NULL
|| !is_mpzobject(mpzp
)) {
155 PyErr_BadInternalCall();
159 assert(base
>= 2 && base
<= 36);
162 i
= strlen(initialiser_name
) + 2; /* e.g. 'mpz(' + ')' */
166 if ((cmpres
= mpz_cmp_si(&mpzp
->mpz
, 0L)) == 0)
167 base
= 10; /* '0' in every base, right */
168 else if (cmpres
< 0) {
170 i
+= 1; /* space to hold '-' */
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
179 i
+= ((size_t) abs(mpzp
->mpz
._mp_size
) * BITS_PER_MP_LIMB
180 * __mp_bases
[base
].chars_per_bit_exactly
) + 1;
182 i
+= ((size_t) abs(mpzp
->mpz
.size
) * BITS_PER_MP_LIMB
183 * __mp_bases
[base
].chars_per_bit_exactly
) + 1;
185 #else /* def MPZ_GET_STR_BUG */
186 i
+= (int)mpz_sizeinbase(&mpzp
->mpz
, base
);
187 #endif /* def MPZ_GET_STR_BUG else */
192 i
+= 2; /* space to hold '0x' */
194 else if (base
== 8) {
196 i
+= 1; /* space to hold the extra '0' */
198 else if (base
> 10) {
199 *tcp
++ = '0' + base
/ 10;
200 *tcp
++ = '0' + base
% 10;
202 i
+= 3; /* space to hold e.g. '12#' */
204 else if (base
< 10) {
207 i
+= 2; /* space to hold e.g. '6#' */
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
215 if (mpz_size(&mpzp
->mpz
) > 1
216 || (long)mpz_get_ui(&mpzp
->mpz
) < 0L) {
218 i
+= 1; /* space to hold 'L' */
222 fprintf(stderr
, "mpz_format: requesting string size %d\n", i
);
223 #endif /* def MPZ_DEBUG */
225 (PyStringObject
*)PyString_FromStringAndSize((char *)0, i
))
229 /* get the beginning of the string memory and start copying things */
230 cp
= PyString_AS_STRING(strobjp
);
232 strcpy(cp
, initialiser_name
);
233 cp
+= strlen(initialiser_name
);
237 /* copy the already prepared prefix; e.g. sign and base indicator */
242 /* since' we have the sign already, let the lib think it's a positive
245 mpz_neg(&mpzp
->mpz
,&mpzp
->mpz
); /* hack Hack HAck HACk HACK */
246 (void)mpz_get_str(cp
, base
, &mpzp
->mpz
);
248 mpz_neg(&mpzp
->mpz
,&mpzp
->mpz
); /* hack Hack HAck HACk HACK */
250 fprintf(stderr
, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
252 #endif /* def MPZ_DEBUG */
264 "mpz_format: cp (str end) 0x%x, begin 0x%x, diff %d, i %d\n",
265 cp
, PyString_AS_STRING(strobjp
),
266 cp
- PyString_AS_STRING(strobjp
), i
);
267 #endif /* def MPZ_DEBUG */
268 assert(cp
- PyString_AS_STRING(strobjp
) <= i
);
270 if (cp
- PyString_AS_STRING(strobjp
) != i
) {
271 strobjp
->ob_size
-= i
- (cp
- PyString_AS_STRING(strobjp
));
274 return (PyObject
*)strobjp
;
284 fputs( "mpz_dealloc() called...\n", stderr
);
285 #endif /* def MPZ_DEBUG */
286 mpz_clear(&mpzp
->mpz
);
288 } /* mpz_dealloc() */
291 /* pointers to frequently used values 0, 1 and -1 */
292 static mpzobject
*mpz_value_zero
, *mpz_value_one
, *mpz_value_mone
;
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() */
314 #ifdef MPZ_SPARE_MALLOC
315 if (mpz_cmp_ui(&a
->mpz
, (unsigned long int)0) == 0) {
317 return (PyObject
*)b
;
320 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) == 0) {
322 return (PyObject
*)a
;
324 #endif /* def MPZ_SPARE_MALLOC */
326 if ((z
= newmpzobject()) == NULL
)
329 mpz_add(&z
->mpz
, &a
->mpz
, &b
->mpz
);
330 return (PyObject
*)z
;
331 } /* mpz_addition() */
341 #ifdef MPZ_SPARE_MALLOC
342 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) == 0) {
344 return (PyObject
*)a
;
346 #endif /* MPZ_SPARE_MALLOC */
348 if ((z
= newmpzobject()) == NULL
)
351 mpz_sub(&z
->mpz
, &a
->mpz
, &b
->mpz
);
352 return (PyObject
*)z
;
353 } /* mpz_substract() */
360 #ifdef MPZ_SPARE_MALLOC
362 #endif /* def MPZ_SPARE_MALLOC */
366 #ifdef MPZ_SPARE_MALLOC
367 if ((cmpres
= mpz_cmp_ui(&a
->mpz
, (unsigned long int)0)) == 0) {
368 Py_INCREF(mpz_value_zero
);
369 return (PyObject
*)mpz_value_zero
;
371 if (cmpres
> 0 && mpz_cmp_ui(&a
->mpz
, (unsigned long int)1) == 0) {
373 return (PyObject
*)b
;
376 if ((cmpres
= mpz_cmp_ui(&b
->mpz
, (unsigned long_int
)0)) == 0) {
377 Py_INCREF(mpz_value_zero
);
378 return (PyObject
*)mpz_value_zero
;
380 if (cmpres
> 0 && mpz_cmp_ui(&b
->mpz
, (unsigned long int)1) == 0) {
382 return (PyObject
*)a
;
384 #endif /* MPZ_SPARE_MALLOC */
386 if ((z
= newmpzobject()) == NULL
)
389 mpz_mul( &z
->mpz
, &a
->mpz
, &b
->mpz
);
390 return (PyObject
*)z
;
392 } /* mpz_multiply() */
399 #ifdef MPZ_SPARE_MALLOC
401 #endif /* def MPZ_SPARE_MALLOC */
406 #ifdef MPZ_SPARE_MALLOC
408 #endif /* def MPZ_SPARE_MALLOC */
409 mpz_cmp_ui(&b
->mpz
, (unsigned long int)0)) == 0) {
410 PyErr_SetString(PyExc_ZeroDivisionError
, "mpz./ by zero");
413 #ifdef MPZ_SPARE_MALLOC
414 if (cmpres
> 0 && mpz_cmp_ui(&b
->mpz(unsigned long int)1) == 0) {
416 return (PyObject
*)a
;
418 #endif /* def MPZ_SPARE_MALLOC */
420 if ((z
= newmpzobject()) == NULL
)
424 fputs("mpz_divide: div result", stderr
);
425 mpz_div(&z
->mpz
, &a
->mpz
, &b
->mpz
);
426 mpz_out_str(stderr
, 10, &z
->mpz
);
428 #endif /* def MPZ_TEST_DIV */
430 if ((mpz_cmp_ui(&a
->mpz
, (unsigned long int)0) < 0)
431 != (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) < 0)) {
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
441 mpz_divmod(&z
->mpz
, &tmpmpz
, &a
->mpz
, &b
->mpz
);
443 if (mpz_cmp_ui(&tmpmpz
, (unsigned long int)0) != 0)
444 mpz_sub_ui(&z
->mpz
, &z
->mpz
, (unsigned long int)1);
449 mpz_div(&z
->mpz
, &a
->mpz
, &b
->mpz
);
450 /* the ``naive'' implementation does it right for operands
451 having the same sign */
453 #else /* def MPZ_MDIV_BUG */
454 mpz_mdiv(&z
->mpz
, &a
->mpz
, &b
->mpz
);
455 #endif /* def MPZ_MDIV_BUG else */
457 fputs("mpz_divide: mdiv result", stderr
);
458 mpz_out_str(stderr
, 10, &z
->mpz
);
460 #endif /* def MPZ_TEST_DIV */
461 return (PyObject
*)z
;
470 #ifdef MPZ_SPARE_MALLOC
472 #endif /* def MPZ_SPARE_MALLOC */
477 #ifdef MPZ_SPARE_MALLOC
479 #endif /* def MPZ_SPARE_MALLOC */
480 mpz_cmp_ui(&b
->mpz
, (unsigned long int)0)) == 0) {
481 PyErr_SetString(PyExc_ZeroDivisionError
, "mpz.% by zero");
484 #ifdef MPZ_SPARE_MALLOC
486 if ((cmpres
= mpz_cmp_ui(&b
->mpz
, (unsigned long int)2)) == 0)
488 Py_INCREF(mpz_value_one
);
489 return (PyObject
*)mpz_value_one
;
492 /* b must be 1 now */
493 Py_INCREF(mpz_value_zero
);
494 return (PyObject
*)mpz_value_zero
;
497 #endif /* def MPZ_SPARE_MALLOC */
499 if ((z
= newmpzobject()) == NULL
)
503 fputs("mpz_remain: mod result", stderr
);
504 mpz_mod(&z
->mpz
, &a
->mpz
, &b
->mpz
);
505 mpz_out_str(stderr
, 10, &z
->mpz
);
507 #endif /* def MPZ_TEST_DIV */
510 /* the ``naive'' implementation does it right for operands
511 having the same sign */
512 mpz_mod(&z
->mpz
, &a
->mpz
, &b
->mpz
);
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
);
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
524 #else /* def MPZ_MDIV_BUG */
525 mpz_mmod(&z
->mpz
, &a
->mpz
, &b
->mpz
);
526 #endif /* def MPZ_MDIV_BUG else */
528 fputs("mpz_remain: mmod result", stderr
);
529 mpz_out_str(stderr
, 10, &z
->mpz
);
531 #endif /* def MPZ_TEST_DIV */
532 return (PyObject
*)z
;
534 } /* mpz_remainder() */
537 mpz_div_and_mod(a
, b
)
542 mpzobject
*x
= NULL
, *y
= NULL
;
545 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0) == 0) {
546 PyErr_SetString(PyExc_ZeroDivisionError
, "mpz.divmod by zero");
550 if ((z
= PyTuple_New(2)) == NULL
551 || (x
= newmpzobject()) == NULL
552 || (y
= newmpzobject()) == NULL
) {
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
);
564 mpz_out_str(stderr
, 10, &y
->mpz
);
566 #endif /* def MPZ_TEST_DIV */
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) {
573 ** numerator has other sign than denominator: we have
574 ** to look at the remainder for a correction.
576 mpz_add(&y
->mpz
, &y
->mpz
, &b
->mpz
);
577 mpz_sub_ui(&x
->mpz
, &x
->mpz
, (unsigned long int)1);
579 #else /* def MPZ_MDIV_BUG */
580 mpz_mdivmod( &x
->mpz
, &y
->mpz
, &a
->mpz
, &b
->mpz
);
581 #endif /* def MPZ_MDIV_BUG else */
583 fputs("mpz_divmod: mdm result", stderr
);
584 mpz_out_str(stderr
, 10, &x
->mpz
);
586 mpz_out_str(stderr
, 10, &y
->mpz
);
588 #endif /* def MPZ_TEST_DIV */
590 (void)PyTuple_SetItem(z
, 0, (PyObject
*)x
);
591 (void)PyTuple_SetItem(z
, 1, (PyObject
*)y
);
594 } /* mpz_div_and_mod() */
605 if ((PyObject
*)m
!= Py_None
) {
608 z
=(mpzobject
*)mpz_power(a
, b
, (mpzobject
*)Py_None
);
610 if (z
==NULL
) return((PyObject
*)z
);
611 z2
=(mpzobject
*)mpz_remainder(z
, m
);
613 return((PyObject
*)z2
);
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 */
619 Py_INCREF(mpz_value_one
);
620 return (PyObject
*)mpz_value_one
;
624 PyErr_SetString(PyExc_ValueError
,
625 "mpz.pow to negative exponent");
629 if ((cmpres
= mpz_cmp_ui(&a
->mpz
, (unsigned long int)0)) == 0) {
632 Py_INCREF(mpz_value_zero
);
633 return (PyObject
*)mpz_value_zero
;
636 && mpz_cmp_ui(&a
->mpz
, (unsigned long int)1) == 0) {
639 Py_INCREF(mpz_value_one
);
640 return (PyObject
*)mpz_value_one
;
643 && mpz_cmp_si(&a
->mpz
, (long int)-1) == 0) {
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 */
651 /* is the exponent even? */
654 /* look to the remainder after a division by (1 << 1) */
655 mpz_mod_2exp(&tmpmpz
, &b
->mpz
, (unsigned long int)1);
657 if (mpz_cmp_ui(&tmpmpz
, (unsigned int)0) == 0) {
659 Py_INCREF(mpz_value_one
);
660 return (PyObject
*)mpz_value_one
;
663 Py_INCREF(mpz_value_mone
);
664 return (PyObject
*)mpz_value_mone
;
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)
671 return (PyObject
*)PyErr_NoMemory();
672 #else /* def MPZ_LIB_DOES_CHECKING */
673 /* wet finger method */
674 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0x10000) >= 0) {
675 PyErr_SetString(PyExc_ValueError
,
676 "mpz.pow outrageous exponent");
679 #endif /* def MPZ_LIB_DOES_CHECKING else */
681 if ((z
= newmpzobject()) == NULL
)
684 mpz_pow_ui(&z
->mpz
, &a
->mpz
, mpz_get_ui(&b
->mpz
));
686 return (PyObject
*)z
;
697 #ifdef MPZ_SPARE_MALLOC
698 if (mpz_cmp_ui(&v
->mpz
, (unsigned long int)0) == 0) {
701 return (PyObject
*)v
;
703 #endif /* def MPZ_SPARE_MALLOC */
705 if ((z
= newmpzobject()) == NULL
)
708 mpz_neg(&z
->mpz
, &v
->mpz
);
709 return (PyObject
*)z
;
710 } /* mpz_negative() */
718 return (PyObject
*)v
;
719 } /* mpz_positive() */
729 if (mpz_cmp_ui(&v
->mpz
, (unsigned long int)0) >= 0) {
731 return (PyObject
*)v
;
734 if ((z
= newmpzobject()) == NULL
)
737 mpz_neg(&z
->mpz
, &v
->mpz
);
738 return (PyObject
*)z
;
739 } /* mpz_absolute() */
745 return mpz_cmp_ui(&v
->mpz
, (unsigned long int)0) != 0;
746 } /* mpz_nonzero() */
755 /* I think mpz_com does exactly what needed */
756 if ((z
= newmpzobject()) == NULL
)
759 mpz_com(&z
->mpz
, &v
->mpz
);
760 return (PyObject
*)z
;
761 } /* py_mpz_invert() */
772 if ((cmpres
= mpz_cmp_ui(&b
->mpz
, (unsigned long int)0)) == 0) {
775 return (PyObject
*)a
;
779 PyErr_SetString(PyExc_ValueError
,
780 "mpz.<< negative shift count");
784 #ifdef MPZ_LIB_DOES_CHECKING
785 if (mpz_size(&b
->mpz
) > 1)
786 return (PyObject
*)PyErr_NoMemory();
787 #else /* def MPZ_LIB_DOES_CHECKING */
788 /* wet finger method */
789 if (mpz_cmp_ui(&b
->mpz
, (unsigned long int)0x10000) >= 0) {
790 PyErr_SetString(PyExc_ValueError
,
791 "mpz.<< outrageous shift count");
794 #endif /* def MPZ_LIB_DOES_CHECKING else */
796 if ((z
= newmpzobject()) == NULL
)
799 mpz_mul_2exp(&z
->mpz
, &a
->mpz
, mpz_get_ui(&b
->mpz
));
800 return (PyObject
*)z
;
812 if ((cmpres
= mpz_cmp_ui(&b
->mpz
, (unsigned long int)0)) == 0) {
815 return (PyObject
*)a
;
819 PyErr_SetString(PyExc_ValueError
,
820 "mpz.>> negative shift count");
824 if (mpz_size(&b
->mpz
) > 1)
825 return (PyObject
*)PyErr_NoMemory();
827 if ((z
= newmpzobject()) == NULL
)
830 mpz_div_2exp(&z
->mpz
, &a
->mpz
, mpz_get_ui(&b
->mpz
));
831 return (PyObject
*)z
;
842 if ((z
= newmpzobject()) == NULL
)
845 mpz_and(&z
->mpz
, &a
->mpz
, &b
->mpz
);
846 return (PyObject
*)z
;
847 } /* mpz_andfunc() */
849 /* hack Hack HAck HACk HACK, XXX this code is dead slow */
851 mpz_xor(res
, op1
, op2
)
860 mpz_and(res
, op1
, op2
);
861 mpz_com(&tmpmpz
, res
);
862 mpz_ior(res
, op1
, op2
);
863 mpz_and(res
, res
, &tmpmpz
);
866 } /* mpz_xor() HACK */
876 if ((z
= newmpzobject()) == NULL
)
879 mpz_xor(&z
->mpz
, &a
->mpz
, &b
->mpz
);
880 return (PyObject
*)z
;
881 } /* mpz_xorfunc() */
891 if ((z
= newmpzobject()) == NULL
)
894 mpz_ior(&z
->mpz
, &a
->mpz
, &b
->mpz
);
895 return (PyObject
*)z
;
898 /* MPZ initialisation */
900 #include "longintrepr.h"
912 fputs("MPZ_mpz() called...\n", stderr
);
913 #endif /* def MPZ_DEBUG */
915 if (!PyArg_Parse(args
, "O", &objp
))
918 /* at least we know it's some object */
919 /* note DON't Py_DECREF args NEITHER objp */
921 if (PyInt_Check(objp
)) {
924 if (!PyArg_Parse(objp
, "l", &lval
))
927 if (lval
== (long)0) {
928 Py_INCREF(mpz_value_zero
);
929 mpzp
= mpz_value_zero
;
931 else if (lval
== (long)1) {
932 Py_INCREF(mpz_value_one
);
933 mpzp
= mpz_value_one
;
935 else if ((mpzp
= newmpzobject()) == NULL
)
937 else mpz_set_si(&mpzp
->mpz
, lval
);
939 else if (PyLong_Check(objp
)) {
942 unsigned char isnegative
;
945 if ((mpzp
= newmpzobject()) == NULL
)
948 mpz_set_si(&mpzp
->mpz
, 0L);
949 mpz_init(&mplongdigit
);
951 /* how we're gonna handle this? */
953 ((i
= ((PyLongObject
*)objp
)->ob_size
) < 0) ))
957 mpz_set_ui(&mplongdigit
,
959 ((PyLongObject
*)objp
)->ob_digit
[i
]);
960 mpz_mul_2exp(&mplongdigit
,&mplongdigit
,
961 (unsigned long int)i
* SHIFT
);
962 mpz_ior(&mpzp
->mpz
, &mpzp
->mpz
, &mplongdigit
);
966 mpz_neg(&mpzp
->mpz
, &mpzp
->mpz
);
968 /* get rid of allocation for tmp variable */
969 mpz_clear(&mplongdigit
);
971 else if (PyString_Check(objp
)) {
972 unsigned char *cp
= (unsigned char *)PyString_AS_STRING(objp
);
973 int len
= PyString_GET_SIZE(objp
);
976 if ((mpzp
= newmpzobject()) == NULL
)
979 mpz_set_si(&mpzp
->mpz
, 0L);
980 mpz_init(&mplongdigit
);
982 /* let's do it the same way as with the long conversion:
983 without thinking how it can be faster (-: :-) */
987 mpz_set_ui(&mplongdigit
, (unsigned long)*--cp
);
988 mpz_mul_2exp(&mplongdigit
,&mplongdigit
,
989 (unsigned long int)len
* 8);
990 mpz_ior(&mpzp
->mpz
, &mpzp
->mpz
, &mplongdigit
);
993 /* get rid of allocation for tmp variable */
994 mpz_clear(&mplongdigit
);
996 else if (is_mpzobject(objp
)) {
998 mpzp
= (mpzobject
*)objp
;
1001 PyErr_SetString(PyExc_TypeError
,
1002 "mpz.mpz() expects integer, long, string or mpz object argument");
1008 fputs("MPZ_mpz: created mpz=", stderr
);
1009 mpz_out_str(stderr
, 10, &mpzp
->mpz
);
1011 #endif /* def MPZ_DEBUG */
1012 return (PyObject
*)mpzp
;
1019 /* shortcut: 9 out of 10 times the type is already ok */
1020 if (is_mpzobject(z
)) {
1022 return (mpzobject
*)z
; /* coercion succeeded */
1025 /* what types do we accept?: intobjects and longobjects */
1026 if (PyInt_Check(z
) || PyLong_Check(z
))
1027 return (mpzobject
*)MPZ_mpz((PyObject
*)NULL
, z
);
1029 PyErr_SetString(PyExc_TypeError
,
1030 "number coercion (to mpzobject) failed");
1032 } /* mpz_mpzcoerce() */
1035 static void mpz_divm
Py_PROTO((MP_INT
*res
, const MP_INT
*num
,
1036 const MP_INT
*den
, const MP_INT
*mod
));
1039 MPZ_powm(self
, args
)
1043 PyObject
*base
, *exp
, *mod
;
1044 mpzobject
*mpzbase
= NULL
, *mpzexp
= NULL
, *mpzmod
= NULL
;
1049 if (!PyArg_Parse(args
, "(OOO)", &base
, &exp
, &mod
))
1052 if ((mpzbase
= mpz_mpzcoerce(base
)) == NULL
1053 || (mpzexp
= mpz_mpzcoerce(exp
)) == NULL
1054 || (mpzmod
= mpz_mpzcoerce(mod
)) == NULL
1055 || (z
= newmpzobject()) == NULL
) {
1056 Py_XDECREF(mpzbase
);
1062 if ((tstres
=mpz_cmp_ui(&mpzexp
->mpz
, (unsigned long int)0)) == 0) {
1063 Py_INCREF(mpz_value_one
);
1064 return (PyObject
*)mpz_value_one
;
1071 mpz_init_set(&absexp
, &mpzexp
->mpz
);
1072 mpz_abs(&absexp
, &absexp
);
1073 mpz_powm(&z
->mpz
, &mpzbase
->mpz
, &absexp
, &mpzmod
->mpz
);
1075 mpz_divm(&z
->mpz
, &mpz_value_one
->mpz
, &z
->mpz
, &mpzmod
->mpz
);
1080 mpz_powm(&z
->mpz
, &mpzbase
->mpz
, &mpzexp
->mpz
, &mpzmod
->mpz
);
1087 return (PyObject
*)z
;
1096 PyObject
*op1
, *op2
;
1097 mpzobject
*mpzop1
= NULL
, *mpzop2
= NULL
;
1101 if (!PyArg_Parse(args
, "(OO)", &op1
, &op2
))
1104 if ((mpzop1
= mpz_mpzcoerce(op1
)) == NULL
1105 || (mpzop2
= mpz_mpzcoerce(op2
)) == NULL
1106 || (z
= newmpzobject()) == NULL
) {
1112 /* ok, we have three mpzobjects, and an initialised result holder */
1113 mpz_gcd(&z
->mpz
, &mpzop1
->mpz
, &mpzop2
->mpz
);
1118 return (PyObject
*)z
;
1123 MPZ_gcdext(self
, args
)
1127 PyObject
*op1
, *op2
, *z
= NULL
;
1128 mpzobject
*mpzop1
= NULL
, *mpzop2
= NULL
;
1129 mpzobject
*g
= NULL
, *s
= NULL
, *t
= NULL
;
1132 if (!PyArg_Parse(args
, "(OO)", &op1
, &op2
))
1135 if ((mpzop1
= mpz_mpzcoerce(op1
)) == NULL
1136 || (mpzop2
= mpz_mpzcoerce(op2
)) == NULL
1137 || (z
= PyTuple_New(3)) == NULL
1138 || (g
= newmpzobject()) == NULL
1139 || (s
= newmpzobject()) == NULL
1140 || (t
= newmpzobject()) == NULL
) {
1150 mpz_gcdext(&g
->mpz
, &s
->mpz
, &t
->mpz
, &mpzop1
->mpz
, &mpzop2
->mpz
);
1155 (void)PyTuple_SetItem(z
, 0, (PyObject
*)g
);
1156 (void)PyTuple_SetItem(z
, 1, (PyObject
*)s
);
1157 (void)PyTuple_SetItem(z
, 2, (PyObject
*)t
);
1159 return (PyObject
*)z
;
1160 } /* MPZ_gcdext() */
1164 MPZ_sqrt(self
, args
)
1169 mpzobject
*mpzop
= NULL
;
1173 if (!PyArg_Parse(args
, "O", &op
))
1176 if ((mpzop
= mpz_mpzcoerce(op
)) == NULL
1177 || (z
= newmpzobject()) == NULL
) {
1182 mpz_sqrt(&z
->mpz
, &mpzop
->mpz
);
1186 return (PyObject
*)z
;
1191 MPZ_sqrtrem(self
, args
)
1195 PyObject
*op
, *z
= NULL
;
1196 mpzobject
*mpzop
= NULL
;
1197 mpzobject
*root
= NULL
, *rem
= NULL
;
1200 if (!PyArg_Parse(args
, "O", &op
))
1203 if ((mpzop
= mpz_mpzcoerce(op
)) == NULL
1204 || (z
= PyTuple_New(2)) == NULL
1205 || (root
= newmpzobject()) == NULL
1206 || (rem
= newmpzobject()) == NULL
) {
1210 /*Py_XDECREF(rem);*/
1214 mpz_sqrtrem(&root
->mpz
, &rem
->mpz
, &mpzop
->mpz
);
1218 (void)PyTuple_SetItem(z
, 0, (PyObject
*)root
);
1219 (void)PyTuple_SetItem(z
, 1, (PyObject
*)rem
);
1221 return (PyObject
*)z
;
1222 } /* MPZ_sqrtrem() */
1227 mpz_divm(MP_INT
*res
, const MP_INT
*num
, const MP_INT
*den
, const MP_INT
*mod
)
1229 mpz_divm(res
, num
, den
, mod
)
1236 MP_INT s0
, s1
, q
, r
, x
, d0
, d1
;
1238 mpz_init_set(&s0
, num
);
1239 mpz_init_set_ui(&s1
, 0);
1243 mpz_init_set(&d0
, den
);
1244 mpz_init_set(&d1
, mod
);
1247 while (d1
._mp_size
!= 0) {
1249 while (d1
.size
!= 0) {
1251 mpz_divmod(&q
, &r
, &d0
, &d1
);
1255 mpz_mul(&x
, &s1
, &q
);
1256 mpz_sub(&x
, &s0
, &x
);
1262 if (d0
._mp_size
!= 1 || d0
._mp_d
[0] != 1)
1263 res
->_mp_size
= 0; /* trouble: the gcd != 1; set s to zero */
1265 if (d0
.size
!= 1 || d0
.d
[0] != 1)
1266 res
->size
= 0; /* trouble: the gcd != 1; set s to zero */
1270 /* watch out here! first check the signs, and then perform
1271 the mpz_mod() since mod could point to res */
1272 if ((s0
.size
< 0) != (mod
->size
< 0)) {
1273 mpz_mod(res
, &s0
, mod
);
1276 mpz_add(res
, res
, mod
);
1279 mpz_mod(res
, &s0
, mod
);
1281 #else /* def MPZ_MDIV_BUG */
1282 mpz_mmod(res
, &s0
, mod
);
1283 #endif /* def MPZ_MDIV_BUG else */
1297 MPZ_divm(self
, args
)
1301 PyObject
*num
, *den
, *mod
;
1302 mpzobject
*mpznum
, *mpzden
, *mpzmod
= NULL
;
1303 mpzobject
*z
= NULL
;
1306 if (!PyArg_Parse(args
, "(OOO)", &num
, &den
, &mod
))
1309 if ((mpznum
= mpz_mpzcoerce(num
)) == NULL
1310 || (mpzden
= mpz_mpzcoerce(den
)) == NULL
1311 || (mpzmod
= mpz_mpzcoerce(mod
)) == NULL
1312 || (z
= newmpzobject()) == NULL
) {
1319 mpz_divm(&z
->mpz
, &mpznum
->mpz
, &mpzden
->mpz
, &mpzmod
->mpz
);
1325 if (mpz_cmp_ui(&z
->mpz
, (unsigned long int)0) == 0) {
1327 PyErr_SetString(PyExc_ValueError
,
1328 "gcd(den, mod) != 1 or num == 0");
1332 return (PyObject
*)z
;
1336 /* MPZ methods-as-attributes */
1337 #ifdef MPZ_CONVERSIONS_AS_METHODS
1342 #else /* def MPZ_CONVERSIONS_AS_METHODS */
1346 #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1351 #ifdef MPZ_CONVERSIONS_AS_METHODS
1352 if (!PyArg_NoArgs(args
))
1354 #endif /* def MPZ_CONVERSIONS_AS_METHODS */
1356 if (mpz_size(&self
->mpz
) > 1
1357 || (sli
= (long)mpz_get_ui(&self
->mpz
)) < (long)0 ) {
1358 PyErr_SetString(PyExc_ValueError
,
1359 "mpz.int() arg too long to convert");
1363 if (mpz_cmp_ui(&self
->mpz
, (unsigned long)0) < 0)
1366 return PyInt_FromLong(sli
);
1370 #ifdef MPZ_CONVERSIONS_AS_METHODS
1371 mpz_long(self
, args
)
1374 #else /* def MPZ_CONVERSIONS_AS_METHODS */
1377 #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1380 unsigned long int uli
;
1381 PyLongObject
*longobjp
;
1383 int bitpointer
, newbitpointer
;
1387 #ifdef MPZ_CONVERSIONS_AS_METHODS
1388 if (!PyArg_NoArgs(args
))
1390 #endif /* def MPZ_CONVERSIONS_AS_METHODS */
1392 /* determine length of python-long to be allocated */
1393 if ((longobjp
= _PyLong_New(i
= (int)
1394 ((mpz_size(&self
->mpz
) * BITS_PER_MP_LIMB
1399 /* determine sign, and copy self to scratch var */
1400 mpz_init_set(&mpzscratch
, &self
->mpz
);
1401 if ((isnegative
= (mpz_cmp_ui(&self
->mpz
, (unsigned long int)0) < 0)))
1402 mpz_neg(&mpzscratch
, &mpzscratch
);
1404 /* let those bits come, let those bits go,
1405 e.g. dismantle mpzscratch, build PyLongObject */
1407 bitpointer
= 0; /* the number of valid bits in stock */
1409 ldcount
= 0; /* the python-long limb counter */
1410 uli
= (unsigned long int)0;
1412 longobjp
->ob_digit
[ldcount
] = uli
& MASK
;
1414 /* check if we've had enough bits for this digit */
1415 if (bitpointer
< SHIFT
) {
1416 uli
= mpz_get_ui(&mpzscratch
);
1417 longobjp
->ob_digit
[ldcount
] |=
1418 (uli
<< bitpointer
) & MASK
;
1419 uli
>>= SHIFT
-bitpointer
;
1420 bitpointer
+= BITS_PER_MP_LIMB
;
1421 mpz_div_2exp(&mpzscratch
, &mpzscratch
,
1426 bitpointer
-= SHIFT
;
1430 assert(mpz_cmp_ui(&mpzscratch
, (unsigned long int)0) == 0);
1431 mpz_clear(&mpzscratch
);
1432 assert(ldcount
<= longobjp
->ob_size
);
1434 /* long_normalize() is file-static */
1435 /* longobjp = long_normalize(longobjp); */
1436 while (ldcount
> 0 && longobjp
->ob_digit
[ldcount
-1] == 0)
1438 longobjp
->ob_size
= ldcount
;
1442 longobjp
->ob_size
= -longobjp
->ob_size
;
1444 return (PyObject
*)longobjp
;
1449 /* I would have avoided pow() anyways, so ... */
1450 static const double multiplier
= 256.0 * 256.0 * 256.0 * 256.0;
1452 #ifdef MPZ_CONVERSIONS_AS_METHODS
1454 mpz_float(self
, args
)
1457 #else /* def MPZ_CONVERSIONS_AS_METHODS */
1461 #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1469 #ifdef MPZ_CONVERSIONS_AS_METHODS
1470 if (!PyArg_NoArgs(args
))
1472 #endif /* def MPZ_CONVERSIONS_AS_METHODS */
1474 i
= (int)mpz_size(&self
->mpz
);
1476 /* determine sign, and copy abs(self) to scratch var */
1477 if ((isnegative
= (mpz_cmp_ui(&self
->mpz
, (unsigned long int)0) < 0)))
1479 mpz_init(&mpzscratch
);
1480 mpz_neg(&mpzscratch
, &self
->mpz
);
1483 mpz_init_set(&mpzscratch
, &self
->mpz
);
1485 /* let those bits come, let those bits go,
1486 e.g. dismantle mpzscratch, build PyFloatObject */
1488 /* Can this overflow? Dunno, protect against that possibility. */
1489 PyFPE_START_PROTECT("mpz_float", return 0)
1493 x
+= mulstate
* mpz_get_ui(&mpzscratch
);
1494 mulstate
*= multiplier
;
1495 mpz_div_2exp(&mpzscratch
, &mpzscratch
, BITS_PER_MP_LIMB
);
1497 PyFPE_END_PROTECT(mulstate
)
1499 assert(mpz_cmp_ui(&mpzscratch
, (unsigned long int)0) == 0);
1500 mpz_clear(&mpzscratch
);
1505 return PyFloat_FromDouble(x
);
1509 #ifdef MPZ_CONVERSIONS_AS_METHODS
1514 #else /* def MPZ_CONVERSIONS_AS_METHODS */
1518 #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1520 #ifdef MPZ_CONVERSIONS_AS_METHODS
1521 if (!PyArg_NoArgs(args
))
1523 #endif /* def MPZ_CONVERSIONS_AS_METHODS */
1525 return mpz_format(self
, 16, (unsigned char)1);
1528 #ifdef MPZ_CONVERSIONS_AS_METHODS
1533 #else /* def MPZ_CONVERSIONS_AS_METHODS */
1537 #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
1539 #ifdef MPZ_CONVERSIONS_AS_METHODS
1540 if (!PyArg_NoArgs(args
))
1542 #endif /* def MPZ_CONVERSIONS_AS_METHODS */
1544 return mpz_format(self
, 8, (unsigned char)1);
1548 mpz_binary(self
, args
)
1553 PyStringObject
*strobjp
;
1556 unsigned long ldigit
;
1558 if (!PyArg_NoArgs(args
))
1561 if (mpz_cmp_ui(&self
->mpz
, (unsigned long int)0) < 0) {
1562 PyErr_SetString(PyExc_ValueError
,
1563 "mpz.binary() arg must be >= 0");
1567 mpz_init_set(&mp
, &self
->mpz
);
1568 size
= (int)mpz_size(&mp
);
1570 if ((strobjp
= (PyStringObject
*)
1571 PyString_FromStringAndSize(
1572 (char *)0, size
* sizeof (unsigned long int))) == NULL
)
1575 /* get the beginning of the string memory and start copying things */
1576 cp
= PyString_AS_STRING(strobjp
);
1578 /* this has been programmed using a (fairly) decent lib-i/f it could
1579 be must faster if we looked into the GMP lib */
1581 ldigit
= mpz_get_ui(&mp
);
1582 mpz_div_2exp(&mp
, &mp
, BITS_PER_MP_LIMB
);
1583 *cp
++ = (unsigned char)(ldigit
& 0xFF);
1584 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1585 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1586 *cp
++ = (unsigned char)((ldigit
>>= 8) & 0xFF);
1589 while (strobjp
->ob_size
&& !*--cp
)
1592 return (PyObject
*)strobjp
;
1593 } /* mpz_binary() */
1596 static PyMethodDef mpz_methods
[] = {
1597 #ifdef MPZ_CONVERSIONS_AS_METHODS
1600 {"float", mpz_float
},
1603 #endif /* def MPZ_CONVERSIONS_AS_METHODS */
1604 {"binary", (PyCFunction
)mpz_binary
},
1605 {NULL
, NULL
} /* sentinel */
1609 mpz_getattr(self
, name
)
1613 return Py_FindMethod(mpz_methods
, (PyObject
*)self
, name
);
1614 } /* mpz_getattr() */
1625 fputs("mpz_coerce() called...\n", stderr
);
1626 #endif /* def MPZ_DEBUG */
1628 assert(is_mpzobject(*pv
));
1630 /* always convert other arg to mpz value, except for floats */
1631 if (!PyFloat_Check(*pw
)) {
1632 if ((z
= (PyObject
*)mpz_mpzcoerce(*pw
)) == NULL
)
1633 return -1; /* -1: an error always has been set */
1639 if ((z
= mpz_float(*pv
, NULL
)) == NULL
)
1645 return 0; /* coercion succeeded */
1647 } /* mpz_coerce() */
1654 return mpz_format(v
, 10, (unsigned char)1);
1659 #define UF (unaryfunc)
1660 #define BF (binaryfunc)
1661 #define TF (ternaryfunc)
1662 #define IF (inquiry)
1663 #define CF (coercion)
1665 static PyNumberMethods mpz_as_number
= {
1666 BF mpz_addition
, /*nb_add*/
1667 BF mpz_substract
, /*nb_subtract*/
1668 BF mpz_multiply
, /*nb_multiply*/
1669 BF mpz_divide
, /*nb_divide*/
1670 BF mpz_remainder
, /*nb_remainder*/
1671 BF mpz_div_and_mod
, /*nb_divmod*/
1672 TF mpz_power
, /*nb_power*/
1673 UF mpz_negative
, /*nb_negative*/
1674 UF mpz_positive
, /*tp_positive*/
1675 UF mpz_absolute
, /*tp_absolute*/
1676 IF mpz_nonzero
, /*tp_nonzero*/
1677 UF py_mpz_invert
, /*nb_invert*/
1678 BF mpz_lshift
, /*nb_lshift*/
1679 BF mpz_rshift
, /*nb_rshift*/
1680 BF mpz_andfunc
, /*nb_and*/
1681 BF mpz_xorfunc
, /*nb_xor*/
1682 BF mpz_orfunc
, /*nb_or*/
1683 CF mpz_coerce
, /*nb_coerce*/
1684 #ifndef MPZ_CONVERSIONS_AS_METHODS
1685 UF mpz_int
, /*nb_int*/
1686 UF mpz_long
, /*nb_long*/
1687 UF mpz_float
, /*nb_float*/
1688 UF mpz_oct
, /*nb_oct*/
1689 UF mpz_hex
, /*nb_hex*/
1690 #endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
1693 static PyTypeObject MPZtype
= {
1694 PyObject_HEAD_INIT(&PyType_Type
)
1697 sizeof(mpzobject
), /*tp_size*/
1700 (destructor
)mpz_dealloc
, /*tp_dealloc*/
1702 (getattrfunc
)mpz_getattr
, /*tp_getattr*/
1704 (cmpfunc
)mpz_compare
, /*tp_compare*/
1705 (reprfunc
)mpz_repr
, /*tp_repr*/
1706 &mpz_as_number
, /*tp_as_number*/
1709 /* List of functions exported by this module */
1711 static PyMethodDef mpz_functions
[] = {
1713 {initialiser_name
, MPZ_mpz
},
1715 /* until guido ``fixes'' struct PyMethodDef */
1716 {(char *)initialiser_name
, MPZ_mpz
},
1720 {"gcdext", MPZ_gcdext
},
1722 {"sqrtrem", MPZ_sqrtrem
},
1724 {NULL
, NULL
} /* Sentinel */
1728 /* #define MP_TEST_ALLOC */
1730 #ifdef MP_TEST_ALLOC
1731 #define MP_TEST_SIZE 4
1732 static const char mp_test_magic
[MP_TEST_SIZE
] = {'\xAA','\xAA','\xAA','\xAA'};
1733 static mp_test_error( location
)
1736 /* assumptions: *alloc returns address dividable by 4,
1737 mpz_* routines allocate in chunks dividable by four */
1738 fprintf(stderr
, "MP_TEST_ERROR: location holds 0x%08d\n", *location
);
1739 Py_FatalError("MP_TEST_ERROR");
1740 } /* static mp_test_error() */
1741 #define MP_EXTRA_ALLOC(size) ((size) + MP_TEST_SIZE)
1742 #define MP_SET_TEST(basep,size) (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
1743 #define MP_DO_TEST(basep,size) if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
1746 mp_test_error((int *)((char *)(basep) + size))
1747 #else /* def MP_TEST_ALLOC */
1748 #define MP_EXTRA_ALLOC(size) (size)
1749 #define MP_SET_TEST(basep,size)
1750 #define MP_DO_TEST(basep,size)
1751 #endif /* def MP_TEST_ALLOC else */
1753 void *mp_allocate( alloc_size
)
1759 fprintf(stderr
, "mp_allocate : size %ld\n",
1761 #endif /* def MPZ_DEBUG */
1763 if ( (res
= malloc(MP_EXTRA_ALLOC(alloc_size
))) == NULL
)
1764 Py_FatalError("mp_allocate failure");
1767 fprintf(stderr
, "mp_allocate : address 0x%08x\n", res
);
1768 #endif /* def MPZ_DEBUG */
1770 MP_SET_TEST(res
,alloc_size
);
1773 } /* mp_allocate() */
1776 void *mp_reallocate( ptr
, old_size
, new_size
)
1784 fprintf(stderr
, "mp_reallocate: old address 0x%08x, old size %ld\n",
1786 #endif /* def MPZ_DEBUG */
1788 MP_DO_TEST(ptr
, old_size
);
1790 if ( (res
= realloc(ptr
, MP_EXTRA_ALLOC(new_size
))) == NULL
)
1791 Py_FatalError("mp_reallocate failure");
1794 fprintf(stderr
, "mp_reallocate: new address 0x%08x, new size %ld\n",
1796 #endif /* def MPZ_DEBUG */
1798 MP_SET_TEST(res
, new_size
);
1801 } /* mp_reallocate() */
1804 void mp_free( ptr
, size
)
1810 fprintf(stderr
, "mp_free : old address 0x%08x, old size %ld\n",
1812 #endif /* def MPZ_DEBUG */
1814 MP_DO_TEST(ptr
, size
);
1820 /* Initialize this module. */
1829 fputs( "initmpz() called...\n", stderr
);
1830 #endif /* def MPZ_DEBUG */
1832 mp_set_memory_functions( mp_allocate
, mp_reallocate
, mp_free
);
1833 module
= Py_InitModule("mpz", mpz_functions
);
1835 /* create some frequently used constants */
1836 if ((mpz_value_zero
= newmpzobject()) == NULL
)
1837 Py_FatalError("initmpz: can't initialize mpz constants");
1838 mpz_set_ui(&mpz_value_zero
->mpz
, (unsigned long int)0);
1840 if ((mpz_value_one
= newmpzobject()) == NULL
)
1841 Py_FatalError("initmpz: can't initialize mpz constants");
1842 mpz_set_ui(&mpz_value_one
->mpz
, (unsigned long int)1);
1844 if ((mpz_value_mone
= newmpzobject()) == NULL
)
1845 Py_FatalError("initmpz: can't initialize mpz constants");
1846 mpz_set_si(&mpz_value_mone
->mpz
, (long)-1);
1848 dict
= PyModule_GetDict(module
);
1850 PyDict_SetItemString(dict
, "MPZType", (PyObject
*)&MPZtype
);
1855 int _mpz_dummy_int
; /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
1856 #endif /* def MAKEDUMMYINT */