--- gmpmodule-0.91/gmpmodule.c Wed May 29 05:13:16 1996 +++ gmpmodule-0.92/gmpmodule.c Wed Jun 5 18:17:58 1996 @@ -306,7 +306,7 @@ } mpz_clear(temp); s = PyString_FromStringAndSize(buffer, size); -#ifndef USA_ALLOCA +#ifndef USE_ALLOCA free(buffer); #endif return s; @@ -569,22 +569,37 @@ } if (!(r = Pympz_new())) return NULL; - mpz_pow_ui(r->z, b->z, el); + if ((el == 0) && ( mpz_cmp_ui(b->z, 0) == 0)) + /* Make sure pow(0,0) == 1 */ + mpz_set_ui(r->z, 1); + else + mpz_pow_ui(r->z, b->z, el); if (options.debug) fprintf(stderr, "Pympz_pow (ui) -> %p\n", r); return (PyObject *) r; } else { /* Modulo exponentiation */ - if (mpz_cmp_ui(m->z, 0) == 0) + int sign; + + sign = mpz_cmp_ui(m->z, 0); + if (sign == 0) { PyErr_SetString(PyExc_ValueError, "mpz.pow divide by zero"); return NULL; } - /* What happens with negative modulo? */ if (!(r = Pympz_new())) return NULL; mpz_powm(r->z, b->z, e->z, m->z); + if ( (sign < 0) && (mpz_cmp_ui(r->z,0) > 0)) + { + /* Python uses a rather peculiar convention for negative modulos + * If the modulo is negative, result should be in the interval + * m < r <= 0 . + */ + mpz_add(r->z, r->z, m->z); + } + if (options.debug) fprintf(stderr, "Pympz_pow -> %p\n", r); return (PyObject *) r;