home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Python 1.4 / Python 1.4 source / Modules / mpzmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-28  |  40.3 KB  |  1,836 lines  |  [TEXT/CWIE]

  1. /***********************************************************
  2. Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
  3. The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  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
  15. permission.
  16.  
  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.
  20.  
  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.
  29.  
  30. ******************************************************************/
  31.  
  32. /* 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.  
  43. #include "allobjects.h"
  44.  
  45. #include <assert.h>
  46. #include <sys/types.h>        /* For size_t */
  47.  
  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
  86. ** This has been fixed with gmp release 2.0
  87. */
  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. */
  93.  
  94. #include "gmp.h"
  95. #include "gmp-impl.h"
  96.  
  97. #if __GNU_MP__ == 2
  98. #define GMP2
  99. #else
  100. #define MPZ_GET_STR_BUG
  101. #endif
  102.  
  103. typedef struct {
  104.     OB_HEAD
  105.         MP_INT    mpz;        /* the actual number */
  106. } mpzobject;
  107.  
  108. staticforward typeobject MPZtype;
  109.  
  110. #define is_mpzobject(v)        ((v)->ob_type == &MPZtype)
  111.  
  112. static const char initialiser_name[] = "mpz";
  113.  
  114. /* #define MPZ_DEBUG */
  115.  
  116. static mpzobject *
  117. newmpzobject()
  118. {
  119.     mpzobject *mpzp;
  120.  
  121.  
  122. #ifdef MPZ_DEBUG
  123.     fputs( "mpz_object() called...\n", stderr );
  124. #endif /* def MPZ_DEBUG */
  125.     mpzp = NEWOBJ(mpzobject, &MPZtype);
  126.     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
  134. #include "longlong.h"
  135. #endif /* def MPZ_GET_STR_BUG */
  136.  
  137. static object *
  138. mpz_format(objp, base, withname)
  139.     object *objp;
  140.     int base;
  141.     unsigned char withname;
  142. {
  143.     mpzobject *mpzp = (mpzobject *)objp;
  144.     stringobject *strobjp;
  145.     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)) {
  155.         err_badcall();
  156.         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
  178. #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
  182.     i += ((size_t) abs(mpzp->mpz.size) * BITS_PER_MP_LIMB
  183.           * __mp_bases[base].chars_per_bit_exactly) + 1;
  184. #endif
  185. #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 */    
  224.     if ((strobjp = (stringobject *)newsizedstringobject((char *)0, i))
  225.         == NULL)
  226.         return NULL;
  227.  
  228.     /* get the beginning of the string memory and start copying things */
  229.     cp = GETSTRINGVALUE(strobjp);
  230.     if (withname) {
  231.         strcpy(cp, initialiser_name);
  232.         cp += strlen(initialiser_name);
  233.         *cp++ = '('; /*')'*/
  234.     }
  235.  
  236.     /* copy the already prepared prefix; e.g. sign and base indicator */
  237.     *tcp = '\0';
  238.     strcpy(cp, prefix);
  239.     cp += tcp - prefix;
  240.  
  241.     /* since' we have the sign already, let the lib think it's a positive
  242.         number */
  243.     if (cmpres < 0)
  244.         mpz_neg(&mpzp->mpz,&mpzp->mpz);    /* hack Hack HAck HACk HACK */
  245.     (void)mpz_get_str(cp, base, &mpzp->mpz);
  246.     if (cmpres < 0)
  247.         mpz_neg(&mpzp->mpz,&mpzp->mpz);    /* hack Hack HAck HACk HACK */
  248. #ifdef MPZ_DEBUG
  249.     fprintf(stderr, "mpz_format: base (ultim) %d, mpz_get_str: %s\n",
  250.         base, cp);
  251. #endif /* def MPZ_DEBUG */
  252.     cp += strlen(cp);
  253.  
  254.     if (taglong)
  255.         *cp++ = 'L';
  256.     if (withname)
  257.         *cp++ = /*'('*/ ')';
  258.  
  259.     *cp = '\0';
  260.  
  261. #ifdef MPZ_DEBUG
  262.     fprintf(stderr,
  263.         "mpz_format: cp (str end) 0x%x, begin 0x%x, diff %d, i %d\n",
  264.         cp, GETSTRINGVALUE(strobjp), cp - GETSTRINGVALUE(strobjp), i);
  265. #endif /* def MPZ_DEBUG */    
  266.     assert(cp - GETSTRINGVALUE(strobjp) <= i);
  267.  
  268.     if (cp - GETSTRINGVALUE(strobjp) != i) {
  269.         strobjp->ob_size -= i - (cp - GETSTRINGVALUE(strobjp));
  270.     }
  271.  
  272.     return (object *)strobjp;
  273. } /* mpz_format() */
  274.  
  275. /* MPZ methods */
  276.  
  277. static void
  278. mpz_dealloc(mpzp)
  279.     mpzobject *mpzp;
  280. {
  281. #ifdef MPZ_DEBUG
  282.     fputs( "mpz_dealloc() called...\n", stderr );
  283. #endif /* def MPZ_DEBUG */
  284.     mpz_clear(&mpzp->mpz);
  285.     DEL(mpzp);
  286. } /* mpz_dealloc() */
  287.  
  288.  
  289. /* pointers to frequently used values 0, 1 and -1 */
  290. static mpzobject *mpz_value_zero, *mpz_value_one, *mpz_value_mone;
  291.  
  292. static int
  293. mpz_compare(a, b)
  294.     mpzobject *a, *b;
  295. {
  296.     int cmpres;
  297.  
  298.  
  299.     /* guido sez it's better to return -1, 0 or 1 */
  300.     return (cmpres = mpz_cmp( &a->mpz, &b->mpz )) == 0 ? 0
  301.         : cmpres > 0 ? 1 : -1;
  302. } /* mpz_compare() */
  303.  
  304. static object *
  305. mpz_addition(a, b)
  306.     mpzobject *a;
  307.     mpzobject *b;
  308. {
  309.     mpzobject *z;
  310.  
  311.     
  312. #ifdef MPZ_SPARE_MALLOC
  313.     if (mpz_cmp_ui(&a->mpz, (unsigned long int)0) == 0) {
  314.         INCREF(b);
  315.         return (object *)b;
  316.     }
  317.  
  318.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
  319.         INCREF(a);
  320.         return (object *)a;
  321.     }
  322. #endif /* def MPZ_SPARE_MALLOC */
  323.  
  324.     if ((z = newmpzobject()) == NULL)
  325.         return NULL;
  326.     
  327.     mpz_add(&z->mpz, &a->mpz, &b->mpz);
  328.     return (object *)z;
  329. } /* mpz_addition() */
  330.  
  331. static object *
  332. mpz_substract(a, b)
  333.     mpzobject *a;
  334.     mpzobject *b;
  335. {
  336.     mpzobject *z;
  337.  
  338.     
  339. #ifdef MPZ_SPARE_MALLOC
  340.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
  341.         INCREF(a);
  342.         return (object *)a;
  343.     }
  344. #endif /* MPZ_SPARE_MALLOC */    
  345.  
  346.     if ((z = newmpzobject()) == NULL)
  347.         return NULL;
  348.  
  349.     mpz_sub(&z->mpz, &a->mpz, &b->mpz);
  350.     return (object *)z;
  351. } /* mpz_substract() */
  352.  
  353. static object *
  354. mpz_multiply(a, b)
  355.     mpzobject *a;
  356.     mpzobject *b;
  357. {
  358. #ifdef MPZ_SPARE_MALLOC
  359.     int cmpres;
  360. #endif /* def MPZ_SPARE_MALLOC */
  361.     mpzobject *z;
  362.  
  363.  
  364. #ifdef MPZ_SPARE_MALLOC
  365.     if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
  366.         INCREF(mpz_value_zero);
  367.         return (object *)mpz_value_zero;
  368.     }
  369.     if (cmpres > 0 && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
  370.         INCREF(b);
  371.         return (object *)b;
  372.     }
  373.  
  374.     if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long_int)0)) == 0) {
  375.         INCREF(mpz_value_zero);
  376.         return (object *)mpz_value_zero;
  377.     }
  378.     if (cmpres > 0 && mpz_cmp_ui(&b->mpz, (unsigned long int)1) == 0) {
  379.         INCREF(a);
  380.         return (object *)a;
  381.     }
  382. #endif /* MPZ_SPARE_MALLOC */
  383.  
  384.     if ((z = newmpzobject()) == NULL)
  385.         return NULL;
  386.  
  387.     mpz_mul( &z->mpz, &a->mpz, &b->mpz );
  388.     return (object *)z;
  389.     
  390. } /* mpz_multiply() */
  391.  
  392. static object *
  393. mpz_divide(a, b)
  394.     mpzobject *a;
  395.     mpzobject *b;
  396. {
  397. #ifdef MPZ_SPARE_MALLOC
  398.     int cmpres;
  399. #endif /* def MPZ_SPARE_MALLOC */
  400.     mpzobject *z;
  401.  
  402.  
  403.     if ((
  404. #ifdef MPZ_SPARE_MALLOC
  405.          cmpres =
  406. #endif /* def MPZ_SPARE_MALLOC */
  407.          mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  408.         err_setstr(ZeroDivisionError, "mpz./ by zero");
  409.         return NULL;
  410.     }
  411. #ifdef MPZ_SPARE_MALLOC
  412.     if (cmpres > 0 && mpz_cmp_ui(&b->mpz(unsigned long int)1) == 0) {
  413.         INCREF(a);
  414.         return (object *)a;
  415.     }
  416. #endif /* def MPZ_SPARE_MALLOC */
  417.  
  418.     if ((z = newmpzobject()) == NULL)
  419.         return NULL;
  420.  
  421. #ifdef MPZ_TEST_DIV
  422.     fputs("mpz_divide:  div result", stderr);
  423.     mpz_div(&z->mpz, &a->mpz, &b->mpz);
  424.     mpz_out_str(stderr, 10, &z->mpz);
  425.     putc('\n', stderr);
  426. #endif /* def MPZ_TEST_DIV */
  427. #ifdef MPZ_MDIV_BUG
  428.     if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
  429.         != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)) {
  430.         /*
  431.         ** numerator has other sign than denominator: we have
  432.         ** to look at the remainder for a correction, since mpz_mdiv
  433.         ** also calls mpz_divmod, I can as well do it myself
  434.         */
  435.         MP_INT tmpmpz;
  436.  
  437.  
  438.         mpz_init(&tmpmpz);
  439.         mpz_divmod(&z->mpz, &tmpmpz, &a->mpz, &b->mpz);
  440.  
  441.         if (mpz_cmp_ui(&tmpmpz, (unsigned long int)0) != 0)
  442.             mpz_sub_ui(&z->mpz, &z->mpz, (unsigned long int)1);
  443.  
  444.         mpz_clear(&tmpmpz);
  445.     }
  446.     else
  447.         mpz_div(&z->mpz, &a->mpz, &b->mpz);
  448.         /* the ``naive'' implementation does it right for operands
  449.            having the same sign */
  450.  
  451. #else /* def MPZ_MDIV_BUG */
  452.     mpz_mdiv(&z->mpz, &a->mpz, &b->mpz);
  453. #endif /* def MPZ_MDIV_BUG else */
  454. #ifdef MPZ_TEST_DIV
  455.     fputs("mpz_divide: mdiv result", stderr);
  456.     mpz_out_str(stderr, 10, &z->mpz);
  457.     putc('\n', stderr);
  458. #endif /* def MPZ_TEST_DIV */
  459.     return (object *)z;
  460.     
  461. } /* mpz_divide() */
  462.  
  463. static object *
  464. mpz_remainder(a, b)
  465.     mpzobject *a;
  466.     mpzobject *b;
  467. {
  468. #ifdef MPZ_SPARE_MALLOC
  469.     int cmpres;
  470. #endif /* def MPZ_SPARE_MALLOC */    
  471.     mpzobject *z;
  472.  
  473.     
  474.     if ((
  475. #ifdef MPZ_SPARE_MALLOC         
  476.          cmpres =
  477. #endif /* def MPZ_SPARE_MALLOC */    
  478.          mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  479.         err_setstr(ZeroDivisionError, "mpz.% by zero");
  480.         return NULL;
  481.     }
  482. #ifdef MPZ_SPARE_MALLOC
  483.     if (cmpres > 0) {
  484.         if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)2)) == 0) {
  485.             INCREF(mpz_value_one);
  486.             return (object *)mpz_value_one;
  487.         }
  488.         if (cmpres < 0) {
  489.             /* b must be 1 now */
  490.             INCREF(mpz_value_zero);
  491.             return (object *)mpz_value_zero;
  492.         }
  493.     }
  494. #endif /* def MPZ_SPARE_MALLOC */    
  495.  
  496.     if ((z = newmpzobject()) == NULL)
  497.         return NULL;
  498.  
  499. #ifdef MPZ_TEST_DIV
  500.     fputs("mpz_remain:  mod result", stderr);
  501.     mpz_mod(&z->mpz, &a->mpz, &b->mpz);
  502.     mpz_out_str(stderr, 10, &z->mpz);
  503.     putc('\n', stderr);
  504. #endif /* def MPZ_TEST_DIV */
  505. #ifdef MPZ_MDIV_BUG
  506.  
  507.     /* the ``naive'' implementation does it right for operands
  508.        having the same sign */
  509.     mpz_mod(&z->mpz, &a->mpz, &b->mpz);
  510.  
  511.     /* assumption: z, a and b all point to different locations */
  512.     if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
  513.         != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
  514.         && mpz_cmp_ui(&z->mpz, (unsigned long int)0) != 0)
  515.         mpz_add(&z->mpz, &z->mpz, &b->mpz);
  516.         /*
  517.         ** numerator has other sign than denominator: we have
  518.         ** to look at the remainder for a correction, since mpz_mdiv
  519.         ** also calls mpz_divmod, I can as well do it myself
  520.         */
  521. #else /* def MPZ_MDIV_BUG */
  522.     mpz_mmod(&z->mpz, &a->mpz, &b->mpz);
  523. #endif /* def MPZ_MDIV_BUG else */
  524. #ifdef MPZ_TEST_DIV
  525.     fputs("mpz_remain: mmod result", stderr);
  526.     mpz_out_str(stderr, 10, &z->mpz);
  527.     putc('\n', stderr);
  528. #endif /* def MPZ_TEST_DIV */
  529.     return (object *)z;
  530.     
  531. } /* mpz_remainder() */
  532.  
  533. static object *
  534. mpz_div_and_mod(a, b)
  535.     mpzobject *a;
  536.     mpzobject *b;
  537. {
  538.     object *z = NULL;
  539.     mpzobject *x = NULL, *y = NULL;
  540.  
  541.  
  542.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0) == 0) {
  543.         err_setstr(ZeroDivisionError, "mpz.divmod by zero");
  544.         return NULL;
  545.     }
  546.  
  547.     if ((z = newtupleobject(2)) == NULL
  548.         || (x = newmpzobject()) == NULL
  549.         || (y = newmpzobject()) == NULL) {
  550.         XDECREF(z);
  551.         XDECREF(x);
  552.         XDECREF(y);
  553.         return NULL;
  554.     }
  555.  
  556. #ifdef MPZ_TEST_DIV
  557.     fputs("mpz_divmod:  dm  result", stderr);
  558.     mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
  559.     mpz_out_str(stderr, 10, &x->mpz);
  560.     putc('\n', stderr);
  561.     mpz_out_str(stderr, 10, &y->mpz);
  562.     putc('\n', stderr);
  563. #endif /* def MPZ_TEST_DIV */
  564. #ifdef MPZ_MDIV_BUG
  565.     mpz_divmod(&x->mpz, &y->mpz, &a->mpz, &b->mpz);
  566.     if ((mpz_cmp_ui(&a->mpz, (unsigned long int)0) < 0)
  567.         != (mpz_cmp_ui(&b->mpz, (unsigned long int)0) < 0)
  568.         && mpz_cmp_ui(&y->mpz, (unsigned long int)0) != 0) {
  569.         /*
  570.         ** numerator has other sign than denominator: we have
  571.         ** to look at the remainder for a correction.
  572.         */
  573.         mpz_add(&y->mpz, &y->mpz, &b->mpz);
  574.         mpz_sub_ui(&x->mpz, &x->mpz, (unsigned long int)1);
  575.     }
  576. #else /* def MPZ_MDIV_BUG */
  577.     mpz_mdivmod( &x->mpz, &y->mpz, &a->mpz, &b->mpz );
  578. #endif /* def MPZ_MDIV_BUG else */
  579. #ifdef MPZ_TEST_DIV
  580.     fputs("mpz_divmod: mdm  result", stderr);
  581.     mpz_out_str(stderr, 10, &x->mpz);
  582.     putc('\n', stderr);
  583.     mpz_out_str(stderr, 10, &y->mpz);
  584.     putc('\n', stderr);
  585. #endif /* def MPZ_TEST_DIV */
  586.  
  587.     (void)settupleitem(z, 0, (object *)x);
  588.     (void)settupleitem(z, 1, (object *)y);
  589.     
  590.     return z;
  591. } /* mpz_div_and_mod() */
  592.  
  593. static object *
  594. mpz_power(a, b, m)
  595.     mpzobject *a;
  596.     mpzobject *b;
  597.         mpzobject *m;
  598. {
  599.     mpzobject *z;
  600.     int cmpres;
  601.  
  602.      if ((object *)m!=Py_None)
  603.        {
  604.          mpzobject *z2;
  605.         INCREF(Py_None);
  606.          z=(mpzobject *)mpz_power(a, b, (mpzobject *)Py_None);
  607.         DECREF(Py_None);
  608.          if (z==NULL) return((object *)z);
  609.          z2=(mpzobject *)mpz_remainder(z, m);
  610.          DECREF(z);
  611.          return((object *)z2);
  612.        }        
  613.  
  614.     if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  615.         /* the gnu-mp lib sets pow(0,0) to 0, we to 1 */
  616.  
  617.         INCREF(mpz_value_one);
  618.         return (object *)mpz_value_one;
  619.     }
  620.         
  621.     if (cmpres < 0) {
  622.         err_setstr(ValueError, "mpz.pow to negative exponent");
  623.         return NULL;
  624.     }
  625.  
  626.     if ((cmpres = mpz_cmp_ui(&a->mpz, (unsigned long int)0)) == 0) {
  627.         /* the base is 0 */
  628.  
  629.         INCREF(mpz_value_zero);
  630.         return (object *)mpz_value_zero;
  631.     }
  632.     else if (cmpres > 0
  633.          && mpz_cmp_ui(&a->mpz, (unsigned long int)1) == 0) {
  634.         /* the base is 1 */
  635.  
  636.         INCREF(mpz_value_one);
  637.         return (object *)mpz_value_one;
  638.     }
  639.     else if (cmpres < 0
  640.          && mpz_cmp_si(&a->mpz, (long int)-1) == 0) {
  641.  
  642.         MP_INT tmpmpz;
  643.         /* the base is -1: pow(-1, any) == 1,-1 for even,uneven b */
  644.         /* XXX this code needs to be optimized: what's better?
  645.            mpz_mmod_ui or mpz_mod_2exp, I choose for the latter
  646.            for *un*obvious reasons */
  647.  
  648.         /* is the exponent even? */
  649.         mpz_init(&tmpmpz);
  650.  
  651.         /* look to the remainder after a division by (1 << 1) */
  652.         mpz_mod_2exp(&tmpmpz, &b->mpz, (unsigned long int)1);
  653.  
  654.         if (mpz_cmp_ui(&tmpmpz, (unsigned int)0) == 0) {
  655.             mpz_clear(&tmpmpz);
  656.             INCREF(mpz_value_one);
  657.             return (object *)mpz_value_one;
  658.         }
  659.         mpz_clear(&tmpmpz);
  660.         INCREF(mpz_value_mone);
  661.         return (object *)mpz_value_mone;
  662.     }
  663.  
  664. #ifdef MPZ_LIB_DOES_CHECKING
  665.     /* check if it's doable: sizeof(exp) > sizeof(long) &&
  666.        abs(base) > 1 ?? --> No Way */
  667.     if (mpz_size(&b->mpz) > 1)
  668.         return (object *)err_nomem();
  669. #else /* def MPZ_LIB_DOES_CHECKING */
  670.     /* wet finger method */
  671.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
  672.         err_setstr(ValueError, "mpz.pow outrageous exponent");
  673.         return NULL;
  674.     }
  675. #endif /* def MPZ_LIB_DOES_CHECKING else */
  676.  
  677.     if ((z = newmpzobject()) == NULL)
  678.         return NULL;
  679.     
  680.     mpz_pow_ui(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
  681.     
  682.     return (object *)z;
  683. } /* mpz_power() */
  684.  
  685.  
  686. static object *
  687. mpz_negative(v)
  688.     mpzobject *v;
  689. {
  690.     mpzobject *z;
  691.  
  692.     
  693. #ifdef MPZ_SPARE_MALLOC
  694.     if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) == 0) {
  695.         /* -0 == 0 */
  696.         INCREF(v);
  697.         return (object *)v;
  698.     }
  699. #endif /* def MPZ_SPARE_MALLOC */
  700.  
  701.     if ((z = newmpzobject()) == NULL)
  702.         return NULL;
  703.  
  704.     mpz_neg(&z->mpz, &v->mpz);
  705.     return (object *)z;
  706. } /* mpz_negative() */
  707.  
  708.  
  709. static object *
  710. mpz_positive(v)
  711.     mpzobject *v;
  712. {
  713.     INCREF(v);
  714.     return (object *)v;
  715. } /* mpz_positive() */
  716.  
  717.  
  718. static object *
  719. mpz_absolute(v)
  720.     mpzobject *v;
  721. {
  722.     mpzobject *z;
  723.  
  724.     
  725.     if (mpz_cmp_ui(&v->mpz, (unsigned long int)0) >= 0) {
  726.         INCREF(v);
  727.         return (object *)v;
  728.     }
  729.  
  730.     if ((z = newmpzobject()) == NULL)
  731.         return NULL;
  732.  
  733.     mpz_neg(&z->mpz, &v->mpz);
  734.     return (object *)z;
  735. } /* mpz_absolute() */
  736.  
  737. static int
  738. mpz_nonzero(v)
  739.     mpzobject *v;
  740. {
  741.     return mpz_cmp_ui(&v->mpz, (unsigned long int)0) != 0;
  742. } /* mpz_nonzero() */
  743.         
  744. static object *
  745. py_mpz_invert(v)
  746.     mpzobject *v;
  747. {
  748.     mpzobject *z;
  749.  
  750.  
  751.     /* I think mpz_com does exactly what needed */
  752.     if ((z = newmpzobject()) == NULL)
  753.         return NULL;
  754.  
  755.     mpz_com(&z->mpz, &v->mpz);
  756.     return (object *)z;
  757. } /* py_mpz_invert() */
  758.  
  759. static object *
  760. mpz_lshift(a, b)
  761.     mpzobject *a;
  762.     mpzobject *b;
  763. {
  764.     int cmpres;
  765.     mpzobject *z;
  766.  
  767.  
  768.     if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  769.         /* a << 0 == a */
  770.         INCREF(a);
  771.         return (object *)a;
  772.     }
  773.  
  774.     if (cmpres < 0) {
  775.         err_setstr(ValueError, "mpz.<< negative shift count");
  776.         return NULL;
  777.     }
  778.  
  779. #ifdef MPZ_LIB_DOES_CHECKING
  780.     if (mpz_size(&b->mpz) > 1)
  781.         return (object *)err_nomem();
  782. #else /* def MPZ_LIB_DOES_CHECKING */
  783.     /* wet finger method */
  784.     if (mpz_cmp_ui(&b->mpz, (unsigned long int)0x10000) >= 0) {
  785.         err_setstr(ValueError, "mpz.<< outrageous shift count");
  786.         return NULL;
  787.     }
  788. #endif /* def MPZ_LIB_DOES_CHECKING else */
  789.  
  790.     if ((z = newmpzobject()) == NULL)
  791.         return NULL;
  792.  
  793.     mpz_mul_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
  794.     return (object *)z;
  795. } /* mpz_lshift() */
  796.  
  797. static object *
  798. mpz_rshift(a, b)
  799.     mpzobject *a;
  800.     mpzobject *b;
  801. {
  802.     int cmpres;
  803.     mpzobject *z;
  804.  
  805.  
  806.     if ((cmpres = mpz_cmp_ui(&b->mpz, (unsigned long int)0)) == 0) {
  807.         /* a >> 0 == a */
  808.         INCREF(a);
  809.         return (object *)a;
  810.     }
  811.  
  812.     if (cmpres < 0) {
  813.         err_setstr(ValueError, "mpz.>> negative shift count");
  814.         return NULL;
  815.     }
  816.  
  817.     if (mpz_size(&b->mpz) > 1)
  818.         return (object *)err_nomem();
  819.  
  820.     if ((z = newmpzobject()) == NULL)
  821.         return NULL;
  822.  
  823.     mpz_div_2exp(&z->mpz, &a->mpz, mpz_get_ui(&b->mpz));
  824.     return (object *)z;
  825. } /* mpz_rshift() */
  826.  
  827. static object *
  828. mpz_andfunc(a, b)
  829.     mpzobject *a;
  830.     mpzobject *b;
  831. {
  832.     mpzobject *z;
  833.  
  834.  
  835.     if ((z = newmpzobject()) == NULL)
  836.         return NULL;
  837.  
  838.     mpz_and(&z->mpz, &a->mpz, &b->mpz);
  839.     return (object *)z;
  840. } /* mpz_andfunc() */
  841.  
  842. /* hack Hack HAck HACk HACK, XXX this code is dead slow */
  843. void
  844. mpz_xor(res, op1, op2)
  845.     MP_INT *res;
  846.     const MP_INT *op1;
  847.     const MP_INT *op2;
  848. {
  849.     MP_INT tmpmpz;
  850.     
  851.     mpz_init(&tmpmpz);
  852.  
  853.     mpz_and(res, op1, op2);
  854.     mpz_com(&tmpmpz, res);
  855.     mpz_ior(res, op1, op2);
  856.     mpz_and(res, res, &tmpmpz);
  857.  
  858.     mpz_clear(&tmpmpz);
  859. } /* mpz_xor() HACK */
  860.  
  861. static object *
  862. mpz_xorfunc(a, b)
  863.     mpzobject *a;
  864.     mpzobject *b;
  865. {
  866.     mpzobject *z;
  867.  
  868.  
  869.     if ((z = newmpzobject()) == NULL)
  870.         return NULL;
  871.  
  872.     mpz_xor(&z->mpz, &a->mpz, &b->mpz);
  873.     return (object *)z;
  874. } /* mpz_xorfunc() */
  875.  
  876. static object *
  877. mpz_orfunc(a, b)
  878.     mpzobject *a;
  879.     mpzobject *b;
  880. {
  881.     mpzobject *z;
  882.  
  883.  
  884.     if ((z = newmpzobject()) == NULL)
  885.         return NULL;
  886.  
  887.     mpz_ior(&z->mpz, &a->mpz, &b->mpz);
  888.     return (object *)z;
  889. } /* mpz_orfunc() */
  890.  
  891. /* MPZ initialisation */
  892.  
  893. #include "longintrepr.h"
  894.  
  895. static object *
  896. MPZ_mpz(self, args)
  897.     object *self;
  898.     object *args;
  899. {
  900.     mpzobject *mpzp;
  901.     object *objp;
  902.  
  903.  
  904. #ifdef MPZ_DEBUG
  905.     fputs("MPZ_mpz() called...\n", stderr);
  906. #endif /* def MPZ_DEBUG */
  907.  
  908.     if (!getargs(args, "O", &objp))
  909.         return NULL;
  910.  
  911.     /* at least we know it's some object */
  912.     /* note DON't DECREF args NEITHER objp */
  913.  
  914.     if (is_intobject(objp)) {
  915.         long lval;
  916.  
  917.         if (!getargs(objp, "l", &lval))
  918.             return NULL;
  919.         
  920.         if (lval == (long)0) {
  921.             INCREF(mpz_value_zero);
  922.             mpzp = mpz_value_zero;
  923.         }
  924.         else if (lval == (long)1) {
  925.             INCREF(mpz_value_one);
  926.             mpzp = mpz_value_one;
  927.         }            
  928.         else if ((mpzp = newmpzobject()) == NULL)
  929.             return NULL;
  930.         else mpz_set_si(&mpzp->mpz, lval);
  931.     }
  932.     else if (is_longobject(objp)) {
  933.         MP_INT mplongdigit;
  934.         int i;
  935.         unsigned char isnegative;
  936.         
  937.  
  938.         if ((mpzp = newmpzobject()) == NULL)
  939.             return NULL;
  940.  
  941.         mpz_set_si(&mpzp->mpz, 0L);
  942.         mpz_init(&mplongdigit);
  943.         
  944.         /* how we're gonna handle this? */
  945.         if ((isnegative = ((i = ((longobject *)objp)->ob_size) < 0) ))
  946.             i = -i;
  947.  
  948.         while (i--) {
  949.             mpz_set_ui(&mplongdigit,
  950.                    (unsigned long)
  951.                    ((longobject *)objp)->ob_digit[i]);
  952.             mpz_mul_2exp(&mplongdigit,&mplongdigit,
  953.                      (unsigned long int)i * SHIFT);
  954.             mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
  955.         }
  956.  
  957.         if (isnegative)
  958.             mpz_neg(&mpzp->mpz, &mpzp->mpz);
  959.  
  960.         /* get rid of allocation for tmp variable */
  961.         mpz_clear(&mplongdigit);
  962.     }
  963.     else if (is_stringobject(objp)) {
  964.         char *cp;
  965.         int len;
  966.         MP_INT mplongdigit;
  967.         
  968.         if (!getargs(objp, "s#", &cp, &len))
  969.             return NULL;
  970.  
  971.         if ((mpzp = newmpzobject()) == NULL)
  972.             return NULL;
  973.  
  974.         mpz_set_si(&mpzp->mpz, 0L);
  975.         mpz_init(&mplongdigit);
  976.         
  977.         /* let's do it the same way as with the long conversion:
  978.            without thinking how it can be faster (-: :-) */
  979.  
  980.         cp += len;
  981.         while (len--) {
  982.             mpz_set_ui(&mplongdigit, (unsigned long)*--cp );
  983.             mpz_mul_2exp(&mplongdigit,&mplongdigit,
  984.                      (unsigned long int)len * 8);
  985.             mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
  986.         }
  987.  
  988.         /* get rid of allocation for tmp variable */
  989.         mpz_clear(&mplongdigit);
  990.     }
  991.     else if (is_mpzobject(objp)) {
  992.         INCREF(objp);
  993.         mpzp = (mpzobject *)objp;
  994.     }
  995.     else {
  996.         err_setstr(TypeError,
  997.                "mpz.mpz() expects integer, long, string or mpz object argument");
  998.         return NULL;
  999.     }
  1000.  
  1001.  
  1002. #ifdef MPZ_DEBUG
  1003.     fputs("MPZ_mpz: created mpz=", stderr);
  1004.     mpz_out_str(stderr, 10, &mpzp->mpz);
  1005.     putc('\n', stderr);
  1006. #endif /* def MPZ_DEBUG */
  1007.     return (object *)mpzp;
  1008. } /* MPZ_mpz() */
  1009.  
  1010. static mpzobject *
  1011. mpz_mpzcoerce(z)
  1012.     object *z;
  1013. {
  1014.     /* shortcut: 9 out of 10 times the type is already ok */
  1015.     if (is_mpzobject(z)) {
  1016.         INCREF(z);
  1017.         return (mpzobject *)z;    /* coercion succeeded */
  1018.     }
  1019.  
  1020.     /* what types do we accept?: intobjects and longobjects */
  1021.     if (is_intobject(z) || is_longobject(z))
  1022.         return (mpzobject *)MPZ_mpz((object *)NULL, z);
  1023.  
  1024.     err_setstr(TypeError, "number coercion (to mpzobject) failed");
  1025.     return NULL;
  1026. } /* mpz_mpzcoerce() */
  1027.     
  1028. /* Forward */
  1029. static void mpz_divm PROTO((MP_INT *res, const MP_INT *num,
  1030.                 const MP_INT *den, const MP_INT *mod));
  1031.  
  1032. static object *
  1033. MPZ_powm(self, args)
  1034.     object *self;
  1035.     object *args;
  1036. {
  1037.     object *base, *exp, *mod;
  1038.     mpzobject *mpzbase = NULL, *mpzexp = NULL, *mpzmod = NULL;
  1039.     mpzobject *z;
  1040.     int tstres;
  1041.  
  1042.     
  1043.     if (!getargs(args, "(OOO)", &base, &exp, &mod))
  1044.         return NULL;
  1045.  
  1046.     if ((mpzbase = mpz_mpzcoerce(base)) == NULL
  1047.         || (mpzexp = mpz_mpzcoerce(exp)) == NULL
  1048.         || (mpzmod = mpz_mpzcoerce(mod)) == NULL
  1049.         || (z = newmpzobject()) == NULL) {
  1050.         XDECREF(mpzbase);
  1051.         XDECREF(mpzexp);
  1052.         XDECREF(mpzmod);
  1053.         return NULL;
  1054.     }
  1055.  
  1056.     if ((tstres=mpz_cmp_ui(&mpzexp->mpz, (unsigned long int)0)) == 0) {
  1057.         INCREF(mpz_value_one);
  1058.         return (object *)mpz_value_one;
  1059.     }
  1060.  
  1061.     if (tstres < 0) {
  1062.         MP_INT absexp;
  1063.         /* negative exp */
  1064.  
  1065.         mpz_init_set(&absexp, &mpzexp->mpz);
  1066.         mpz_abs(&absexp, &absexp);
  1067.         mpz_powm(&z->mpz, &mpzbase->mpz, &absexp, &mpzmod->mpz);
  1068.  
  1069.         mpz_divm(&z->mpz, &mpz_value_one->mpz, &z->mpz, &mpzmod->mpz);
  1070.         
  1071.         mpz_clear(&absexp);
  1072.     }
  1073.     else {
  1074.         mpz_powm(&z->mpz, &mpzbase->mpz, &mpzexp->mpz, &mpzmod->mpz);
  1075.     }
  1076.         
  1077.     DECREF(mpzbase);
  1078.     DECREF(mpzexp);
  1079.     DECREF(mpzmod);
  1080.  
  1081.     return (object *)z;
  1082. } /* MPZ_powm() */
  1083.  
  1084.  
  1085. static object *
  1086. MPZ_gcd(self, args)
  1087.     object *self;
  1088.     object *args;
  1089. {
  1090.     object *op1, *op2;
  1091.     mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
  1092.     mpzobject *z;
  1093.  
  1094.     
  1095.     if (!getargs(args, "(OO)", &op1, &op2))
  1096.         return NULL;
  1097.  
  1098.     if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
  1099.         || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
  1100.         || (z = newmpzobject()) == NULL) {
  1101.         XDECREF(mpzop1);
  1102.         XDECREF(mpzop2);
  1103.         return NULL;
  1104.     }
  1105.  
  1106.     /* ok, we have three mpzobjects, and an initialised result holder */
  1107.     mpz_gcd(&z->mpz, &mpzop1->mpz, &mpzop2->mpz);
  1108.  
  1109.     DECREF(mpzop1);
  1110.     DECREF(mpzop2);
  1111.  
  1112.     return (object *)z;
  1113. } /* MPZ_gcd() */
  1114.  
  1115.  
  1116. static object *
  1117. MPZ_gcdext(self, args)
  1118.     object *self;
  1119.     object *args;
  1120. {
  1121.     object *op1, *op2, *z = NULL;
  1122.     mpzobject *mpzop1 = NULL, *mpzop2 = NULL;
  1123.     mpzobject *g = NULL, *s = NULL, *t = NULL;
  1124.  
  1125.     
  1126.     if (!getargs(args, "(OO)", &op1, &op2))
  1127.         return NULL;
  1128.  
  1129.     if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
  1130.         || (mpzop2 = mpz_mpzcoerce(op2)) == NULL
  1131.         || (z = newtupleobject(3)) == NULL
  1132.         || (g = newmpzobject()) == NULL
  1133.         || (s = newmpzobject()) == NULL
  1134.         || (t = newmpzobject()) == NULL) {
  1135.         XDECREF(mpzop1);
  1136.         XDECREF(mpzop2);
  1137.         XDECREF(z);
  1138.         XDECREF(g);
  1139.         XDECREF(s);
  1140.         /*XDECREF(t);*/
  1141.         return NULL;
  1142.     }
  1143.  
  1144.     mpz_gcdext(&g->mpz, &s->mpz, &t->mpz, &mpzop1->mpz, &mpzop2->mpz);
  1145.  
  1146.     DECREF(mpzop1);
  1147.     DECREF(mpzop2);
  1148.  
  1149.     (void)settupleitem(z, 0, (object *)g);
  1150.     (void)settupleitem(z, 1, (object *)s);
  1151.     (void)settupleitem(z, 2, (object *)t);
  1152.  
  1153.     return (object *)z;
  1154. } /* MPZ_gcdext() */
  1155.  
  1156.  
  1157. static object *
  1158. MPZ_sqrt(self, args)
  1159.     object *self;
  1160.     object *args;
  1161. {
  1162.     object *op;
  1163.     mpzobject *mpzop = NULL;
  1164.     mpzobject *z;
  1165.  
  1166.     
  1167.     if (!getargs(args, "O", &op))
  1168.         return NULL;
  1169.  
  1170.     if ((mpzop = mpz_mpzcoerce(op)) == NULL
  1171.         || (z = newmpzobject()) == NULL) {
  1172.         XDECREF(mpzop);
  1173.         return NULL;
  1174.     }
  1175.  
  1176.     mpz_sqrt(&z->mpz, &mpzop->mpz);
  1177.  
  1178.     DECREF(mpzop);
  1179.  
  1180.     return (object *)z;
  1181. } /* MPZ_sqrt() */
  1182.  
  1183.  
  1184. static object *
  1185. MPZ_sqrtrem(self, args)
  1186.     object *self;
  1187.     object *args;
  1188. {
  1189.     object *op, *z = NULL;
  1190.     mpzobject *mpzop = NULL;
  1191.     mpzobject *root = NULL, *rem = NULL;
  1192.  
  1193.     
  1194.     if (!getargs(args, "O", &op))
  1195.         return NULL;
  1196.  
  1197.     if ((mpzop = mpz_mpzcoerce(op)) == NULL
  1198.         || (z = newtupleobject(2)) == NULL
  1199.         || (root = newmpzobject()) == NULL
  1200.         || (rem = newmpzobject()) == NULL) {
  1201.         XDECREF(mpzop);
  1202.         XDECREF(z);
  1203.         XDECREF(root);
  1204.         /*XDECREF(rem);*/
  1205.         return NULL;
  1206.     }
  1207.  
  1208.     mpz_sqrtrem(&root->mpz, &rem->mpz, &mpzop->mpz);
  1209.  
  1210.     DECREF(mpzop);
  1211.  
  1212.     (void)settupleitem(z, 0, (object *)root);
  1213.     (void)settupleitem(z, 1, (object *)rem);
  1214.  
  1215.     return (object *)z;
  1216. } /* MPZ_sqrtrem() */
  1217.  
  1218.  
  1219. static void
  1220. #if __STDC__
  1221. mpz_divm(MP_INT *res, const MP_INT *num, const MP_INT *den, const MP_INT *mod)
  1222. #else
  1223. mpz_divm(res, num, den, mod)
  1224.     MP_INT *res;
  1225.     const MP_INT *num;
  1226.     const MP_INT *den;
  1227.     const MP_INT *mod;
  1228. #endif
  1229. {
  1230.     MP_INT s0, s1, q, r, x, d0, d1;
  1231.  
  1232.     mpz_init_set(&s0, num);
  1233.     mpz_init_set_ui(&s1, 0);
  1234.     mpz_init(&q);
  1235.     mpz_init(&r);
  1236.     mpz_init(&x);
  1237.     mpz_init_set(&d0, den);
  1238.     mpz_init_set(&d1, mod);
  1239.  
  1240. #ifdef GMP2
  1241.     while (d1._mp_size != 0) {
  1242. #else
  1243.     while (d1.size != 0) {
  1244. #endif
  1245.         mpz_divmod(&q, &r, &d0, &d1);
  1246.         mpz_set(&d0, &d1);
  1247.         mpz_set(&d1, &r);
  1248.  
  1249.         mpz_mul(&x, &s1, &q);
  1250.         mpz_sub(&x, &s0, &x);
  1251.         mpz_set(&s0, &s1);
  1252.         mpz_set(&s1, &x);
  1253.     }
  1254.  
  1255. #ifdef GMP2
  1256.     if (d0._mp_size != 1 || d0._mp_d[0] != 1)
  1257.         res->_mp_size = 0; /* trouble: the gcd != 1; set s to zero */
  1258. #else
  1259.     if (d0.size != 1 || d0.d[0] != 1)
  1260.         res->size = 0;    /* trouble: the gcd != 1; set s to zero */
  1261. #endif
  1262.     else {
  1263. #ifdef MPZ_MDIV_BUG
  1264.         /* watch out here! first check the signs, and then perform
  1265.            the mpz_mod() since mod could point to res */
  1266.         if ((s0.size < 0) != (mod->size < 0)) {
  1267.             mpz_mod(res, &s0, mod);
  1268.  
  1269.             if (res->size)
  1270.                 mpz_add(res, res, mod);
  1271.         }
  1272.         else
  1273.             mpz_mod(res, &s0, mod);
  1274.         
  1275. #else /* def MPZ_MDIV_BUG */
  1276.         mpz_mmod(res, &s0, mod);
  1277. #endif /* def MPZ_MDIV_BUG else */
  1278.     }
  1279.  
  1280.     mpz_clear(&s0);
  1281.     mpz_clear(&s1);
  1282.     mpz_clear(&q);
  1283.     mpz_clear(&r);
  1284.     mpz_clear(&x);
  1285.     mpz_clear(&d0);
  1286.     mpz_clear(&d1);
  1287. } /* mpz_divm() */
  1288.  
  1289.  
  1290. static object *
  1291. MPZ_divm(self, args)
  1292.     object *self;
  1293.     object *args;
  1294. {
  1295.     object *num, *den, *mod;
  1296.     mpzobject *mpznum, *mpzden, *mpzmod = NULL;
  1297.     mpzobject *z = NULL;
  1298.  
  1299.     
  1300.     if (!getargs(args, "(OOO)", &num, &den, &mod))
  1301.         return NULL;
  1302.  
  1303.     if ((mpznum = mpz_mpzcoerce(num)) == NULL
  1304.         || (mpzden = mpz_mpzcoerce(den)) == NULL
  1305.         || (mpzmod = mpz_mpzcoerce(mod)) == NULL
  1306.         || (z = newmpzobject()) == NULL ) {
  1307.         XDECREF(mpznum);
  1308.         XDECREF(mpzden);
  1309.         XDECREF(mpzmod);
  1310.         return NULL;
  1311.     }
  1312.     
  1313.     mpz_divm(&z->mpz, &mpznum->mpz, &mpzden->mpz, &mpzmod->mpz);
  1314.  
  1315.     DECREF(mpznum);
  1316.     DECREF(mpzden);
  1317.     DECREF(mpzmod);
  1318.  
  1319.     if (mpz_cmp_ui(&z->mpz, (unsigned long int)0) == 0) {
  1320.         DECREF(z);
  1321.         err_setstr(ValueError, "gcd(den, mod) != 1 or num == 0");
  1322.         return NULL;
  1323.     }
  1324.  
  1325.     return (object *)z;
  1326. } /* MPZ_divm() */
  1327.  
  1328.  
  1329. /* MPZ methods-as-attributes */
  1330. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1331. static object *
  1332. mpz_int(self, args)
  1333.     mpzobject *self;
  1334.     object *args;
  1335. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1336. static object *
  1337. mpz_int(self)
  1338.     mpzobject *self;
  1339. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1340. {
  1341.     long sli;
  1342.  
  1343.  
  1344. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1345.     if (!getnoarg(args))
  1346.         return NULL;
  1347. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1348.  
  1349.     if (mpz_size(&self->mpz) > 1
  1350.         || (sli = (long)mpz_get_ui(&self->mpz)) < (long)0 ) {
  1351.         err_setstr(ValueError, "mpz.int() arg too long to convert");
  1352.         return NULL;
  1353.     }
  1354.  
  1355.     if (mpz_cmp_ui(&self->mpz, (unsigned long)0) < 0)
  1356.         sli = -sli;
  1357.  
  1358.     return newintobject(sli);
  1359. } /* mpz_int() */
  1360.     
  1361. static object *
  1362. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1363. mpz_long(self, args)
  1364.     mpzobject *self;
  1365.     object *args;
  1366. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1367. mpz_long(self)
  1368.     mpzobject *self;
  1369. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1370. {
  1371.     int i, isnegative;
  1372.     unsigned long int uli;
  1373.     longobject *longobjp;
  1374.     int ldcount;
  1375.     int bitpointer, newbitpointer;
  1376.     MP_INT mpzscratch;
  1377.  
  1378.  
  1379. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1380.     if (!getnoarg(args))
  1381.         return NULL;
  1382. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1383.  
  1384.     /* determine length of python-long to be allocated */
  1385.     if ((longobjp = alloclongobject(i = (int)
  1386.                 ((mpz_size(&self->mpz) * BITS_PER_MP_LIMB
  1387.                   + SHIFT - 1) /
  1388.                  SHIFT))) == NULL)
  1389.         return NULL;
  1390.  
  1391.     /* determine sign, and copy self to scratch var */
  1392.     mpz_init_set(&mpzscratch, &self->mpz);
  1393.     if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0)))
  1394.         mpz_neg(&mpzscratch, &mpzscratch);
  1395.  
  1396.     /* let those bits come, let those bits go,
  1397.        e.g. dismantle mpzscratch, build longobject */
  1398.  
  1399.     bitpointer = 0;        /* the number of valid bits in stock */
  1400.     newbitpointer = 0;
  1401.     ldcount = 0;        /* the python-long limb counter */
  1402.     uli = (unsigned long int)0;
  1403.     while (i--) {
  1404.         longobjp->ob_digit[ldcount] = uli & MASK;
  1405.  
  1406.         /* check if we've had enough bits for this digit */
  1407.         if (bitpointer < SHIFT) {
  1408.             uli = mpz_get_ui(&mpzscratch);
  1409.             longobjp->ob_digit[ldcount] |=
  1410.                 (uli << bitpointer) & MASK;
  1411.             uli >>= SHIFT-bitpointer;
  1412.             bitpointer += BITS_PER_MP_LIMB;
  1413.             mpz_div_2exp(&mpzscratch, &mpzscratch,
  1414.                      BITS_PER_MP_LIMB);
  1415.         }
  1416.         else
  1417.             uli >>= SHIFT;
  1418.         bitpointer -= SHIFT;
  1419.         ldcount++;
  1420.     }
  1421.  
  1422.     assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
  1423.     mpz_clear(&mpzscratch);
  1424.     assert(ldcount <= longobjp->ob_size);
  1425.  
  1426.     /* long_normalize() is file-static */
  1427.     /* longobjp = long_normalize(longobjp); */
  1428.     while (ldcount > 0 && longobjp->ob_digit[ldcount-1] == 0)
  1429.         ldcount--;
  1430.     longobjp->ob_size = ldcount;
  1431.     
  1432.  
  1433.     if (isnegative)
  1434.         longobjp->ob_size = -longobjp->ob_size;
  1435.  
  1436.     return (object *)longobjp;
  1437.     
  1438. } /* mpz_long() */
  1439.  
  1440.  
  1441. /* I would have avoided pow() anyways, so ... */
  1442. static const double multiplier = 256.0 * 256.0 * 256.0 * 256.0;
  1443.     
  1444. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1445. static object *
  1446. mpz_float(self, args)
  1447.     mpzobject *self;
  1448.     object *args;
  1449. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1450. static object *
  1451. mpz_float(self)
  1452.     mpzobject *self;
  1453. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1454. {
  1455.     int i, isnegative;
  1456.     double x;
  1457.     double mulstate;
  1458.     MP_INT mpzscratch;
  1459.  
  1460.  
  1461. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1462.     if (!getnoarg(args))
  1463.         return NULL;
  1464. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1465.  
  1466.     i = (int)mpz_size(&self->mpz);
  1467.     
  1468.     /* determine sign, and copy abs(self) to scratch var */
  1469.     if ((isnegative = (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0))) {
  1470.         mpz_init(&mpzscratch);
  1471.         mpz_neg(&mpzscratch, &self->mpz);
  1472.     }
  1473.     else
  1474.         mpz_init_set(&mpzscratch, &self->mpz);
  1475.  
  1476.     /* let those bits come, let those bits go,
  1477.        e.g. dismantle mpzscratch, build floatobject */
  1478.  
  1479.     x = 0.0;
  1480.     mulstate = 1.0;
  1481.     while (i--) {
  1482.         x += mulstate * mpz_get_ui(&mpzscratch);
  1483.         mulstate *= multiplier;
  1484.         mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
  1485.     }
  1486.  
  1487.     assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
  1488.     mpz_clear(&mpzscratch);
  1489.  
  1490.     if (isnegative)
  1491.         x = -x;
  1492.  
  1493.     return newfloatobject(x);
  1494.     
  1495. } /* mpz_float() */
  1496.  
  1497. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1498. static object *
  1499. mpz_hex(self, args)
  1500.     mpzobject *self;
  1501.     object *args;
  1502. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1503. static object *
  1504. mpz_hex(self)
  1505.     mpzobject *self;
  1506. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1507. {
  1508. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1509.     if (!getnoarg(args))
  1510.         return NULL;
  1511. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1512.     
  1513.     return mpz_format(self, 16, (unsigned char)1);
  1514. } /* mpz_hex() */
  1515.     
  1516. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1517. static object *
  1518. mpz_oct(self, args)
  1519.     mpzobject *self;
  1520.     object *args;
  1521. #else /* def MPZ_CONVERSIONS_AS_METHODS */
  1522. static object *
  1523. mpz_oct(self)
  1524.     mpzobject *self;
  1525. #endif /* def MPZ_CONVERSIONS_AS_METHODS else */
  1526. {
  1527. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1528.     if (!getnoarg(args))
  1529.         return NULL;
  1530. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1531.     
  1532.     return mpz_format(self, 8, (unsigned char)1);
  1533. } /* mpz_oct() */
  1534.     
  1535. static object *
  1536. mpz_binary(self, args)
  1537.     mpzobject *self;
  1538.     object *args;
  1539. {
  1540.     int size;
  1541.     stringobject *strobjp;
  1542.     char *cp;
  1543.     MP_INT mp;
  1544.     unsigned long ldigit;
  1545.     
  1546.     if (!getnoarg(args))
  1547.         return NULL;
  1548.  
  1549.     if (mpz_cmp_ui(&self->mpz, (unsigned long int)0) < 0) {
  1550.         err_setstr(ValueError, "mpz.binary() arg must be >= 0");
  1551.         return NULL;
  1552.     }
  1553.  
  1554.     mpz_init_set(&mp, &self->mpz);
  1555.     size = (int)mpz_size(&mp);
  1556.  
  1557.     if ((strobjp = (stringobject *)
  1558.          newsizedstringobject((char *)0,
  1559.                   size * sizeof (unsigned long int))) == NULL)
  1560.         return NULL;
  1561.  
  1562.     /* get the beginning of the string memory and start copying things */
  1563.     cp = GETSTRINGVALUE(strobjp);
  1564.  
  1565.     /* this has been programmed using a (fairly) decent lib-i/f it could
  1566.        be must faster if we looked into the GMP lib */
  1567.     while (size--) {
  1568.         ldigit = mpz_get_ui(&mp);
  1569.         mpz_div_2exp(&mp, &mp, BITS_PER_MP_LIMB);
  1570.         *cp++ = (unsigned char)(ldigit & 0xFF);
  1571.         *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
  1572.         *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
  1573.         *cp++ = (unsigned char)((ldigit >>= 8) & 0xFF);
  1574.     }
  1575.  
  1576.     while (strobjp->ob_size && !*--cp)
  1577.         strobjp->ob_size--;
  1578.  
  1579.     return (object *)strobjp;
  1580. } /* mpz_binary() */
  1581.     
  1582.  
  1583. static struct methodlist mpz_methods[] = {
  1584. #ifdef MPZ_CONVERSIONS_AS_METHODS
  1585.     {"int",            mpz_int},
  1586.     {"long",        mpz_long},
  1587.     {"float",        mpz_float},
  1588.     {"hex",            mpz_hex},
  1589.     {"oct",            mpz_oct},
  1590. #endif /* def MPZ_CONVERSIONS_AS_METHODS */
  1591.     {"binary",        (object *(*)(object *, object *))mpz_binary},
  1592.     {NULL,            NULL}        /* sentinel */
  1593. };
  1594.  
  1595. static object *
  1596. mpz_getattr(self, name)
  1597.     mpzobject *self;
  1598.     char *name;
  1599. {
  1600.     return findmethod(mpz_methods, (object *)self, name);
  1601. } /* mpz_getattr() */
  1602.  
  1603.  
  1604. static int
  1605. mpz_coerce(pv, pw)
  1606.     object **pv;
  1607.     object **pw;
  1608. {
  1609.     object *z;
  1610.  
  1611. #ifdef MPZ_DEBUG
  1612.     fputs("mpz_coerce() called...\n", stderr);
  1613. #endif /* def MPZ_DEBUG */
  1614.  
  1615.     assert(is_mpzobject(*pv));
  1616.  
  1617.     /* always convert other arg to mpz value, except for floats */
  1618.     if (!is_floatobject(*pw)) {
  1619.         if ((z = (object *)mpz_mpzcoerce(*pw)) == NULL)
  1620.             return -1;    /* -1: an error always has been set */
  1621.         
  1622.         INCREF(*pv);
  1623.         *pw = z;
  1624.     }
  1625.     else {
  1626.         if ((z = mpz_float(*pv, NULL)) == NULL)
  1627.             return -1;
  1628.  
  1629.         INCREF(*pw);
  1630.         *pv = z;
  1631.     }
  1632.     return 0;        /* coercion succeeded */
  1633.  
  1634. } /* mpz_coerce() */
  1635.  
  1636.  
  1637. static object *
  1638. mpz_repr(v)
  1639.     object *v;
  1640. {
  1641.     return mpz_format(v, 10, (unsigned char)1);
  1642. } /* mpz_repr() */
  1643.  
  1644.  
  1645.  
  1646. #define UF (unaryfunc)
  1647. #define BF (binaryfunc)
  1648. #define TF (ternaryfunc)
  1649. #define IF (inquiry)
  1650. #define CF (coercion)
  1651.  
  1652. static number_methods mpz_as_number = {
  1653.     BF mpz_addition,    /*nb_add*/
  1654.     BF mpz_substract,    /*nb_subtract*/
  1655.     BF mpz_multiply,    /*nb_multiply*/
  1656.     BF mpz_divide,        /*nb_divide*/
  1657.     BF mpz_remainder,    /*nb_remainder*/
  1658.     BF mpz_div_and_mod,    /*nb_divmod*/
  1659.     TF mpz_power,        /*nb_power*/
  1660.     UF mpz_negative,    /*nb_negative*/
  1661.     UF mpz_positive,    /*tp_positive*/
  1662.     UF mpz_absolute,    /*tp_absolute*/
  1663.     IF mpz_nonzero,        /*tp_nonzero*/
  1664.     UF py_mpz_invert,    /*nb_invert*/
  1665.     BF mpz_lshift,        /*nb_lshift*/
  1666.     BF mpz_rshift,        /*nb_rshift*/
  1667.     BF mpz_andfunc,        /*nb_and*/
  1668.     BF mpz_xorfunc,        /*nb_xor*/
  1669.     BF mpz_orfunc,        /*nb_or*/
  1670.     CF mpz_coerce,        /*nb_coerce*/
  1671. #ifndef MPZ_CONVERSIONS_AS_METHODS
  1672.     UF mpz_int,        /*nb_int*/
  1673.     UF mpz_long,        /*nb_long*/
  1674.     UF mpz_float,        /*nb_float*/
  1675.     UF mpz_oct,        /*nb_oct*/
  1676.     UF mpz_hex,        /*nb_hex*/
  1677. #endif /* ndef MPZ_CONVERSIONS_AS_METHODS */
  1678. };
  1679.  
  1680. static typeobject MPZtype = {
  1681.     OB_HEAD_INIT(&Typetype)
  1682.     0,            /*ob_size*/
  1683.     "mpz",            /*tp_name*/
  1684.     sizeof(mpzobject),    /*tp_size*/
  1685.     0,            /*tp_itemsize*/
  1686.     /* methods */
  1687.     (destructor)mpz_dealloc, /*tp_dealloc*/
  1688.     0,            /*tp_print*/
  1689.     (getattrfunc)mpz_getattr, /*tp_getattr*/
  1690.     0,            /*tp_setattr*/
  1691.     (cmpfunc)mpz_compare,    /*tp_compare*/
  1692.     (reprfunc)mpz_repr,    /*tp_repr*/
  1693.         &mpz_as_number,     /*tp_as_number*/
  1694. };
  1695.  
  1696. /* List of functions exported by this module */
  1697.  
  1698. static struct methodlist mpz_functions[] = {
  1699. #if 0
  1700.     {initialiser_name,    MPZ_mpz},
  1701. #else /* 0 */
  1702.     /* until guido ``fixes'' struct methodlist */
  1703.     {(char *)initialiser_name,    MPZ_mpz},
  1704. #endif /* 0 else */    
  1705.     {"powm",        MPZ_powm},
  1706.     {"gcd",            MPZ_gcd},
  1707.     {"gcdext",        MPZ_gcdext},
  1708.     {"sqrt",        MPZ_sqrt},
  1709.     {"sqrtrem",        MPZ_sqrtrem},
  1710.     {"divm",        MPZ_divm},
  1711.     {NULL,            NULL}         /* Sentinel */
  1712. };
  1713.  
  1714.  
  1715. /* #define MP_TEST_ALLOC */
  1716.  
  1717. #ifdef MP_TEST_ALLOC
  1718. #define MP_TEST_SIZE        4
  1719. static const char mp_test_magic[MP_TEST_SIZE] = {'\xAA','\xAA','\xAA','\xAA'};
  1720. static mp_test_error( location )
  1721.     int *location;
  1722. {
  1723.     /* assumptions: *alloc returns address dividable by 4,
  1724.     mpz_* routines allocate in chunks dividable by four */
  1725.     fprintf(stderr, "MP_TEST_ERROR: location holds 0x%08d\n", *location );
  1726.     fatal("MP_TEST_ERROR");
  1727. } /* static mp_test_error() */
  1728. #define MP_EXTRA_ALLOC(size)    ((size) + MP_TEST_SIZE)
  1729. #define MP_SET_TEST(basep,size)    (void)memcpy( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE)
  1730. #define MP_DO_TEST(basep,size)    if ( !memcmp( ((char *)(basep))+(size), mp_test_magic, MP_TEST_SIZE ) ) \
  1731.                     ; \
  1732.                 else \
  1733.                     mp_test_error((int *)((char *)(basep) + size))
  1734. #else /* def MP_TEST_ALLOC */
  1735. #define MP_EXTRA_ALLOC(size)    (size)
  1736. #define MP_SET_TEST(basep,size)
  1737. #define MP_DO_TEST(basep,size)
  1738. #endif /* def MP_TEST_ALLOC else */
  1739.  
  1740. void *mp_allocate( alloc_size )
  1741.     size_t    alloc_size;
  1742. {
  1743.     void *res;
  1744.  
  1745. #ifdef MPZ_DEBUG
  1746.     fprintf(stderr, "mp_allocate  :                             size %ld\n",
  1747.         alloc_size);
  1748. #endif /* def MPZ_DEBUG */    
  1749.  
  1750.     if ( (res = malloc(MP_EXTRA_ALLOC(alloc_size))) == NULL )
  1751.         fatal("mp_allocate failure");
  1752.  
  1753. #ifdef MPZ_DEBUG
  1754.     fprintf(stderr, "mp_allocate  :     address 0x%08x\n", res);
  1755. #endif /* def MPZ_DEBUG */    
  1756.  
  1757.     MP_SET_TEST(res,alloc_size);
  1758.     
  1759.     return res;
  1760. } /* mp_allocate() */
  1761.  
  1762.  
  1763. void *mp_reallocate( ptr, old_size, new_size )
  1764.     void *ptr;
  1765.     size_t old_size;
  1766.     size_t new_size;
  1767. {
  1768.     void *res;
  1769.  
  1770. #ifdef MPZ_DEBUG
  1771.     fprintf(stderr, "mp_reallocate: old address 0x%08x, old size %ld\n",
  1772.         ptr, old_size);
  1773. #endif /* def MPZ_DEBUG */    
  1774.  
  1775.     MP_DO_TEST(ptr, old_size);
  1776.     
  1777.     if ( (res = realloc(ptr, MP_EXTRA_ALLOC(new_size))) == NULL )
  1778.         fatal("mp_reallocate failure");
  1779.  
  1780. #ifdef MPZ_DEBUG
  1781.     fprintf(stderr, "mp_reallocate: new address 0x%08x, new size %ld\n",
  1782.         res, new_size);
  1783. #endif /* def MPZ_DEBUG */    
  1784.  
  1785.     MP_SET_TEST(res, new_size);
  1786.  
  1787.     return res;
  1788. } /* mp_reallocate() */
  1789.  
  1790.  
  1791. void mp_free( ptr, size )
  1792.     void *ptr;
  1793.     size_t size;
  1794. {
  1795.  
  1796. #ifdef MPZ_DEBUG
  1797.     fprintf(stderr, "mp_free      : old address 0x%08x, old size %ld\n",
  1798.         ptr, size);
  1799. #endif /* def MPZ_DEBUG */    
  1800.  
  1801.     MP_DO_TEST(ptr, size);
  1802.     free(ptr);
  1803. } /* mp_free() */
  1804.  
  1805.  
  1806.  
  1807. /* Initialize this module. */
  1808.  
  1809. void
  1810. initmpz()
  1811. {
  1812. #ifdef MPZ_DEBUG
  1813.     fputs( "initmpz() called...\n", stderr );
  1814. #endif /* def MPZ_DEBUG */
  1815.  
  1816.     mp_set_memory_functions( mp_allocate, mp_reallocate, mp_free );
  1817.     (void)initmodule("mpz", mpz_functions);
  1818.  
  1819.     /* create some frequently used constants */
  1820.     if ((mpz_value_zero = newmpzobject()) == NULL)
  1821.         fatal("initmpz: can't initialize mpz constants");
  1822.     mpz_set_ui(&mpz_value_zero->mpz, (unsigned long int)0);
  1823.  
  1824.     if ((mpz_value_one = newmpzobject()) == NULL)
  1825.         fatal("initmpz: can't initialize mpz constants");
  1826.     mpz_set_ui(&mpz_value_one->mpz, (unsigned long int)1);
  1827.  
  1828.     if ((mpz_value_mone = newmpzobject()) == NULL)
  1829.         fatal("initmpz: can't initialize mpz constants");
  1830.     mpz_set_si(&mpz_value_mone->mpz, (long)-1);
  1831.  
  1832. } /* initmpz() */
  1833. #ifdef MAKEDUMMYINT
  1834. int _mpz_dummy_int;    /* XXX otherwise, we're .bss-less (DYNLOAD->Jack?) */
  1835. #endif /* def MAKEDUMMYINT */
  1836.