SeedValue seed_mpfr_copysign (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException *exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; CHECK_ARG_COUNT("mpfr.copysign", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); if ( seed_value_is_object_of_class(ctx, args[0], mpfr_class) && seed_value_is_object_of_class(ctx, args[1], mpfr_class)) { op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); } else { TYPE_EXCEPTION("mpfr.copysign", "mpfr_t"); } ret = mpfr_copysign(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); }
static void copysign_variant (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode, int k) { mpfr_clear_flags (); switch (k) { case 0: mpfr_copysign (z, x, y, MPFR_RNDN); return; case 1: (mpfr_copysign) (z, x, y, MPFR_RNDN); return; case 2: mpfr_setsign (z, x, mpfr_signbit (y), MPFR_RNDN); return; case 3: mpfr_setsign (z, x, (mpfr_signbit) (y), MPFR_RNDN); return; case 4: (mpfr_setsign) (z, x, mpfr_signbit (y), MPFR_RNDN); return; case 5: (mpfr_setsign) (z, x, (mpfr_signbit) (y), MPFR_RNDN); return; } }
int main (void) { mpfr_t x, y, z; tests_start_mpfr (); mpfr_init (x); mpfr_init (y); mpfr_init (z); /* case y=NaN */ mpfr_set_nan (y); mpfr_set_ui (x, 1250, GMP_RNDN); mpfr_copysign (z, x, y, GMP_RNDN); if (!mpfr_nan_p (z)) { printf ("Error in mpfr_copysign (NaN)\n"); exit (1); } /* case y!=NaN */ mpfr_set_ui (y, 123, GMP_RNDN); mpfr_set_ui (x, 1250, GMP_RNDN); mpfr_copysign (z, x, y, GMP_RNDN); if (mpfr_cmp_ui (z, 1250)) { printf ("Error in mpfr_copysign (1250)\n"); exit (1); } mpfr_set_si (y, -17, GMP_RNDN); mpfr_set_ui (x, 42, GMP_RNDN); mpfr_copysign (z, x, y, GMP_RNDN); if (mpfr_cmp_si (z, -42)) { printf ("Error in mpfr_copysign (-42)\n"); exit (1); } mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); tests_end_mpfr (); return 0; }
static int synge_factorial(synge_t to, synge_t num, mpfr_rnd_t round) { /* round input */ synge_t number; mpfr_init2(number, SYNGE_PRECISION); mpfr_abs(number, num, round); mpfr_floor(number, number); /* multilply original number by reverse iterator */ mpfr_set_si(to, 1, round); while(!iszero(number)) { mpfr_mul(to, to, number, round); mpfr_sub_si(number, number, 1, round); } mpfr_copysign(to, to, num, round); mpfr_clears(number, NULL); return 0; } /* synge_factorial() */
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; }
int mpc_exp (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) { mpfr_t x, y, z; mpfr_prec_t prec; int ok = 0; int inex_re, inex_im; int saved_underflow, saved_overflow; /* special values */ if (mpfr_nan_p (mpc_realref (op)) || mpfr_nan_p (mpc_imagref (op))) /* NaNs exp(nan +i*y) = nan -i*0 if y = -0, nan +i*0 if y = +0, nan +i*nan otherwise exp(x+i*nan) = +/-0 +/-i*0 if x=-inf, +/-inf +i*nan if x=+inf, nan +i*nan otherwise */ { if (mpfr_zero_p (mpc_imagref (op))) return mpc_set (rop, op, MPC_RNDNN); if (mpfr_inf_p (mpc_realref (op))) { if (mpfr_signbit (mpc_realref (op))) return mpc_set_ui_ui (rop, 0, 0, MPC_RNDNN); else { mpfr_set_inf (mpc_realref (rop), +1); mpfr_set_nan (mpc_imagref (rop)); return MPC_INEX(0, 0); /* Inf/NaN are exact */ } } mpfr_set_nan (mpc_realref (rop)); mpfr_set_nan (mpc_imagref (rop)); return MPC_INEX(0, 0); /* NaN is exact */ } if (mpfr_zero_p (mpc_imagref(op))) /* special case when the input is real exp(x-i*0) = exp(x) -i*0, even if x is NaN exp(x+i*0) = exp(x) +i*0, even if x is NaN */ { inex_re = mpfr_exp (mpc_realref(rop), mpc_realref(op), MPC_RND_RE(rnd)); inex_im = mpfr_set (mpc_imagref(rop), mpc_imagref(op), MPC_RND_IM(rnd)); return MPC_INEX(inex_re, inex_im); } if (mpfr_zero_p (mpc_realref (op))) /* special case when the input is imaginary */ { inex_re = mpfr_cos (mpc_realref (rop), mpc_imagref (op), MPC_RND_RE(rnd)); inex_im = mpfr_sin (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM(rnd)); return MPC_INEX(inex_re, inex_im); } if (mpfr_inf_p (mpc_realref (op))) /* real part is an infinity, exp(-inf +i*y) = 0*(cos y +i*sin y) exp(+inf +i*y) = +/-inf +i*nan if y = +/-inf +inf*(cos y +i*sin y) if 0 < |y| < inf */ { mpfr_t n; mpfr_init2 (n, 2); if (mpfr_signbit (mpc_realref (op))) mpfr_set_ui (n, 0, GMP_RNDN); else mpfr_set_inf (n, +1); if (mpfr_inf_p (mpc_imagref (op))) { inex_re = mpfr_set (mpc_realref (rop), n, GMP_RNDN); if (mpfr_signbit (mpc_realref (op))) inex_im = mpfr_set (mpc_imagref (rop), n, GMP_RNDN); else { mpfr_set_nan (mpc_imagref (rop)); inex_im = 0; /* NaN is exact */ } } else { mpfr_t c, s; mpfr_init2 (c, 2); mpfr_init2 (s, 2); mpfr_sin_cos (s, c, mpc_imagref (op), GMP_RNDN); inex_re = mpfr_copysign (mpc_realref (rop), n, c, GMP_RNDN); inex_im = mpfr_copysign (mpc_imagref (rop), n, s, GMP_RNDN); mpfr_clear (s); mpfr_clear (c); } mpfr_clear (n); return MPC_INEX(inex_re, inex_im); } if (mpfr_inf_p (mpc_imagref (op))) /* real part is finite non-zero number, imaginary part is an infinity */ { mpfr_set_nan (mpc_realref (rop)); mpfr_set_nan (mpc_imagref (rop)); return MPC_INEX(0, 0); /* NaN is exact */ } /* from now on, both parts of op are regular numbers */ prec = MPC_MAX_PREC(rop) + MPC_MAX (MPC_MAX (-mpfr_get_exp (mpc_realref (op)), 0), -mpfr_get_exp (mpc_imagref (op))); /* When op is close to 0, then exp is close to 1+Re(op), while cos is close to 1-Im(op); to decide on the ternary value of exp*cos, we need a high enough precision so that none of exp or cos is computed as 1. */ mpfr_init2 (x, 2); mpfr_init2 (y, 2); mpfr_init2 (z, 2); /* save the underflow or overflow flags from MPFR */ saved_underflow = mpfr_underflow_p (); saved_overflow = mpfr_overflow_p (); do { prec += mpc_ceil_log2 (prec) + 5; mpfr_set_prec (x, prec); mpfr_set_prec (y, prec); mpfr_set_prec (z, prec); /* FIXME: x may overflow so x.y does overflow too, while Re(exp(op)) could be represented in the precision of rop. */ mpfr_clear_overflow (); mpfr_clear_underflow (); mpfr_exp (x, mpc_realref(op), GMP_RNDN); /* error <= 0.5ulp */ mpfr_sin_cos (z, y, mpc_imagref(op), GMP_RNDN); /* errors <= 0.5ulp */ mpfr_mul (y, y, x, GMP_RNDN); /* error <= 2ulp */ ok = mpfr_overflow_p () || mpfr_zero_p (x) || mpfr_can_round (y, prec - 2, GMP_RNDN, GMP_RNDZ, MPC_PREC_RE(rop) + (MPC_RND_RE(rnd) == GMP_RNDN)); if (ok) /* compute imaginary part */ { mpfr_mul (z, z, x, GMP_RNDN); ok = mpfr_overflow_p () || mpfr_zero_p (x) || mpfr_can_round (z, prec - 2, GMP_RNDN, GMP_RNDZ, MPC_PREC_IM(rop) + (MPC_RND_IM(rnd) == GMP_RNDN)); } } while (ok == 0); inex_re = mpfr_set (mpc_realref(rop), y, MPC_RND_RE(rnd)); inex_im = mpfr_set (mpc_imagref(rop), z, MPC_RND_IM(rnd)); if (mpfr_overflow_p ()) { /* overflow in real exponential, inex is sign of infinite result */ inex_re = mpfr_sgn (y); inex_im = mpfr_sgn (z); } else if (mpfr_underflow_p ()) { /* underflow in real exponential, inex is opposite of sign of 0 result */ inex_re = (mpfr_signbit (y) ? +1 : -1); inex_im = (mpfr_signbit (z) ? +1 : -1); } mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); /* restore underflow and overflow flags from MPFR */ if (saved_underflow) mpfr_set_underflow (); if (saved_overflow) mpfr_set_overflow (); return MPC_INEX(inex_re, inex_im); }
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 */ }