REAL _mod(REAL a, REAL b, QByteArray &error) { if (b == ZERO) { error = QByteArray("ERROR: division by zero error!"); print(error.constData()); return ZERO; } mpfr_t base; mpfr_init2(base, NUMBITS); mpfr_t degr; mpfr_init2(degr, NUMBITS); mpfr_t result; mpfr_init2(result, NUMBITS); // mpfr_init_set_f(base, a.get_mpf_t(), MPFR_RNDN); // mpfr_init_set_f(degr, b.get_mpf_t(), MPFR_RNDN); mpfr_set_str(base, getString(a).data(), 10, MPFR_RNDN); mpfr_set_str(degr, getString(b).data(), 10, MPFR_RNDN); mpfr_fmod(result, degr, base, MPFR_RNDN); mpfr_get_f(a.get_mpf_t(), result, MPFR_RNDN); mpfr_clear(base); mpfr_clear(degr); mpfr_clear(result); return a; }
SeedValue seed_mpfr_fmod (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.fmod", 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.fmod", "mpfr_t"); } ret = mpfr_fmod(rop, op1, op2, rnd); return seed_value_from_int(ctx, ret, exception); }
decimal r_mod(const decimal& a,const decimal& b) { #ifdef USE_CGAL CGAL::Gmpfr m; CGAL::Gmpfr n=to_gmpfr(a); CGAL::Gmpfr o=to_gmpfr(b); mpfr_fmod(m.fr(),n.fr(),o.fr(),MPFR_RNDN); return decimal(m); #else return fmod(a,b); #endif }
static void check (mpfr_t r0, mpfr_t x, mpfr_t y, mpfr_rnd_t rnd) { int inex0, inex1; mpfr_t r1; mpfr_init2 (r1, mpfr_get_prec (r0)); inex0 = mpfr_fmod (r0, x, y, rnd); inex1 = slow_fmod (r1, x, y, rnd); if (!mpfr_equal_p (r0, r1) || inex0 != inex1) test_failed (r1, r0, inex1, inex0, x, y, rnd); mpfr_clear (r1); }
void ovm_q_rem(oregister_t *l, oregister_t *r) { switch (r->t) { case t_void: ovm_raise(except_floating_point_error); case t_word: if (r->v.w == 0) ovm_raise(except_floating_point_error); if (r->v.w > 0) mpz_mul_ui(ozr(r), ozs(l), r->v.w); else { mpz_set_si(ozr(r), r->v.w); mpz_mul(ozr(r), ozs(l), ozr(r)); } mpz_tdiv_r(ozr(l), ozr(l), ozr(r)); mpq_canonicalize(oqr(l)); check_mpq(l); break; case t_float: l->t = t_float; l->v.d = fmod(mpq_get_d(oqr(l)), r->v.d); break; case t_mpz: mpz_mul(ozr(r), ozs(l), ozr(r)); mpz_tdiv_r(ozr(l), ozr(l), ozr(r)); check_mpq(l); break; case t_rat: mpq_set_si(oqr(r), rat_num(r->v.r), rat_den(r->v.r)); case t_mpq: mpq_div(oqr(l), oqr(l), oqr(r)); mpz_tdiv_r(ozr(l), ozr(l), ozs(l)); mpz_mul(ozs(l), ozs(l), ozs(r)); mpq_canonicalize(oqr(l)); if (mpq_sgn(oqr(r)) < 0) mpq_neg(oqr(l), oqr(l)); check_mpq(l); break; case t_mpr: l->t = t_mpr; mpfr_set_q(orr(l), oqr(l), thr_rnd); mpfr_fmod(orr(l), orr(l), orr(r), thr_rnd); break; default: ovm_raise(except_not_a_real_number); } }
/* bug reported by Eric Veach */ static void bug20090519 (void) { mpfr_t x, y, r; int inexact; mpfr_inits2 (100, x, y, r, (mpfr_ptr) 0); mpfr_set_prec (x, 3); mpfr_set_prec (y, 3); mpfr_set_prec (r, 3); mpfr_set_si (x, 8, MPFR_RNDN); mpfr_set_si (y, 7, MPFR_RNDN); check (r, x, y, MPFR_RNDN); mpfr_set_prec (x, 10); mpfr_set_prec (y, 10); mpfr_set_prec (r, 10); mpfr_set_ui_2exp (x, 3, 26, MPFR_RNDN); mpfr_set_si (y, (1 << 9) - 1, MPFR_RNDN); check (r, x, y, MPFR_RNDN); mpfr_set_prec (x, 100); mpfr_set_prec (y, 100); mpfr_set_prec (r, 100); mpfr_set_str (x, "3.5", 10, MPFR_RNDN); mpfr_set_str (y, "1.1", 10, MPFR_RNDN); check (r, x, y, MPFR_RNDN); /* double check, with a pre-computed value */ { mpfr_t er; mpfr_init2 (er, 100); mpfr_set_str (er, "CCCCCCCCCCCCCCCCCCCCCCCC8p-102", 16, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, er) || inexact != 0) test_failed (er, r, 0, inexact, x, y, MPFR_RNDN); mpfr_clear (er); } mpfr_set_si (x, 20, MPFR_RNDN); mpfr_set_ui_2exp (y, 1, 1, MPFR_RNDN); /* exact */ mpfr_sin (y, y, MPFR_RNDN); check (r, x, y, MPFR_RNDN); mpfr_clears(r, x, y, (mpfr_ptr) 0); }
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; }
MpfrFloat MpfrFloat::operator%(const MpfrFloat& rhs) const { MpfrFloat retval(kNoInitialization); mpfr_fmod(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return retval; }
MpfrFloat& MpfrFloat::operator%=(const MpfrFloat& rhs) { copyIfShared(); mpfr_fmod(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return *this; }
num_t num_float_two_op(optype_t op_type, num_t a, num_t b) { num_t r, r_z, rem_z, a_z, b_z; int both_z = num_both_z(a, b); r = num_new_fp(N_TEMP, NULL); mpfr_set_prec(F(r), num_max_prec(a, b)); a = num_new_fp(N_TEMP, a); b = num_new_fp(N_TEMP, b); if (both_z) { r_z = num_new_z(N_TEMP, NULL); rem_z = num_new_z(N_TEMP, NULL); a_z = num_new_z(N_TEMP, a); b_z = num_new_z(N_TEMP, b); } switch (op_type) { case OP_ADD: if (both_z) { mpz_add(Z(r_z), Z(a_z), Z(b_z)); return r_z; } else { mpfr_add(F(r), F(a), F(b), round_mode); } break; case OP_SUB: if (both_z) { mpz_sub(Z(r_z), Z(a_z), Z(b_z)); return r_z; } else { mpfr_sub(F(r), F(a), F(b), round_mode); } break; case OP_MUL: if (both_z) { mpz_mul(Z(r_z), Z(a_z), Z(b_z)); return r_z; } else { mpfr_mul(F(r), F(a), F(b), round_mode); } break; case OP_DIV: if (both_z) mpz_divmod(Z(r_z), Z(rem_z), Z(a_z), Z(b_z)); if (both_z && num_is_zero(rem_z)) return r_z; else mpfr_div(F(r), F(a), F(b), round_mode); break; case OP_MOD: if (both_z) { mpz_mod(Z(r_z), Z(a_z), Z(b_z)); return r_z; } else { /* * XXX: mpfr_fmod or mpfr_remainder */ mpfr_fmod(F(r), F(a), F(b), round_mode); } break; case OP_POW: mpfr_pow(F(r), F(a), F(b), round_mode); break; default: yyxerror("Unknown op in num_float_two_op"); } return r; }
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 */ }
static void special (void) { int inexact; mpfr_t x, y, r, nan; mpfr_inits (x, y, r, nan, (mpfr_ptr) 0); mpfr_set_nan (nan); /* fmod (NaN, NaN) is NaN */ mpfr_set_nan (x); mpfr_set_nan (y); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (NaN, +0) is NaN */ mpfr_set_ui (y, 0, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (+1, 0) is NaN */ mpfr_set_ui (x, 1, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (0, 0) is NaN */ mpfr_set_ui (x, 0, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (+inf, +0) is NaN */ mpfr_set_inf (x, +1); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (-inf, +0) is NaN */ mpfr_set_inf (x, -1); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (-inf, -0) is NaN */ mpfr_neg (x, x, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (-inf, +1) is NaN */ mpfr_set_ui (y, +1, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (+inf, +1) is NaN */ mpfr_neg (x, x, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (+inf, -inf) is NaN */ mpfr_set_inf (y, -1); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (-inf, -inf) is NaN */ mpfr_neg (x, x, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (-inf, +inf) is NaN */ mpfr_neg (y, y, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (+inf, +inf) is NaN */ mpfr_neg (x, x, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (x, +inf) = x, if x is finite */ mpfr_set_ui (x, 1, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); /* fmod (+0, +inf) = +0 */ mpfr_set_ui (x, 0, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); /* fmod (-0, +inf) = -0 */ mpfr_neg (x, x, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); /* fmod (x, -inf) = x, if x is finite */ mpfr_set_inf (y, -1); mpfr_set_ui (x, 1, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); /* fmod (+0, -inf) = +0 */ mpfr_set_ui (x, 0, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); /* fmod (-0, -inf) = -0 */ mpfr_neg (x, x, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); /* fmod (+0, +0) is NaN */ mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_set_ui (y, 0, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (+0, -0) is NaN */ mpfr_neg (y, y, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_nan_p (r) || inexact != 0) test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); /* fmod (+0, +1) = +0 */ mpfr_set_ui (y, 1, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); /* fmod (+0, -1) = +0 */ mpfr_neg (y, y, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); /* fmod (-0, -1) = -0 */ mpfr_neg (x, x, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); /* fmod (-0, +1) = -0 */ mpfr_neg (y, y, MPFR_RNDN); inexact = mpfr_fmod (r, x, y, MPFR_RNDN); if (!mpfr_equal_p (r, x) || inexact != 0) test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); mpfr_clears (x, y, r, nan, (mpfr_ptr) 0); return; }