Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}