/* This is a bit disgusting. Oh well. */ SeedValue seed_mpfr_add (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException *exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gdouble dop1, dop2; gint ret; seed_mpfr_t argt1, argt2; /* only want 1 double argument. alternatively, could accept 2, add those, and set from the result*/ CHECK_ARG_COUNT("mpfr.add", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); argt1 = seed_mpfr_arg_type(ctx, args[0], exception); argt2 = seed_mpfr_arg_type(ctx, args[1], exception); if ( (argt1 & argt2) == SEED_MPFR_MPFR ) { /* both mpfr_t */ op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); ret = mpfr_add(rop, op1, op2, rnd); } else if ( (argt1 | argt2) == (SEED_MPFR_MPFR | SEED_MPFR_DOUBLE) ) { /* a double and an mpfr_t. Figure out the order */ if ( argt1 == SEED_MPFR_MPFR ) { op1 = seed_object_get_private(args[0]); dop2 = seed_value_to_double(ctx, args[1], exception); mpfr_add_d(rop, op1, dop2, rnd); } else { dop2 = seed_value_to_double(ctx, args[0], exception); op1 = seed_object_get_private(args[1]); mpfr_add_d(rop, op1, dop2, rnd); } } else if ( (argt1 & argt2) == SEED_MPFR_DOUBLE ) { /* 2 doubles. hopefully doesn't happen */ dop1 = seed_value_to_double(ctx, args[0], exception); dop2 = seed_value_to_double(ctx, args[1], exception); ret = mpfr_set_d(rop, dop1 + dop2, rnd); } else { TYPE_EXCEPTION("mpfr.add", "double or mpfr_t"); } return seed_value_from_int(ctx, ret, exception); }
static void check_regulars (void) { mpfr_t x, y, z; double d; int inexact; /* (1) check with enough precision */ mpfr_init2 (x, IEEE_DBL_MANT_DIG); mpfr_init2 (y, IEEE_DBL_MANT_DIG); mpfr_init2 (z, IEEE_DBL_MANT_DIG); mpfr_set_str (y, "4096", 10, GMP_RNDN); d = 0.125; mpfr_clear_flags (); inexact = mpfr_add_d (x, y, d, GMP_RNDN); if (inexact != 0) { printf ("Inexact flag error in mpfr_add_d (1)\n"); exit (1); } mpfr_set_str (z, "4096.125", 10, GMP_RNDN); if (mpfr_cmp (z, x)) { printf ("Error in mpfr_add_d ("); mpfr_out_str (stdout, 10, 7, y, GMP_RNDN); printf (" + %.20g)\nexpected ", d); mpfr_out_str (stdout, 10, 0, z, GMP_RNDN); printf ("\ngot "); mpfr_out_str (stdout, 10, 0, x, GMP_RNDN); printf ("\n"); exit (1); } /* (2) check inexact flag */ mpfr_set_prec (x, 2); mpfr_set_prec (z, 2); mpfr_clear_flags (); inexact = mpfr_add_d (x, y, d, GMP_RNDN); if (inexact == 0) { printf ("Inexact flag error in mpfr_add_d (2)\n"); exit (1); } mpfr_set_str (z, "4096.125", 10, GMP_RNDN); if (mpfr_cmp (z, x)) { printf ("Error in mpfr_add_d ("); mpfr_out_str (stdout, 10, 0, y, GMP_RNDN); printf (" + %.20g)\nexpected ", d); mpfr_out_str (stdout, 10, 0, z, GMP_RNDN); printf ("\ngot "); mpfr_out_str (stdout, 10, 0, x, GMP_RNDN); printf ("\n"); exit (1); } mpfr_clears (x, y, z, (mpfr_ptr) 0); }
static void check_nans (void) { #if !defined(MPFR_ERRDIVZERO) mpfr_t x, y; int inexact; mpfr_init2 (x, 123); mpfr_init2 (y, 123); /* nan + 1.0 is nan */ mpfr_set_nan (x); mpfr_clear_flags (); inexact = mpfr_add_d (y, x, 1.0, MPFR_RNDN); MPFR_ASSERTN (inexact == 0); MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0); MPFR_ASSERTN (mpfr_nan_p (y)); /* +inf + 1.0 == +inf */ mpfr_set_inf (x, 1); mpfr_clear_flags (); inexact = mpfr_add_d (y, x, 1.0, MPFR_RNDN); MPFR_ASSERTN (inexact == 0); MPFR_ASSERTN (__gmpfr_flags == 0); MPFR_ASSERTN (mpfr_inf_p (y)); MPFR_ASSERTN (MPFR_IS_POS (y)); /* -inf + 1.0 == -inf */ mpfr_set_inf (x, -1); mpfr_clear_flags (); inexact = mpfr_add_d (y, x, 1.0, MPFR_RNDN); MPFR_ASSERTN (inexact == 0); MPFR_ASSERTN (__gmpfr_flags == 0); MPFR_ASSERTN (mpfr_inf_p (y)); MPFR_ASSERTN (MPFR_IS_NEG (y)); mpfr_clear (x); mpfr_clear (y); #endif }
static PyObject * GMPy_Real_Add(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) return NULL; if (MPFR_Check(x) && MPFR_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_add(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); goto done; } if (MPFR_Check(x)) { if (PyIntOrLong_Check(y)) { mpz_t tempz; long temp; int error; temp = GMPy_Integer_AsLongAndError(y, &error); if (error) { mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, y); mpfr_clear_flags(); result->rc = mpfr_add_z(result->f, MPFR(x), tempz, GET_MPFR_ROUND(context)); mpz_cloc(tempz); goto done; } else { mpfr_clear_flags(); result->rc = mpfr_add_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(y)) { mpfr_clear_flags(); result->rc = mpfr_add_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(y)) { MPQ_Object *tempy; if (!(tempy = GMPy_MPQ_From_Number(y, context))) { Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_add_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempy); goto done; } if (PyFloat_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_add_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context)); goto done; } } if (MPFR_Check(y)) { if (PyIntOrLong_Check(x)) { mpz_t tempz; long temp; int error; temp = GMPy_Integer_AsLongAndError(x, &error); if (error) { mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, x); mpfr_clear_flags(); result->rc = mpfr_add_z(result->f, MPFR(y), tempz, GET_MPFR_ROUND(context)); mpz_cloc(tempz); goto done; } else { mpfr_clear_flags(); result->rc = mpfr_add_si(result->f, MPFR(y), temp, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(x)) { mpfr_clear_flags(); result->rc = mpfr_add_z(result->f, MPFR(y), MPZ(x), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(x)) { MPQ_Object *tempx; if (!(tempx = GMPy_MPQ_From_Number(x, context))) { Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_add_q(result->f, MPFR(y), tempx->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); goto done; } if (PyFloat_Check(x)) { mpfr_clear_flags(); result->rc = mpfr_add_d(result->f, MPFR(y), PyFloat_AS_DOUBLE(x), GET_MPFR_ROUND(context)); goto done; } } if (IS_REAL(x) && IS_REAL(y)) { MPFR_Object *tempx, *tempy; tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!tempx || !tempy) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_add(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; done: GMPY_MPFR_CLEANUP(result, context, "addition"); return (PyObject*)result; }
//=========================================================================== // Operator functions //=========================================================================== MpfrFloat operator+(double lhs, const MpfrFloat& rhs) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_add_d(retval.mData->mFloat, rhs.mData->mFloat, lhs, GMP_RNDN); return retval; }
MpfrFloat MpfrFloat::operator+(double value) const { MpfrFloat retval(kNoInitialization); mpfr_add_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); return retval; }
MpfrFloat& MpfrFloat::operator+=(double value) { copyIfShared(); mpfr_add_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); return *this; }
static PyObject * GMPy_Real_Add(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPFR_Check(x) && MPFR_Check(y)) { mpfr_clear_flags(); SET_MPFR_MPFR_WAS_NAN(context, x, y); result->rc = mpfr_add(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); goto done; } if (MPFR_Check(x)) { if (PyIntOrLong_Check(y)) { int error; long temp = GMPy_Integer_AsLongAndError(y, &error); if (!error) { mpfr_clear_flags(); SET_MPFR_WAS_NAN(context, x); result->rc = mpfr_add_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context)); goto done; } else { mpz_set_PyIntOrLong(global.tempz, y); mpfr_clear_flags(); SET_MPFR_WAS_NAN(context, x); result->rc = mpfr_add_z(result->f, MPFR(x), global.tempz, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(y)) { mpfr_clear_flags(); SET_MPFR_WAS_NAN(context, x); result->rc = mpfr_add_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(y)) { MPQ_Object *tempy = NULL; if (!(tempy = GMPy_MPQ_From_Number(y, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); SET_MPFR_WAS_NAN(context, x); result->rc = mpfr_add_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempy); goto done; } if (PyFloat_Check(y)) { mpfr_clear_flags(); SET_MPFR_FLOAT_WAS_NAN(context, x, y); result->rc = mpfr_add_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context)); goto done; } } if (MPFR_Check(y)) { if (PyIntOrLong_Check(x)) { int error; long temp = GMPy_Integer_AsLongAndError(x, &error); if (!error) { mpfr_clear_flags(); SET_MPFR_WAS_NAN(context, y); result->rc = mpfr_add_si(result->f, MPFR(y), temp, GET_MPFR_ROUND(context)); goto done; } else { mpz_set_PyIntOrLong(global.tempz, x); mpfr_clear_flags(); SET_MPFR_WAS_NAN(context, y); result->rc = mpfr_add_z(result->f, MPFR(y), global.tempz, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(x)) { mpfr_clear_flags(); SET_MPFR_WAS_NAN(context, y); result->rc = mpfr_add_z(result->f, MPFR(y), MPZ(x), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(x)) { MPQ_Object *tempx = NULL; if (!(tempx = GMPy_MPQ_From_Number(x, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); SET_MPFR_WAS_NAN(context, y); result->rc = mpfr_add_q(result->f, MPFR(y), tempx->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); goto done; } if (PyFloat_Check(x)) { mpfr_clear_flags(); SET_MPFR_FLOAT_WAS_NAN(context, y, x); result->rc = mpfr_add_d(result->f, MPFR(y), PyFloat_AS_DOUBLE(x), GET_MPFR_ROUND(context)); goto done; } } if (IS_REAL(x) && IS_REAL(y)) { MPFR_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = GMPy_MPFR_From_Real(y, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); SET_MPFR_MPFR_WAS_NAN(context, tempx, tempy); result->rc = mpfr_add(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); SYSTEM_ERROR("Internal error in GMPy_Real_Add()."); return NULL; /* LCOV_EXCL_STOP */ done: _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; }