static PyObject * GMPy_Rational_Sub(PyObject *x, PyObject *y, CTXT_Object *context) { MPQ_Object *result; if (!(result = GMPy_MPQ_New(context))) return NULL; if (MPQ_Check(x) && MPQ_Check(y)) { mpq_sub(result->q, MPQ(x), MPQ(y)); return (PyObject*)result; } if (IS_RATIONAL(x) && IS_RATIONAL(y)) { MPQ_Object *tempx, *tempy; tempx = GMPy_MPQ_From_Rational(x, context); tempy = GMPy_MPQ_From_Rational(y, context); if (!tempx || !tempy) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpq_sub(result->q, tempx->q, tempy->q); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_Rational_Abs(PyObject *x, CTXT_Object *context) { MPQ_Object *result = NULL; if (MPQ_Check(x)) { if (mpz_sgn(mpq_numref(MPQ(x))) >= 0) { Py_INCREF(x); return x; } else { if ((result = GMPy_MPQ_New(context))) { mpq_set(result->q, MPQ(x)); mpz_abs(mpq_numref(result->q), mpq_numref(result->q)); } return (PyObject*)result; } } /* This is safe because result is not an incremented reference to an * existing value. MPQ is already handled so GMPy_MPQ_From_Rational() * can't return an incremented reference to an existing value (which it * would do if passed an MPQ). */ if ((result = GMPy_MPQ_From_Rational(x, context))) { mpz_abs(mpq_numref(result->q), mpq_numref(result->q)); } return (PyObject*)result; }
static PyObject * GMPy_Context_Digits(PyObject *self, PyObject *args) { PyObject *arg0, *tuple, *temp, *result; Py_ssize_t argc; argc = PyTuple_GET_SIZE(args); if (argc == 0) { TYPE_ERROR("digits() requires at least one argument"); return NULL; } if (argc > 3) { TYPE_ERROR("digits() accepts at most three arguments"); return NULL; } arg0 = PyTuple_GET_ITEM(args, 0); if (!(tuple = PyTuple_GetSlice(args, 1, argc))) { return NULL; } if (IS_INTEGER(arg0)) { temp = (PyObject*)GMPy_MPZ_From_Integer(arg0, NULL); result = GMPy_MPZ_Digits_Method(temp, tuple); Py_DECREF(temp); Py_DECREF(tuple); return result; } if (IS_RATIONAL(arg0)) { temp = (PyObject*)GMPy_MPQ_From_Rational(arg0, NULL); result = GMPy_MPQ_Digits_Method(temp, tuple); Py_DECREF(temp); Py_DECREF(tuple); return result; } if (IS_REAL(arg0)) { temp = (PyObject*)GMPy_MPFR_From_Real(arg0, 1, NULL); result = GMPy_MPFR_Digits_Method(temp, tuple); Py_DECREF(temp); Py_DECREF(tuple); return result; } if (IS_COMPLEX(arg0)) { temp = (PyObject*)GMPy_MPC_From_Complex(arg0, 1, 1, NULL); result = GMPy_MPC_Digits_Method(temp, tuple); Py_DECREF(temp); Py_DECREF(tuple); return result; } TYPE_ERROR("digits() argument type not supported"); return NULL; }
static PyObject * GMPy_Rational_Minus(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context))) { return NULL; } result = _GMPy_MPQ_Minus(tempx, context); Py_DECREF(tempx); return result; }
static PyObject * GMPy_Rational_Sign(PyObject *x, CTXT_Object *context) { long res; MPQ_Object *tempx; if (!(tempx = GMPy_MPQ_From_Rational(x, context))) { return NULL; } else { res = mpq_sgn(tempx->q); Py_DECREF((PyObject*)tempx); return PyIntOrLong_FromLong(res); } }
static PyObject * GMPy_MPQ_Factory(PyObject *self, PyObject *args, PyObject *keywds) { MPQ_Object *result, *temp; PyObject *n, *m; int base = 10; Py_ssize_t argc, keywdc = 0; static char *kwlist[] = {"s", "base", NULL }; CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } argc = PyTuple_Size(args); if (keywds) { keywdc = PyDict_Size(keywds); } if (argc + keywdc > 2) { TYPE_ERROR("mpq() takes at most 2 arguments"); return NULL; } if (argc + keywdc == 0) { if ((result = GMPy_MPQ_New(context))) { mpq_set_ui(result->q, 0, 1); } return (PyObject*)result; } if (argc == 0) { TYPE_ERROR("mpq() requires at least one non-keyword argument"); return NULL; } n = PyTuple_GetItem(args, 0); /* Handle the case where the first argument is a string. */ if (PyStrOrUnicode_Check(n)) { /* keyword base is legal */ if (keywdc || argc > 1) { if (!(PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &n, &base))) { return NULL; } } if ((base != 0) && ((base < 2) || (base > 62))) { VALUE_ERROR("base for mpq() must be 0 or in the interval [2, 62]"); return NULL; } return (PyObject*)GMPy_MPQ_From_PyStr(n, base, context); } /* Handle 1 argument. It must be non-complex number. */ if (argc == 1) { if (IS_REAL(n)) { return (PyObject*)GMPy_MPQ_From_Number(n, context); } } /* Handle 2 arguments. Both arguments must be integer or rational. */ if (argc == 2) { m = PyTuple_GetItem(args, 1); if (IS_RATIONAL(n) && IS_RATIONAL(m)) { result = GMPy_MPQ_From_Rational(n, context); temp = GMPy_MPQ_From_Rational(m, context); if (!result || !temp) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)temp); return NULL; } if (mpq_sgn(temp->q) == 0) { ZERO_ERROR("zero denominator in mpq()"); Py_DECREF((PyObject*)result); Py_DECREF((PyObject*)temp); return NULL; } mpq_div(result->q, result->q, temp->q); Py_DECREF((PyObject*)temp); return (PyObject*)result; } } TYPE_ERROR("mpq() requires numeric or string argument"); return NULL; }
static PyObject * GMPy_Rational_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context) { MPQ_Object *tempbq = NULL, *resultq = NULL; MPZ_Object *tempez = NULL; int bsign; long tempexp; if (mod != Py_None) { TYPE_ERROR("pow() 3rd argument not allowed unless all arguments are integers"); return NULL; } /* Only support mpq**int. Everything else gets converted to mpf. */ if (IS_RATIONAL(base) && IS_INTEGER(exp)) { resultq = GMPy_MPQ_New(context); tempbq = GMPy_MPQ_From_Rational(base, context); tempez = GMPy_MPZ_From_Integer(exp, context); if (!resultq || !tempbq || !tempez) { Py_XDECREF((PyObject*)resultq); Py_XDECREF((PyObject*)tempbq); Py_XDECREF((PyObject*)tempez); return NULL; } if (!mpz_fits_slong_p(tempez->z)) { VALUE_ERROR("mpq.pow() outrageous exponent"); Py_DECREF((PyObject*)resultq); Py_DECREF((PyObject*)tempbq); Py_DECREF((PyObject*)tempez); return NULL; } tempexp = mpz_get_si(tempez->z); if (tempexp == 0) { mpq_set_si(resultq->q, 1, 1); Py_DECREF((PyObject*)tempbq); Py_DECREF((PyObject*)tempez); return (PyObject*)resultq; } bsign = mpq_sgn(tempbq->q); if (tempexp < 0) { if (bsign == 0) { ZERO_ERROR("pow() 0 base to negative exponent"); Py_DECREF((PyObject*)resultq); Py_DECREF((PyObject*)tempbq); Py_DECREF((PyObject*)tempez); return NULL; } if (bsign < 0) { mpz_neg(mpq_numref(resultq->q), mpq_denref(tempbq->q)); } else { mpz_set(mpq_numref(resultq->q), mpq_denref(tempbq->q)); } mpz_abs(mpq_denref(resultq->q), mpq_numref(tempbq->q)); tempexp = -tempexp; } else { mpq_set(resultq->q, tempbq->q); } if (tempexp > 1) { mpz_pow_ui(mpq_numref(resultq->q), mpq_numref(resultq->q), tempexp); mpz_pow_ui(mpq_denref(resultq->q), mpq_denref(resultq->q), tempexp); } Py_DECREF((PyObject*)tempbq); Py_DECREF((PyObject*)tempez); return (PyObject*)resultq; } else { return GMPy_Real_Pow(base, exp, Py_None, context); } }