static PyObject * Pyxmpz_make_mpz(PyObject *self, PyObject *other) { PympzObject* result; if (!(result = (PympzObject*)Pympz_new())) return NULL; mpz_swap(result->z, Pympz_AS_MPZ(self)); mpz_set_ui(Pympz_AS_MPZ(self), 0); return (PyObject*)result; }
static PyObject * Pygmpy_t_divmod(PyObject *self, PyObject *args) { PyObject *x, *y, *result; PympzObject *q, *r, *tempx, *tempy; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("t_divmod() requires 'mpz','mpz' arguments"); return NULL; } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); CREATE_TWO_MPZ_TUPLE(q, r, result); if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) { if (mpz_sgn(Pympz_AS_MPZ(y)) == 0) { ZERO_ERROR("t_divmod() division by 0"); Py_DECREF((PyObject*)q); Py_DECREF((PyObject*)r); Py_DECREF(result); return NULL; } mpz_tdiv_qr(q->z, r->z, Pympz_AS_MPZ(x), Pympz_AS_MPZ(y)); } else { tempx = Pympz_From_Integer(x); tempy = Pympz_From_Integer(y); if (!tempx || !tempy) { TYPE_ERROR("t_divmod() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)q); Py_DECREF((PyObject*)r); Py_DECREF(result); return NULL; } if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) { ZERO_ERROR("t_divmod() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)q); Py_DECREF((PyObject*)r); Py_DECREF(result); return NULL; } mpz_tdiv_qr(q->z, r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); } PyTuple_SET_ITEM(result, 0, (PyObject*)q); PyTuple_SET_ITEM(result, 1, (PyObject*)r); return result; }
static PyObject * Pympany_printf(PyObject *self, PyObject *args) { PyObject *result = 0, *x = 0; char *buffer = 0, *fmtcode = 0; int buflen; void *generic; if (!PyArg_ParseTuple(args, "sO", &fmtcode, &x)) return NULL; if (CHECK_MPZANY(x) || Pympq_Check(x)) { if (CHECK_MPZANY(x)) generic = Pympz_AS_MPZ(x); else generic = Pympq_AS_MPQ(x); buflen = gmp_asprintf(&buffer, fmtcode, generic); result = Py_BuildValue("s", buffer); PyMem_Free(buffer); return result; } #ifdef WITHMPFR else if(Pympfr_Check(x)) { generic = Pympfr_AS_MPFR(x); buflen = mpfr_asprintf(&buffer, fmtcode, generic); result = Py_BuildValue("s", buffer); PyMem_Free(buffer); return result; } #endif else { TYPE_ERROR("printf() requires a gmpy2 object as argument"); return NULL; } }
static PyObject * Pygmpy_c_div(PyObject *self, PyObject *args) { PyObject *x, *y; PympzObject *q, *tempx, *tempy; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("c_div() requires 'mpz','mpz' arguments"); return NULL; } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); if (!(q = Pympz_new())) return NULL; if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) { if (mpz_sgn(Pympz_AS_MPZ(y)) == 0) { ZERO_ERROR("c_div() division by 0"); Py_DECREF((PyObject*)q); return NULL; } mpz_cdiv_q(q->z, Pympz_AS_MPZ(x), Pympz_AS_MPZ(y)); } else { tempx = Pympz_From_Integer(x); tempy = Pympz_From_Integer(y); if (!tempx || !tempy) { TYPE_ERROR("c_div() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)q); return NULL; } if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) { ZERO_ERROR("c_div() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)q); return NULL; } mpz_cdiv_q(q->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); } return (PyObject*)q; }
static PyObject * Pyxmpz_subscript(PyxmpzObject* self, PyObject* item) { if (PyIndex_Check(item)) { Py_ssize_t i; i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) i += mpz_sizeinbase(self->z, 2); return PyIntOrLong_FromLong(mpz_tstbit(self->z, i)); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength, cur, i; PyObject* result; #if PY_VERSION_HEX > 0x030200A4 if (PySlice_GetIndicesEx(item, #else if (PySlice_GetIndicesEx((PySliceObject*)item, #endif mpz_sizeinbase(self->z, 2), &start, &stop, &step, &slicelength) < 0) { return NULL; } if ((step < 0 && start < stop) || (step > 0 && start > stop)) stop = start; if (!(result = (PyObject*)Pympz_new())) return NULL; mpz_set_ui(Pympz_AS_MPZ(result), 0); if (slicelength > 0) { for (cur = start, i = 0; i < slicelength; cur += step, i++) { if (mpz_tstbit(self->z, cur)) { mpz_setbit(Pympz_AS_MPZ(result), i); } } } return result; } else {
static PyObject * Pympany_pow(PyObject *base, PyObject *exp, PyObject *mod) { #ifndef WITHMPFR PyObject *result = 0, *temp; #endif if (isInteger(base) && isInteger(exp)) return Pympz_pow(base, exp, mod); else if (isRational(base) && isRational(exp)) return Pympq_pow(base, exp, mod); #ifdef WITHMPFR else if (isReal(base) && isReal(exp)); return Pympfr2_pow(base, exp, mod); #else /* Support mpz**float and float**mpz. */ if (CHECK_MPZANY(base) && PyFloat_Check(exp)) { temp = PyFloat_FromDouble(mpz_get_d(Pympz_AS_MPZ(base))); if (temp) { result = PyNumber_Power(temp, exp, mod); Py_DECREF(temp); } return result; } if (CHECK_MPZANY(exp) && PyFloat_Check(base)) { temp = PyFloat_FromDouble(mpz_get_d(Pympz_AS_MPZ(exp))); if (temp) { result = PyNumber_Power(base, temp, mod); Py_DECREF(temp); } return result; } #endif Py_RETURN_NOTIMPLEMENTED; }
static int isOne(PyObject* obj) { int overflow = 0; long temp; if (!obj) return 1; if (Pympq_Check(obj)) { return (0==mpz_cmp_ui(mpq_denref(Pympq_AS_MPQ(obj)),1)) && (0==mpz_cmp_ui(mpq_numref(Pympq_AS_MPQ(obj)),1)); } else if (Pympz_Check(obj)) { return 0==mpz_cmp_ui(Pympz_AS_MPZ(obj),1); } else if (Pyxmpz_Check(obj)) { return 0==mpz_cmp_ui(Pyxmpz_AS_MPZ(obj),1); #ifdef PY2 } else if (PyInt_Check(obj)) { return PyInt_AS_LONG(obj)==1; #endif } #ifdef WITHMPFR else if (Pympfr_Check(obj)) { return mpfr_get_d(Pympfr_AS_MPFR(obj), context->ctx.mpfr_round)==1.0; } #endif else if (PyFloat_Check(obj)) { return PyFloat_AS_DOUBLE(obj)==1.0; } else if (PyLong_Check(obj)) { temp = PyLong_AsLongAndOverflow(obj, &overflow); if (!overflow && temp == 1) return 1; else return 0; } return 0; }
static PyObject * Pympq_qdiv(PyObject *self, PyObject *args) { PyObject *other = 0; PyObject *s = 0; int wasone; if ( self && Pympq_Check(self)) { if (!PyArg_ParseTuple(args, "|O", &other)) return NULL; } else { if (!PyArg_ParseTuple(args, "O|O", &self, &other)) return NULL; } wasone = isOne(other); /* optimize if self must be returned unchanged */ if (Pympq_Check(self) && wasone) { /* optimize if self is mpq and result must==self */ if (mpz_cmp_ui(mpq_denref(Pympq_AS_MPQ(self)), 1) != 0) { Py_INCREF(self); return self; } else { /* denominator is 1, optimize returning an mpz */ s = Pympz_new(); mpz_set(Pympz_AS_MPZ(s), mpq_numref(Pympq_AS_MPQ(self))); return s; } } else if (Pympz_Check(self) && wasone) { /* optimize if self is mpz and result must==self */ Py_INCREF(self); return self; } /* normal, non-optimized case: must make new object as result */ self = (PyObject*)Pympq_From_Rational(self); if (!self) { if (!PyErr_Occurred()) TYPE_ERROR("first argument cannot be converted to 'mpq'"); return NULL; } if (wasone) { /* self was mpf, float, int, long... */ s = self; } else { /* other explicitly present and !=1... must compute */ other = (PyObject*)Pympq_From_Rational(other); if (!other) { Py_DECREF(self); if (!PyErr_Occurred()) TYPE_ERROR("second argument cannot be converted to 'mpq'"); return NULL; } if (mpq_sgn(Pympq_AS_MPQ(other))==0) { PyObject* result = 0; ZERO_ERROR("division or modulo by zero in qdiv"); Py_DECREF(self); Py_DECREF(other); return result; } s = Pympq_new(); mpq_div(Pympq_AS_MPQ(s), Pympq_AS_MPQ(self), Pympq_AS_MPQ(other)); Py_DECREF(self); Py_DECREF(other); } if (mpz_cmp_ui(mpq_denref(Pympq_AS_MPQ(s)), 1) != 0) { return s; } else { /* denominator is 1, return an mpz */ PyObject* ss = Pympz_new(); if (ss) mpz_set(Pympz_AS_MPZ(ss), mpq_numref(Pympq_AS_MPQ(s))); Py_DECREF(s); return ss; } }