static void bug_div_q_20100810 (void) { mpfr_t x; mpfr_t y; mpq_t q; int inexact; mpfr_init (x); mpfr_init (y); mpq_init (q); /* mpfr_div_q: the inexact value must be set in case of overflow */ mpq_set_ui (q, 3, 4096); mpfr_set_inf (x, +1); mpfr_nextbelow (x); inexact = mpfr_div_q (y, x, q, MPFR_RNDU); if (inexact <= 0) { printf ("Overflow error in mpfr_div_q. "); printf ("Wrong inexact flag: got %d, should be positive.\n", inexact); exit (1); } if (!mpfr_inf_p (y)) { printf ("Overflow error in mpfr_div_q (y, x, q, MPFR_RNDD). "); printf ("\nx = "); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD); printf ("\nq = "); mpq_out_str (stdout, 10, q); printf ("\ny = "); mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD); printf (" (should be +infinity)\n"); exit (1); } mpq_clear (q); mpfr_clear (y); mpfr_clear (x); }
static PyObject * GMPy_Real_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPFR_Check(x)) { if (MPFR_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_div(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } if (PyIntOrLong_Check(y)) { int error; long tempi = GMPy_Integer_AsLongAndError(y, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_div_si(result->f, MPFR(x), tempi, GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } else { mpz_set_PyIntOrLong(global.tempz, y); mpfr_clear_flags(); result->rc = mpfr_div_z(result->f, MPFR(x), global.tempz, GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } } if (CHECK_MPZANY(y)) { mpfr_clear_flags(); result->rc = mpfr_div_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); 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_div_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); Py_DECREF((PyObject*)tempy); goto done; } if (PyFloat_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_div_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } } if (MPFR_Check(y)) { if (PyIntOrLong_Check(x)) { int error; long tempi = GMPy_Integer_AsLongAndError(x, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_si_div(result->f, tempi, MPFR(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } } /* Since mpfr_z_div does not exist, this combination is handled at the * end by converting x to an mpfr. Ditto for rational.*/ if (PyFloat_Check(x)) { mpfr_clear_flags(); result->rc = mpfr_d_div(result->f, PyFloat_AS_DOUBLE(x), MPFR(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } } /* Handle the remaining cases. * Note: verify that MPZ if converted at full precision! */ 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_div(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; done: _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; }
static void bug_mul_div_q_20100818 (void) { mpq_t qa, qb; mpfr_t x1, x2, y1, y2, y3; mpfr_exp_t emin, emax, e; int inex; int rnd; emin = mpfr_get_emin (); emax = mpfr_get_emax (); set_emin (MPFR_EMIN_MIN); set_emax (MPFR_EMAX_MAX); mpq_init (qa); mpq_init (qb); mpfr_inits2 (32, x1, x2, y1, y2, y3, (mpfr_ptr) 0); mpq_set_ui (qa, 3, 17); mpq_set_ui (qb, 17, 3); inex = mpfr_set_ui (x1, 7, MPFR_RNDN); MPFR_ASSERTN (inex == 0); e = MPFR_EMAX_MAX - 3; inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN); /* x2 = x1 * 2^e */ MPFR_ASSERTN (inex == 0); RND_LOOP(rnd) { mpfr_mul_q (y1, x1, qa, (mpfr_rnd_t) rnd); mpfr_div_q (y3, x1, qb, (mpfr_rnd_t) rnd); MPFR_ASSERTN (mpfr_equal_p (y1, y3)); inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN); MPFR_ASSERTN (inex == 0); inex = mpfr_mul (y3, y3, y1, MPFR_RNDN); /* y3 = y1 * 2^e */ MPFR_ASSERTN (inex == 0); mpfr_mul_q (y2, x2, qa, (mpfr_rnd_t) rnd); if (! mpfr_equal_p (y2, y3)) { printf ("Error 1 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd); printf ("Expected "); mpfr_dump (y3); printf ("Got "); mpfr_dump (y2); exit (1); } mpfr_div_q (y2, x2, qb, (mpfr_rnd_t) rnd); if (! mpfr_equal_p (y2, y3)) { printf ("Error 2 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd); printf ("Expected "); mpfr_dump (y3); printf ("Got "); mpfr_dump (y2); exit (1); } } e = MPFR_EMIN_MIN; inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN); /* x2 = x1 * 2^e */ MPFR_ASSERTN (inex == 0); RND_LOOP(rnd) { mpfr_div_q (y1, x1, qa, (mpfr_rnd_t) rnd); mpfr_mul_q (y3, x1, qb, (mpfr_rnd_t) rnd); MPFR_ASSERTN (mpfr_equal_p (y1, y3)); inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN); MPFR_ASSERTN (inex == 0); inex = mpfr_mul (y3, y3, y1, MPFR_RNDN); /* y3 = y1 * 2^e */ MPFR_ASSERTN (inex == 0); mpfr_div_q (y2, x2, qa, (mpfr_rnd_t) rnd); if (! mpfr_equal_p (y2, y3)) { printf ("Error 3 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd); printf ("Expected "); mpfr_dump (y3); printf ("Got "); mpfr_dump (y2); exit (1); } mpfr_mul_q (y2, x2, qb, (mpfr_rnd_t) rnd); if (! mpfr_equal_p (y2, y3)) { printf ("Error 4 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd); printf ("Expected "); mpfr_dump (y3); printf ("Got "); mpfr_dump (y2); exit (1); } } mpq_clear (qa); mpq_clear (qb); mpfr_clears (x1, x2, y1, y2, y3, (mpfr_ptr) 0); set_emin (emin); set_emax (emax); }
static void special (void) { mpfr_t x, y; mpq_t q; mpz_t z; int res = 0; mpfr_init (x); mpfr_init (y); mpq_init (q); mpz_init (z); /* cancellation in mpfr_add_q */ mpfr_set_prec (x, 60); mpfr_set_prec (y, 20); mpz_set_str (mpq_numref (q), "-187207494", 10); mpz_set_str (mpq_denref (q), "5721", 10); mpfr_set_str_binary (x, "11111111101001011011100101100011011110010011100010000100001E-44"); mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("cancelation in add_q", mpfr_cmp_ui_2exp (y, 256783, -64) == 0); mpfr_set_prec (x, 19); mpfr_set_str_binary (x, "0.1011110101110011100E0"); mpz_set_str (mpq_numref (q), "187207494", 10); mpz_set_str (mpq_denref (q), "5721", 10); mpfr_set_prec (y, 29); mpfr_add_q (y, x, q, MPFR_RNDD); mpfr_set_prec (x, 29); mpfr_set_str_binary (x, "11111111101001110011010001001E-14"); CHECK_FOR ("cancelation in add_q", mpfr_cmp (x,y) == 0); /* Inf */ mpfr_set_inf (x, 1); mpz_set_str (mpq_numref (q), "395877315", 10); mpz_set_str (mpq_denref (q), "3508975966", 10); mpfr_set_prec (y, 118); mpfr_add_q (y, x, q, MPFR_RNDU); CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0); mpfr_sub_q (y, x, q, MPFR_RNDU); CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0); /* Nan */ MPFR_SET_NAN (x); mpfr_add_q (y, x, q, MPFR_RNDU); CHECK_FOR ("nan", mpfr_nan_p (y)); mpfr_sub_q (y, x, q, MPFR_RNDU); CHECK_FOR ("nan", mpfr_nan_p (y)); /* Exact value */ mpfr_set_prec (x, 60); mpfr_set_prec (y, 60); mpfr_set_str1 (x, "0.5"); mpz_set_str (mpq_numref (q), "3", 10); mpz_set_str (mpq_denref (q), "2", 10); res = mpfr_add_q (y, x, q, MPFR_RNDU); CHECK_FOR ("0.5+3/2", mpfr_cmp_ui(y, 2)==0 && res==0); res = mpfr_sub_q (y, x, q, MPFR_RNDU); CHECK_FOR ("0.5-3/2", mpfr_cmp_si(y, -1)==0 && res==0); /* Inf Rationnal */ mpq_set_ui (q, 1, 0); mpfr_set_str1 (x, "0.5"); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5+1/0", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5-1/0", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0); mpq_set_si (q, -1, 0); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5+ -1/0", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5- -1/0", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0); res = mpfr_div_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5 / (-1/0)", mpfr_zero_p (y) && MPFR_IS_NEG (y) && res == 0); mpq_set_ui (q, 1, 0); mpfr_set_inf (x, 1); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("+Inf + +Inf", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("+Inf - +Inf", MPFR_IS_NAN (y) && res == 0); mpfr_set_inf (x, -1); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("-Inf + +Inf", MPFR_IS_NAN (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("-Inf - +Inf", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0); mpq_set_si (q, -1, 0); mpfr_set_inf (x, 1); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("+Inf + -Inf", MPFR_IS_NAN (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("+Inf - -Inf", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0); mpfr_set_inf (x, -1); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("-Inf + -Inf", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("-Inf - -Inf", MPFR_IS_NAN (y) && res == 0); /* 0 */ mpq_set_ui (q, 0, 1); mpfr_set_ui (x, 42, MPFR_RNDN); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("42+0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("42-0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0); res = mpfr_mul_q (y, x, q, MPFR_RNDN); CHECK_FOR ("42*0/1", mpfr_zero_p (y) && MPFR_IS_POS (y) && res == 0); mpfr_clear_flags (); res = mpfr_div_q (y, x, q, MPFR_RNDN); CHECK_FOR ("42/(0/1)", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0 && mpfr_divby0_p ()); mpz_set_ui (z, 0); mpfr_clear_flags (); res = mpfr_div_z (y, x, z, MPFR_RNDN); CHECK_FORZ ("42/0", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0 && mpfr_divby0_p ()); mpz_clear (z); mpq_clear (q); mpfr_clear (x); mpfr_clear (y); }