示例#1
0
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;
}
示例#2
0
文件: gmpy2_abs.c 项目: godbomb/gmpy
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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
文件: gmpy2_sign.c 项目: godbomb/gmpy
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);
    }
}
示例#6
0
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;
}
示例#7
0
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);
    }
}