static PyObject * GMPy_Real_Mod(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx = NULL, *tempy = NULL, *temp, *result; CHECK_CONTEXT(context); result = GMPy_MPFR_New(0, context); temp = GMPy_MPFR_New(0, context); if (!result || !temp) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)temp); return NULL; } if (IS_REAL(x) && IS_REAL(y)) { tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!tempx || !tempy) { SYSTEM_ERROR("could not convert Real to mpfr"); goto error; } if (mpfr_zero_p(tempy->f)) { context->ctx.divzero = 1; if (context->ctx.traps & TRAP_DIVZERO) { GMPY_DIVZERO("mod() modulo by zero"); goto error; } } if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("mod() invalid operation"); goto error; } else { mpfr_set_nan(result->f); } } else if (mpfr_inf_p(tempy->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("mod() invalid operation"); goto error; } if (mpfr_signbit(tempy->f)) { mpfr_set_inf(result->f, -1); } else { result->rc = mpfr_set(result->f, tempx->f, GET_MPFR_ROUND(context)); } } else { mpfr_fmod(result->f, tempx->f, tempy->f, GET_MPFR_ROUND(context)); if (!mpfr_zero_p(result->f)) { if ((mpfr_sgn(tempy->f) < 0) != (mpfr_sgn(result->f) < 0)) { mpfr_add(result->f, result->f, tempy->f, GET_MPFR_ROUND(context)); } } else { mpfr_copysign(result->f, result->f, tempy->f, GET_MPFR_ROUND(context)); } Py_DECREF((PyObject*)temp); } GMPY_MPFR_CHECK_RANGE(result, context); GMPY_MPFR_SUBNORMALIZE(result, context); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } Py_DECREF((PyObject*)temp); Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)temp); Py_DECREF((PyObject*)result); return NULL; }
static PyObject * GMPy_Real_DivMod_2(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx = NULL, *tempy = NULL, *quo = NULL, *rem = NULL; PyObject *result = NULL; CHECK_CONTEXT(context); if (!(result = PyTuple_New(2)) || !(rem = GMPy_MPFR_New(0, context)) || !(quo = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (IS_REAL(x) && IS_REAL(y)) { if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = GMPy_MPFR_From_Real(y, 1, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (mpfr_zero_p(tempy->f)) { context->ctx.divzero = 1; if (context->ctx.traps & TRAP_DIVZERO) { GMPY_DIVZERO("divmod() division by zero"); goto error; } } if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } else { mpfr_set_nan(quo->f); mpfr_set_nan(rem->f); } } else if (mpfr_inf_p(tempy->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } if (mpfr_zero_p(tempx->f)) { mpfr_set_zero(quo->f, mpfr_sgn(tempy->f)); mpfr_set_zero(rem->f, mpfr_sgn(tempy->f)); } else if ((mpfr_signbit(tempx->f)) != (mpfr_signbit(tempy->f))) { mpfr_set_si(quo->f, -1, MPFR_RNDN); mpfr_set_inf(rem->f, mpfr_sgn(tempy->f)); } else { mpfr_set_si(quo->f, 0, MPFR_RNDN); rem->rc = mpfr_set(rem->f, tempx->f, MPFR_RNDN); } } else { MPQ_Object *mpqx = NULL, *mpqy = NULL, *temp_rem = NULL; MPZ_Object *temp_quo = NULL; if (!(mpqx = GMPy_MPQ_From_MPFR(tempx, context)) || !(mpqy = GMPy_MPQ_From_MPFR(tempy, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)mpqx); Py_XDECREF((PyObject*)mpqy); goto error; /* LCOV_EXCL_STOP */ } if (!(temp_rem = GMPy_MPQ_New(context)) || !(temp_quo = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)temp_rem); Py_XDECREF((PyObject*)temp_quo); Py_XDECREF((PyObject*)mpqx); Py_XDECREF((PyObject*)mpqy); goto error; /* LCOV_EXCL_STOP */ } Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); mpq_div(temp_rem->q, mpqx->q, mpqy->q); mpz_fdiv_q(temp_quo->z, mpq_numref(temp_rem->q), mpq_denref(temp_rem->q)); /* Need to calculate x - quo * y. */ mpq_set_z(temp_rem->q, temp_quo->z); mpq_mul(temp_rem->q, temp_rem->q, mpqy->q); mpq_sub(temp_rem->q, mpqx->q, temp_rem->q); Py_DECREF((PyObject*)mpqx); Py_DECREF((PyObject*)mpqy); quo->rc = mpfr_set_z(quo->f, temp_quo->z, MPFR_RNDD); rem->rc = mpfr_set_q(rem->f, temp_rem->q, MPFR_RNDN); Py_DECREF((PyObject*)temp_rem); Py_DECREF((PyObject*)temp_quo); GMPY_MPFR_CHECK_RANGE(quo, context); GMPY_MPFR_CHECK_RANGE(rem, context); GMPY_MPFR_SUBNORMALIZE(quo, context); GMPY_MPFR_SUBNORMALIZE(rem, context); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Real_DivMod_2()."); error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)rem); Py_XDECREF((PyObject*)quo); Py_XDECREF(result); return NULL; /* LCOV_EXCL_STOP */ }
static PyObject * GMPy_Real_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context) { MPFR_Object *tempb = NULL, *tempe = NULL, *result = NULL; MPZ_Object *tempz = NULL; MPC_Object *mpc_result = NULL; if (mod != Py_None) { TYPE_ERROR("pow() 3rd argument not allowed unless all arguments are integers"); return NULL; } CHECK_CONTEXT(context); result = GMPy_MPFR_New(0, context); tempb = GMPy_MPFR_From_Real(base, 1, context); if (!result || !tempb) { goto err; } mpfr_clear_flags(); if (PyIntOrLong_Check(exp)) { int error; long temp_exp = GMPy_Integer_AsLongAndError(exp, &error); if (!error) { result->rc = mpfr_pow_si(result->f, tempb->f, temp_exp, GET_MPFR_ROUND(context)); } else { mpz_t tempzz; mpz_inoc(tempzz); mpz_set_PyIntOrLong(tempzz, exp); result->rc = mpfr_pow_z(result->f, tempb->f, tempzz, GET_MPFR_ROUND(context)); mpz_cloc(tempzz); } } else if (IS_INTEGER(exp)) { if (!(tempz = GMPy_MPZ_From_Integer(exp, context))) { goto err; } result->rc = mpfr_pow_z(result->f, tempb->f, tempz->z, GET_MPFR_ROUND(context)); } else { if (!(tempe = GMPy_MPFR_From_Real(exp, 1, context))) { goto err; } result->rc = mpfr_pow(result->f, tempb->f, tempe->f, GET_MPFR_ROUND(context)); } /* If the result is NaN, check if a complex result works. */ if (result && mpfr_nanflag_p() && context->ctx.allow_complex) { mpc_result = (MPC_Object*)GMPy_Complex_Pow(base, exp, Py_None, context); if (!mpc_result || MPC_IS_NAN_P(mpc_result)) { Py_XDECREF((PyObject*)mpc_result); context->ctx.invalid = 1; GMPY_INVALID("pow() invalid operation"); goto err; } /* return a valid complex result */ Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempz); Py_XDECREF((PyObject*)tempb); Py_XDECREF((PyObject*)result); return (PyObject*)mpc_result; } GMPY_MPFR_CLEANUP(result, context, "pow()"); Py_XDECREF((PyObject*)tempz); Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempb); return (PyObject*)result; err: Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempz); Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempb); return NULL; }
static PyObject * GMPy_Real_DivMod_1(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx = NULL, *tempy = NULL, *quo = NULL, *rem = NULL; PyObject *result = NULL; CHECK_CONTEXT(context); if (!(result = PyTuple_New(2)) || !(rem = GMPy_MPFR_New(0, context)) || !(quo = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (IS_REAL(x) && IS_REAL(y)) { if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = GMPy_MPFR_From_Real(y, 1, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (mpfr_zero_p(tempy->f)) { context->ctx.divzero = 1; if (context->ctx.traps & TRAP_DIVZERO) { GMPY_DIVZERO("divmod() division by zero"); goto error; } } if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } else { mpfr_set_nan(quo->f); mpfr_set_nan(rem->f); } } else if (mpfr_inf_p(tempy->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } if (mpfr_zero_p(tempx->f)) { mpfr_set_zero(quo->f, mpfr_sgn(tempy->f)); mpfr_set_zero(rem->f, mpfr_sgn(tempy->f)); } else if ((mpfr_signbit(tempx->f)) != (mpfr_signbit(tempy->f))) { mpfr_set_si(quo->f, -1, MPFR_RNDN); mpfr_set_inf(rem->f, mpfr_sgn(tempy->f)); } else { mpfr_set_si(quo->f, 0, MPFR_RNDN); rem->rc = mpfr_set(rem->f, tempx->f, MPFR_RNDN); } } else { MPFR_Object *temp; if (!(temp = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } mpfr_fmod(rem->f, tempx->f, tempy->f, MPFR_RNDN); mpfr_sub(temp->f, tempx->f, rem->f, MPFR_RNDN); mpfr_div(quo->f, temp->f, tempy->f, MPFR_RNDN); if (!mpfr_zero_p(rem->f)) { if ((mpfr_sgn(tempy->f) < 0) != (mpfr_sgn(rem->f) < 0)) { mpfr_add(rem->f, rem->f, tempy->f, MPFR_RNDN); mpfr_sub_ui(quo->f, quo->f, 1, MPFR_RNDN); } } else { mpfr_copysign(rem->f, rem->f, tempy->f, MPFR_RNDN); } if (!mpfr_zero_p(quo->f)) { mpfr_round(quo->f, quo->f); } else { mpfr_setsign(quo->f, quo->f, mpfr_sgn(tempx->f) * mpfr_sgn(tempy->f) - 1, MPFR_RNDN); } Py_DECREF((PyObject*)temp); } GMPY_MPFR_CHECK_RANGE(quo, context); GMPY_MPFR_CHECK_RANGE(rem, context); GMPY_MPFR_SUBNORMALIZE(quo, context); GMPY_MPFR_SUBNORMALIZE(rem, context); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return (PyObject*)result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Real_DivMod_1()."); error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)rem); Py_XDECREF((PyObject*)quo); Py_XDECREF(result); return NULL; /* LCOV_EXCL_STOP */ }