int
mpfr_sub_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
{
  int inexact;
  mpfr_t d;
  MPFR_SAVE_EXPO_DECL (expo);

  MPFR_LOG_FUNC (("b[%#R]=%R c=%.20g rnd=%d", b, b, c, rnd_mode),
                 ("a[%#R]=%R", a, a));

  MPFR_SAVE_EXPO_MARK (expo);

  mpfr_init2 (d, IEEE_DBL_MANT_DIG);
  inexact = mpfr_set_d (d, c, rnd_mode);
  MPFR_ASSERTN (inexact == 0);

  mpfr_clear_flags ();
  inexact = mpfr_sub (a, b, d, rnd_mode);
  MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);

  mpfr_clear(d);
  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (a, inexact, rnd_mode);
}
Пример #2
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y;
  mpfr_exp_t emin, emax;
  int inex, ov;

  tests_start_mpfr ();

  special_overflow ();
  emax_m_eps ();
  exp_range ();

  mpfr_init (x);
  mpfr_init (y);

  mpfr_set_ui (x, 4, MPFR_RNDN);
  mpfr_exp10 (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 10000) != 0)
    {
      printf ("Error for 10^4, MPFR_RNDN\n");
      exit (1);
    }
  mpfr_exp10 (y, x, MPFR_RNDD);
  if (mpfr_cmp_ui (y, 10000) != 0)
    {
      printf ("Error for 10^4, MPFR_RNDD\n");
      exit (1);
    }
  mpfr_exp10 (y, x, MPFR_RNDU);
  if (mpfr_cmp_ui (y, 10000) != 0)
    {
      printf ("Error for 10^4, MPFR_RNDU\n");
      exit (1);
    }

  mpfr_set_prec (x, 10);
  mpfr_set_prec (y, 10);
  /* save emin */
  emin = mpfr_get_emin ();
  set_emin (-11);
  mpfr_set_si (x, -4, MPFR_RNDN);
  mpfr_exp10 (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
      printf ("Error for emin = -11, x = -4, RNDN\n");
      printf ("Expected +0\n");
      printf ("Got      "); mpfr_print_binary (y); puts ("");
      exit (1);
    }
  /* restore emin */
  set_emin (emin);

  /* save emax */
  emax = mpfr_get_emax ();
  set_emax (13);
  mpfr_set_ui (x, 4, MPFR_RNDN);
  mpfr_exp10 (y, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for emax = 13, x = 4, RNDN\n");
      printf ("Expected +inf\n");
      printf ("Got      "); mpfr_print_binary (y); puts ("");
      exit (1);
    }
  /* restore emax */
  set_emax (emax);

  MPFR_SET_INF (x);
  MPFR_SET_POS (x);
  mpfr_exp10 (y, x, MPFR_RNDN);
  if (!MPFR_IS_INF (y))
    {
      printf ("evaluation of function in INF does not return INF\n");
      exit (1);
    }

  MPFR_CHANGE_SIGN (x);
  mpfr_exp10 (y, x, MPFR_RNDN);
  if (!MPFR_IS_ZERO (y))
    {
      printf ("evaluation of function in -INF does not return 0\n");
      exit (1);
    }

  MPFR_SET_NAN (x);
  mpfr_exp10 (y, x, MPFR_RNDN);
  if (!MPFR_IS_NAN (y))
    {
      printf ("evaluation of function in NaN does not return NaN\n");
      exit (1);
    }

  if ((mpfr_uexp_t) 8 << 31 != 0 ||
      mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000)
    {
      /* emax <= 10000000000 */
      mpfr_set_prec (x, 40);
      mpfr_set_prec (y, 40);
      mpfr_set_str (x, "3010299957", 10, MPFR_RNDN);
      mpfr_clear_flags ();
      inex = mpfr_exp10 (y, x, MPFR_RNDN);
      ov = mpfr_overflow_p ();
      if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && ov))
        {
          printf ("Overflow error for x = 3010299957, MPFR_RNDN.\n");
          mpfr_dump (y);
          printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
          exit (1);
        }
    }

  test_generic (2, 100, 100);

  mpfr_clear (x);
  mpfr_clear (y);

  overfl_exp10_0 ();

  data_check ("data/exp10", mpfr_exp10, "mpfr_exp10");

  tests_end_mpfr ();
  return 0;
}
Пример #3
0
static void
test_underflow1 (void)
{
  mpfr_t x, y, z, r;
  int inex, signy, signz, rnd, err = 0;

  mpfr_inits2 (8, x, y, z, r, (void *) 0);

  MPFR_SET_POS (x);
  mpfr_setmin (x, mpfr_get_emin ());  /* x = 0.1@emin */

  for (signy = -1; signy <= 1; signy += 2)
    {
      mpfr_set_si_2exp (y, signy, -1, GMP_RNDN);  /* |y| = 1/2 */
      for (signz = -3; signz <= 3; signz += 2)
        {
          RND_LOOP (rnd)
            {
              mpfr_set_si (z, signz, GMP_RNDN);
              if (ABS (signz) != 1)
                mpfr_setmax (z, mpfr_get_emax ());
              /* |z| = 1 or 2^emax - ulp */
              mpfr_clear_flags ();
              inex = mpfr_fma (r, x, y, z, rnd);
#define ERRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n  "
              if (mpfr_nanflag_p ())
                {
                  printf (ERRTU1 "NaN flag is set\n", signy, signz,
                          mpfr_print_rnd_mode (rnd));
                  err = 1;
                }
              if (signy < 0 && (rnd == GMP_RNDD ||
                                (rnd == GMP_RNDZ && signz > 0)))
                mpfr_nextbelow (z);
              if (signy > 0 && (rnd == GMP_RNDU ||
                                (rnd == GMP_RNDZ && signz < 0)))
                mpfr_nextabove (z);
              if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0))
                {
                  printf (ERRTU1 "wrong overflow flag\n", signy, signz,
                          mpfr_print_rnd_mode (rnd));
                  err = 1;
                }
              if (mpfr_underflow_p ())
                {
                  printf (ERRTU1 "underflow flag is set\n", signy, signz,
                          mpfr_print_rnd_mode (rnd));
                  err = 1;
                }
              if (! mpfr_equal_p (r, z))
                {
                  printf (ERRTU1 "got ", signy, signz,
                          mpfr_print_rnd_mode (rnd));
                  mpfr_print_binary (r);
                  printf (" instead of ");
                  mpfr_print_binary (z);
                  printf ("\n");
                  err = 1;
                }
              if (inex >= 0 && (rnd == GMP_RNDD ||
                                (rnd == GMP_RNDZ && signz > 0) ||
                                (rnd == GMP_RNDN && signy > 0)))
                {
                  printf (ERRTU1 "ternary value = %d instead of < 0\n",
                          signy, signz, mpfr_print_rnd_mode (rnd), inex);
                  err = 1;
                }
              if (inex <= 0 && (rnd == GMP_RNDU ||
                                (rnd == GMP_RNDZ && signz < 0) ||
                                (rnd == GMP_RNDN && signy < 0)))
                {
                  printf (ERRTU1 "ternary value = %d instead of > 0\n",
                          signy, signz, mpfr_print_rnd_mode (rnd), inex);
                  err = 1;
                }
            }
        }
    }

  if (err)
    exit (1);
  mpfr_clears (x, y, z, r, (void *) 0);
}
Пример #4
0
static void
underflowed_cothinf (void)
{
  mpfr_t x, y;
  int i, inex, rnd, err = 0;
  mpfr_exp_t old_emin;

  old_emin = mpfr_get_emin ();

  mpfr_init2 (x, 8);
  mpfr_init2 (y, 8);

  for (i = -1; i <= 1; i += 2)
    RND_LOOP (rnd)
      {
        mpfr_set_inf (x, i);
        mpfr_clear_flags ();
        set_emin (2);  /* 1 is not representable. */
        inex = mpfr_coth (x, x, (mpfr_rnd_t) rnd);
        set_emin (old_emin);
        if (! mpfr_underflow_p ())
          {
            printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
                    "  The underflow flag is not set.\n",
                    i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            err = 1;
          }
        mpfr_set_si (y, (i < 0 && (rnd == MPFR_RNDD || rnd == MPFR_RNDA)) ||
                        (i > 0 && (rnd == MPFR_RNDU || rnd == MPFR_RNDA))
                     ? 2 : 0, MPFR_RNDN);
        if (i < 0)
          mpfr_neg (y, y, MPFR_RNDN);
        if (! (mpfr_equal_p (x, y) &&
               MPFR_MULT_SIGN (MPFR_SIGN (x), MPFR_SIGN (y)) > 0))
          {
            printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
                    "  Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            mpfr_print_binary (x);
            printf (" instead of ");
            mpfr_print_binary (y);
            printf (".\n");
            err = 1;
          }
        if ((rnd == MPFR_RNDD ||
             (i > 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex >= 0)
          {
            printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
                    "  The inexact value must be negative.\n",
                    i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            err = 1;
          }
        if ((rnd == MPFR_RNDU ||
             (i < 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex <= 0)
          {
            printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
                    "  The inexact value must be positive.\n",
                    i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            err = 1;
          }
      }

  if (err)
    exit (1);
  mpfr_clear (x);
  mpfr_clear (y);
}
Пример #5
0
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;
}
Пример #6
0
static void
test_2exp (void)
{
  mpfr_t x;
  int res;

  mpfr_init2 (x, 32);

  mpfr_set_ui_2exp (x, 1, 0, MPFR_RNDN);
  if (mpfr_cmp_ui(x, 1))
    ERROR("(1U,0)");

  mpfr_set_ui_2exp (x, 1024, -10, MPFR_RNDN);
  if (mpfr_cmp_ui(x, 1))
    ERROR("(1024U,-10)");

  mpfr_set_ui_2exp (x, 1024, 10, MPFR_RNDN);
  if (mpfr_cmp_ui(x, 1024*1024))
    ERROR("(1024U,+10)");

  mpfr_set_si_2exp (x, -1024L * 1024L, -10, MPFR_RNDN);
  if (mpfr_cmp_si(x, -1024))
    ERROR("(1M,-10)");

  mpfr_set_ui_2exp (x, 0x92345678, 16, MPFR_RNDN);
  if (mpfr_cmp_str (x, "92345678@4", 16, MPFR_RNDN))
    ERROR("(x92345678U,+16)");

  mpfr_set_si_2exp (x, -0x1ABCDEF0, -256, MPFR_RNDN);
  if (mpfr_cmp_str (x, "-1ABCDEF0@-64", 16, MPFR_RNDN))
    ERROR("(-x1ABCDEF0,-256)");

  mpfr_set_prec (x, 2);
  res = mpfr_set_si_2exp (x, 7, 10, MPFR_RNDU);
  if (mpfr_cmp_ui (x, 1<<13) || res <= 0)
    ERROR ("Prec 2 + si_2exp");

  res = mpfr_set_ui_2exp (x, 7, 10, MPFR_RNDU);
  if (mpfr_cmp_ui (x, 1<<13) || res <= 0)
    ERROR ("Prec 2 + ui_2exp");

  mpfr_clear_flags ();
  mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
  if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
    ERROR ("mpfr_set_ui_2exp and overflow (bad result)");
  if (!mpfr_overflow_p ())
    ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)");

  mpfr_clear_flags ();
  mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
  if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
    ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)");
  if (!mpfr_overflow_p ())
    ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)");

  mpfr_clear_flags ();
  mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, MPFR_RNDN);
  if (!mpfr_inf_p (x) || MPFR_IS_POS (x))
    ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)");
  if (!mpfr_overflow_p ())
    ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)");

  mpfr_clear (x);
}
Пример #7
0
static void
check_special (void)
{
  mpfr_t  a, d, q;
  mpfr_exp_t emax, emin;
  int i;

  mpfr_init2 (a, 100L);
  mpfr_init2 (d, 100L);
  mpfr_init2 (q, 100L);

  /* 1/nan == nan */
  mpfr_set_ui (a, 1L, MPFR_RNDN);
  MPFR_SET_NAN (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);

  /* nan/1 == nan */
  MPFR_SET_NAN (a);
  mpfr_set_ui (d, 1L, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);

  /* +inf/1 == +inf */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  mpfr_set_ui (d, 1L, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* +inf/-1 == -inf */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  mpfr_set_si (d, -1, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -inf/1 == -inf */
  MPFR_SET_INF (a);
  MPFR_SET_NEG (a);
  mpfr_set_ui (d, 1L, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -inf/-1 == +inf */
  MPFR_SET_INF (a);
  MPFR_SET_NEG (a);
  mpfr_set_si (d, -1, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* 1/+inf == +0 */
  mpfr_set_ui (a, 1L, MPFR_RNDN);
  MPFR_SET_INF (d);
  MPFR_SET_POS (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_number_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) == 0);
  MPFR_ASSERTN (MPFR_IS_POS (q));
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* 1/-inf == -0 */
  mpfr_set_ui (a, 1L, MPFR_RNDN);
  MPFR_SET_INF (d);
  MPFR_SET_NEG (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_number_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) == 0);
  MPFR_ASSERTN (MPFR_IS_NEG (q));
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -1/+inf == -0 */
  mpfr_set_si (a, -1, MPFR_RNDN);
  MPFR_SET_INF (d);
  MPFR_SET_POS (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_number_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) == 0);
  MPFR_ASSERTN (MPFR_IS_NEG (q));
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -1/-inf == +0 */
  mpfr_set_si (a, -1, MPFR_RNDN);
  MPFR_SET_INF (d);
  MPFR_SET_NEG (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_number_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) == 0);
  MPFR_ASSERTN (MPFR_IS_POS (q));
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* 0/0 == nan */
  mpfr_set_ui (a, 0L, MPFR_RNDN);
  mpfr_set_ui (d, 0L, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);

  /* +inf/+inf == nan */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  MPFR_SET_INF (d);
  MPFR_SET_POS (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);

  /* 1/+0 = +inf */
  mpfr_set_ui (a, 1, MPFR_RNDZ);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);

  /* 1/-0 = -inf */
  mpfr_set_ui (a, 1, MPFR_RNDZ);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_neg (d, d, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);

  /* -1/+0 = -inf */
  mpfr_set_si (a, -1, MPFR_RNDZ);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);

  /* -1/-0 = +inf */
  mpfr_set_si (a, -1, MPFR_RNDZ);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_neg (d, d, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);

  /* +inf/+0 = +inf */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* +inf/-0 = -inf */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_neg (d, d, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -inf/+0 = -inf */
  MPFR_SET_INF (a);
  MPFR_SET_NEG (a);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -inf/-0 = +inf */
  MPFR_SET_INF (a);
  MPFR_SET_NEG (a);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_neg (d, d, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* check overflow */
  emax = mpfr_get_emax ();
  set_emax (1);
  mpfr_set_ui (a, 1, MPFR_RNDZ);
  mpfr_set_ui (d, 1, MPFR_RNDZ);
  mpfr_div_2exp (d, d, 1, MPFR_RNDZ);
  mpfr_clear_flags ();
  test_div (q, a, d, MPFR_RNDU); /* 1 / 0.5 = 2 -> overflow */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT));
  set_emax (emax);

  /* check underflow */
  emin = mpfr_get_emin ();
  set_emin (-1);
  mpfr_set_ui (a, 1, MPFR_RNDZ);
  mpfr_div_2exp (a, a, 2, MPFR_RNDZ);
  mpfr_set_prec (d, mpfr_get_prec (q) + 8);
  for (i = -1; i <= 1; i++)
    {
      int sign;

      /* Test 2^(-2) / (+/- (2 + eps)), with eps < 0, eps = 0, eps > 0.
         -> underflow.
         With div.c r5513, this test fails for eps > 0 in MPFR_RNDN. */
      mpfr_set_ui (d, 2, MPFR_RNDZ);
      if (i < 0)
        mpfr_nextbelow (d);
      if (i > 0)
        mpfr_nextabove (d);
      for (sign = 0; sign <= 1; sign++)
        {
          mpfr_clear_flags ();
          test_div (q, a, d, MPFR_RNDZ); /* result = 0 */
          MPFR_ASSERTN (__gmpfr_flags ==
                        (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT));
          MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q));
          MPFR_ASSERTN (MPFR_IS_ZERO (q));
          mpfr_clear_flags ();
          test_div (q, a, d, MPFR_RNDN); /* result = 0 iff eps >= 0 */
          MPFR_ASSERTN (__gmpfr_flags ==
                        (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT));
          MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q));
          if (i < 0)
            mpfr_nexttozero (q);
          MPFR_ASSERTN (MPFR_IS_ZERO (q));
          mpfr_neg (d, d, MPFR_RNDN);
        }
    }
  set_emin (emin);

  mpfr_clear (a);
  mpfr_clear (d);
  mpfr_clear (q);
}
Пример #8
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y;
  mpfr_exp_t emin, emax;

  tests_start_mpfr ();

  special_overflow ();
  emax_m_eps ();
  exp_range ();

  mpfr_init (x);
  mpfr_init (y);

  mpfr_set_ui (x, 4, MPFR_RNDN);
  mpfr_exp2 (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 16) != 0)
    {
      printf ("Error for 2^4, MPFR_RNDN\n");
      exit (1);
    }
  mpfr_exp2 (y, x, MPFR_RNDD);
  if (mpfr_cmp_ui (y, 16) != 0)
    {
      printf ("Error for 2^4, MPFR_RNDD\n");
      exit (1);
    }
  mpfr_exp2 (y, x, MPFR_RNDU);
  if (mpfr_cmp_ui (y, 16) != 0)
    {
      printf ("Error for 2^4, MPFR_RNDU\n");
      exit (1);
    }

  mpfr_set_si (x, -4, MPFR_RNDN);
  mpfr_exp2 (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui_2exp (y, 1, -4) != 0)
    {
      printf ("Error for 2^(-4), MPFR_RNDN\n");
      exit (1);
    }
  mpfr_exp2 (y, x, MPFR_RNDD);
  if (mpfr_cmp_ui_2exp (y, 1, -4) != 0)
    {
      printf ("Error for 2^(-4), MPFR_RNDD\n");
      exit (1);
    }
  mpfr_exp2 (y, x, MPFR_RNDU);
  if (mpfr_cmp_ui_2exp (y, 1, -4) != 0)
    {
      printf ("Error for 2^(-4), MPFR_RNDU\n");
      exit (1);
    }

  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);
  mpfr_set_str (x, /*-1683977482443233.0 / 2199023255552.0*/
                "-7.6578429909351734750089235603809357e2", 10, MPFR_RNDN);
  mpfr_exp2 (y, x, MPFR_RNDN);
  if (mpfr_cmp_str1 (y, "2.991959870867646566478e-231"))
    {
      printf ("Error for x=-1683977482443233/2^41\n");
      exit (1);
    }

  mpfr_set_prec (x, 10);
  mpfr_set_prec (y, 10);
  /* save emin */
  emin = mpfr_get_emin ();
  set_emin (-10);
  mpfr_set_si (x, -12, MPFR_RNDN);
  mpfr_exp2 (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
      printf ("Error for x=emin-2, RNDN\n");
      printf ("Expected +0\n");
      printf ("Got      "); mpfr_print_binary (y); puts ("");
      exit (1);
    }
  /* restore emin */
  set_emin (emin);

  /* save emax */
  emax = mpfr_get_emax ();
  set_emax (10);
  mpfr_set_ui (x, 11, MPFR_RNDN);
  mpfr_exp2 (y, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for x=emax+1, RNDN\n");
      exit (1);
    }
  /* restore emax */
  set_emax (emax);

  MPFR_SET_INF(x);
  MPFR_SET_POS(x);
  mpfr_exp2 (y, x, MPFR_RNDN);
  if(!MPFR_IS_INF(y))
    {
      printf ("evaluation of function in INF does not return INF\n");
      exit (1);
    }

  MPFR_CHANGE_SIGN(x);
  mpfr_exp2 (y, x, MPFR_RNDN);
  if(!MPFR_IS_ZERO(y))
    {
      printf ("evaluation of function in -INF does not return 0\n");
      exit (1);
    }

  MPFR_SET_NAN(x);
  mpfr_exp2 (y, x, MPFR_RNDN);
  if(!MPFR_IS_NAN(y))
    {
      printf ("evaluation of function in NaN does not return NaN\n");
      exit (1);
    }

  if ((mpfr_uexp_t) 8 << 31 != 0 ||
      mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000)
    {
      /* emax <= 10000000000 */
      mpfr_set_prec (x, 40);
      mpfr_set_prec (y, 40);
      mpfr_set_str (x, "10000000000.5", 10, MPFR_RNDN);
      mpfr_clear_flags ();
      mpfr_exp2 (y, x, MPFR_RNDN);
      if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && mpfr_overflow_p ()))
        {
          printf ("exp2(10000000000.5) should overflow.\n");
          exit (1);
        }
    }

  mpfr_set_prec (x, 2);
  mpfr_set_prec (y, 2);
  mpfr_set_str_binary (x, "-1.0E-26");
  mpfr_exp2 (y, x, MPFR_RNDD);
  mpfr_set_str_binary (x, "1.1E-1");
  if (mpfr_cmp (x, y))
    {
      printf ("Error for exp(-2^(-26)) for prec=2\n");
      exit (1);
    }

  test_generic (2, 100, 100);

  mpfr_clear (x);
  mpfr_clear (y);

  overflowed_exp2_0 ();

  data_check ("data/exp2", mpfr_exp2, "mpfr_exp2");

  tests_end_mpfr ();
  return 0;
}
static int
tiny_aux (int stop, mpfr_exp_t e)
{
  mpfr_t x, y, z;
  int r, s, spm, inex, err = 0;
  int expected_dir[2][5] = { { 1, -1, 1, -1, 1 }, { 1, 1, 1, -1, -1 } };
  mpfr_exp_t saved_emax;

  saved_emax = mpfr_get_emax ();

  mpfr_init2 (x, 32);
  mpfr_inits2 (8, y, z, (mpfr_ptr) 0);

  mpfr_set_ui_2exp (x, 1, e, MPFR_RNDN);
  spm = 1;
  for (s = 0; s < 2; s++)
    {
      RND_LOOP(r)
        {
          mpfr_rnd_t rr = (mpfr_rnd_t) r;
          mpfr_exp_t exponent, emax;

          /* Exponent of the rounded value in unbounded exponent range. */
          exponent = expected_dir[s][r] < 0 && s == 0 ? - e : 1 - e;

          for (emax = exponent - 1; emax <= exponent; emax++)
            {
              unsigned int flags, expected_flags = MPFR_FLAGS_INEXACT;
              int overflow, expected_inex = expected_dir[s][r];

              if (emax > MPFR_EMAX_MAX)
                break;
              mpfr_set_emax (emax);

              mpfr_clear_flags ();
              inex = mpfr_gamma (y, x, rr);
              flags = __gmpfr_flags;
              mpfr_clear_flags ();
              mpfr_set_si_2exp (z, spm, - e, MPFR_RNDU);
              overflow = mpfr_overflow_p ();
              /* z is 1/x - euler rounded toward +inf */

              if (overflow && rr == MPFR_RNDN && s == 1)
                expected_inex = -1;

              if (expected_inex < 0)
                mpfr_nextbelow (z); /* 1/x - euler rounded toward -inf */

              if (exponent > emax)
                expected_flags |= MPFR_FLAGS_OVERFLOW;

              if (!(mpfr_equal_p (y, z) && flags == expected_flags
                    && SAME_SIGN (inex, expected_inex)))
                {
                  printf ("Error in tiny for s = %d, r = %s, emax = %"
                          MPFR_EXP_FSPEC "d%s\n  on ",
                          s, mpfr_print_rnd_mode (rr), emax,
                          exponent > emax ? " (overflow)" : "");
                  mpfr_dump (x);
                  printf ("  expected inex = %2d, ", expected_inex);
                  mpfr_dump (z);
                  printf ("  got      inex = %2d, ", SIGN (inex));
                  mpfr_dump (y);
                  printf ("  expected flags = %u, got %u\n",
                          expected_flags, flags);
                  if (stop)
                    exit (1);
                  err = 1;
                }
            }
        }
      mpfr_neg (x, x, MPFR_RNDN);
      spm = - spm;
    }

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
  mpfr_set_emax (saved_emax);
  return err;
}
static void
exprange (void)
{
  mpfr_exp_t emin, emax;
  mpfr_t x, y, z;
  int inex1, inex2;
  unsigned int flags1, flags2;

  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();

  mpfr_init2 (x, 16);
  mpfr_inits2 (8, y, z, (mpfr_ptr) 0);

  mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN);
  mpfr_clear_flags ();
  inex1 = mpfr_gamma (y, x, MPFR_RNDN);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emin (0);
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDN);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emin (emin);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test1)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_set_ui_2exp (x, 32769, -60, MPFR_RNDN);
  mpfr_clear_flags ();
  inex1 = mpfr_gamma (y, x, MPFR_RNDD);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (45);
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (emax);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test2)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_set_emax (44);
  mpfr_clear_flags ();
  inex1 = mpfr_check_range (y, inex1, MPFR_RNDD);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (emax);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test3)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_set_ui_2exp (x, 1, -60, MPFR_RNDN);
  mpfr_clear_flags ();
  inex1 = mpfr_gamma (y, x, MPFR_RNDD);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (60);
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (emax);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test4)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  MPFR_ASSERTN (MPFR_EMIN_MIN == - MPFR_EMAX_MAX);
  mpfr_set_emin (MPFR_EMIN_MIN);
  mpfr_set_emax (MPFR_EMAX_MAX);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_nextabove (x);  /* x = 2^(emin - 1) */
  mpfr_set_inf (y, 1);
  inex1 = 1;
  flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
  mpfr_clear_flags ();
  /* MPFR_RNDU: overflow, infinity since 1/x = 2^(emax + 1) */
  inex2 = mpfr_gamma (z, x, MPFR_RNDU);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test5)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_clear_flags ();
  /* MPFR_RNDN: overflow, infinity since 1/x = 2^(emax + 1) */
  inex2 = mpfr_gamma (z, x, MPFR_RNDN);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test6)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_nextbelow (y);
  inex1 = -1;
  mpfr_clear_flags ();
  /* MPFR_RNDD: overflow, maxnum since 1/x = 2^(emax + 1) */
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test7)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_mul_2ui (x, x, 1, MPFR_RNDN);  /* x = 2^emin */
  mpfr_set_inf (y, 1);
  inex1 = 1;
  flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
  mpfr_clear_flags ();
  /* MPFR_RNDU: overflow, infinity since 1/x = 2^emax */
  inex2 = mpfr_gamma (z, x, MPFR_RNDU);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test8)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_clear_flags ();
  /* MPFR_RNDN: overflow, infinity since 1/x = 2^emax */
  inex2 = mpfr_gamma (z, x, MPFR_RNDN);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test9)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_nextbelow (y);
  inex1 = -1;
  flags1 = MPFR_FLAGS_INEXACT;
  mpfr_clear_flags ();
  /* MPFR_RNDD: no overflow, maxnum since 1/x = 2^emax and euler > 0 */
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test10)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_set_emin (emin);
  mpfr_set_emax (emax);

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
static void
underflow (mpfr_exp_t e)
{
  mpfr_t x, y, z1, z2;
  mpfr_exp_t emin;
  int i, k;
  int prec;
  int rnd;
  int div;
  int inex1, inex2;
  unsigned int flags1, flags2;

  /* Test mul_2si(x, e - k), div_2si(x, k - e) and div_2ui(x, k - e)
   * with emin = e, x = 1 + i/16, i in { -1, 0, 1 }, and k = 1 to 4,
   * by comparing the result with the one of a simple division.
   */
  emin = mpfr_get_emin ();
  set_emin (e);
  mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
  for (i = 15; i <= 17; i++)
    {
      inex1 = mpfr_set_ui_2exp (x, i, -4, MPFR_RNDN);
      MPFR_ASSERTN (inex1 == 0);
      for (prec = 6; prec >= 3; prec -= 3)
        {
          mpfr_inits2 (prec, z1, z2, (mpfr_ptr) 0);
          RND_LOOP (rnd)
            for (k = 1; k <= 4; k++)
              {
                /* The following one is assumed to be correct. */
                inex1 = mpfr_mul_2si (y, x, e, MPFR_RNDN);
                MPFR_ASSERTN (inex1 == 0);
                inex1 = mpfr_set_ui (z1, 1 << k, MPFR_RNDN);
                MPFR_ASSERTN (inex1 == 0);
                mpfr_clear_flags ();
                /* Do not use mpfr_div_ui to avoid the optimization
                   by mpfr_div_2si. */
                inex1 = mpfr_div (z1, y, z1, (mpfr_rnd_t) rnd);
                flags1 = __gmpfr_flags;

              for (div = 0; div <= 2; div++)
                {
                  mpfr_clear_flags ();
                  inex2 = div == 0 ?
                    mpfr_mul_2si (z2, x, e - k, (mpfr_rnd_t) rnd) : div == 1 ?
                    mpfr_div_2si (z2, x, k - e, (mpfr_rnd_t) rnd) :
                    mpfr_div_2ui (z2, x, k - e, (mpfr_rnd_t) rnd);
                  flags2 = __gmpfr_flags;
                  if (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
                      mpfr_equal_p (z1, z2))
                    continue;
                  printf ("Error in underflow(");
                  if (e == MPFR_EMIN_MIN)
                    printf ("MPFR_EMIN_MIN");
                  else if (e == emin)
                    printf ("default emin");
                  else
                    printf ("%ld", e);
                  printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d, "
                          "%s\n", div == 0 ? "mul_2si" : div == 1 ?
                          "div_2si" : "div_2ui", i, prec, k,
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  printf ("Expected ");
                  mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN);
                  printf (", inex = %d, flags = %u\n", SIGN (inex1), flags1);
                  printf ("Got      ");
                  mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN);
                  printf (", inex = %d, flags = %u\n", SIGN (inex2), flags2);
                  exit (1);
                }  /* div */
              }  /* k */
          mpfr_clears (z1, z2, (mpfr_ptr) 0);
        }  /* prec */
    }  /* i */
  mpfr_clears (x, y, (mpfr_ptr) 0);
  set_emin (emin);
}
static void
large (mpfr_exp_t e)
{
  mpfr_t x, y, z;
  mpfr_exp_t emax;
  int inex;
  unsigned int flags;

  emax = mpfr_get_emax ();
  set_emax (e);
  mpfr_init2 (x, 8);
  mpfr_init2 (y, 8);
  mpfr_init2 (z, 4);

  mpfr_set_inf (x, 1);
  mpfr_nextbelow (x);

  mpfr_mul_2si (y, x, -1, MPFR_RNDU);
  mpfr_prec_round (y, 4, MPFR_RNDU);

  mpfr_clear_flags ();
  inex = mpfr_mul_2si (z, x, -1, MPFR_RNDU);
  flags = __gmpfr_flags;

  if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z))
    {
      printf ("Error in large(");
      if (e == MPFR_EMAX_MAX)
        printf ("MPFR_EMAX_MAX");
      else if (e == emax)
        printf ("default emax");
      else if (e <= LONG_MAX)
        printf ("%ld", (long) e);
      else
        printf (">LONG_MAX");
      printf (") for mpfr_mul_2si\n");
      printf ("Expected inex > 0, flags = %u,\n         y = ",
              (unsigned int) MPFR_FLAGS_INEXACT);
      mpfr_dump (y);
      printf ("Got      inex = %d, flags = %u,\n         y = ",
              inex, flags);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_clear_flags ();
  inex = mpfr_div_2si (z, x, 1, MPFR_RNDU);
  flags = __gmpfr_flags;

  if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z))
    {
      printf ("Error in large(");
      if (e == MPFR_EMAX_MAX)
        printf ("MPFR_EMAX_MAX");
      else if (e == emax)
        printf ("default emax");
      else if (e <= LONG_MAX)
        printf ("%ld", (long) e);
      else
        printf (">LONG_MAX");
      printf (") for mpfr_div_2si\n");
      printf ("Expected inex > 0, flags = %u,\n         y = ",
              (unsigned int) MPFR_FLAGS_INEXACT);
      mpfr_dump (y);
      printf ("Got      inex = %d, flags = %u,\n         y = ",
              inex, flags);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_clear_flags ();
  inex = mpfr_div_2ui (z, x, 1, MPFR_RNDU);
  flags = __gmpfr_flags;

  if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z))
    {
      printf ("Error in large(");
      if (e == MPFR_EMAX_MAX)
        printf ("MPFR_EMAX_MAX");
      else if (e == emax)
        printf ("default emax");
      else if (e <= LONG_MAX)
        printf ("%ld", (long) e);
      else
        printf (">LONG_MAX");
      printf (") for mpfr_div_2ui\n");
      printf ("Expected inex > 0, flags = %u,\n         y = ",
              (unsigned int) MPFR_FLAGS_INEXACT);
      mpfr_dump (y);
      printf ("Got      inex = %d, flags = %u,\n         y = ",
              inex, flags);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
  set_emax (emax);
}
Пример #13
0
static void
test_extreme (void)
{
  mpfr_t x, y, z;
  mpfr_exp_t emin, emax;
  mpfr_prec_t p[4] = { 8, 32, 64, 256 };
  int xi, yi, zi, j, r;
  unsigned int flags, ex_flags;

  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();

  mpfr_set_emin (MPFR_EMIN_MIN);
  mpfr_set_emax (MPFR_EMAX_MAX);

  for (xi = 0; xi < 4; xi++)
    {
      mpfr_init2 (x, p[xi]);
      mpfr_setmax (x, MPFR_EMAX_MAX);
      MPFR_ASSERTN (mpfr_check (x));
      for (yi = 0; yi < 4; yi++)
        {
          mpfr_init2 (y, p[yi]);
          mpfr_setmin (y, MPFR_EMIN_MIN);
          for (j = 0; j < 2; j++)
            {
              MPFR_ASSERTN (mpfr_check (y));
              for (zi = 0; zi < 4; zi++)
                {
                  mpfr_init2 (z, p[zi]);
                  RND_LOOP (r)
                    {
                      mpfr_clear_flags ();
                      mpfr_div (z, x, y, (mpfr_rnd_t) r);
                      flags = __gmpfr_flags;
                      MPFR_ASSERTN (mpfr_check (z));
                      ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
                      if (flags != ex_flags)
                        {
                          printf ("Bad flags in test_extreme on z = a/b"
                                  " with %s and\n",
                                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
                          printf ("a = ");
                          mpfr_dump (x);
                          printf ("b = ");
                          mpfr_dump (y);
                          printf ("Expected flags:");
                          flags_out (ex_flags);
                          printf ("Got flags:     ");
                          flags_out (flags);
                          printf ("z = ");
                          mpfr_dump (z);
                          exit (1);
                        }
                      mpfr_clear_flags ();
                      mpfr_div (z, y, x, (mpfr_rnd_t) r);
                      flags = __gmpfr_flags;
                      MPFR_ASSERTN (mpfr_check (z));
                      ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
                      if (flags != ex_flags)
                        {
                          printf ("Bad flags in test_extreme on z = a/b"
                                  " with %s and\n",
                                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
                          printf ("a = ");
                          mpfr_dump (y);
                          printf ("b = ");
                          mpfr_dump (x);
                          printf ("Expected flags:");
                          flags_out (ex_flags);
                          printf ("Got flags:     ");
                          flags_out (flags);
                          printf ("z = ");
                          mpfr_dump (z);
                          exit (1);
                        }
                    }
                  mpfr_clear (z);
                }  /* zi */
              mpfr_nextabove (y);
            }  /* j */
          mpfr_clear (y);
        }  /* yi */
      mpfr_clear (x);
    }  /* xi */

  set_emin (emin);
  set_emax (emax);
}
Пример #14
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;
}
Пример #15
0
static void
check_special_exprange (void)
{
  int inexact, ov;
  unsigned int eflags, gflags;
  mpfr_t xi, xf, x;
  mpfr_exp_t emax;

  emax = mpfr_get_emax ();
  mpfr_init2 (xi, 7);
  mpfr_init2 (xf, 7);
  mpfr_init2 (x, 8);

  mpfr_set_str (x, "0.11111111", 2, MPFR_RNDN);
  for (ov = 0; ov <= 1; ov++)
    {
      const char *s = ov ? "@Inf@" : "1";

      if (ov)
        set_emax (0);
      mpfr_clear_flags ();
      inexact = mpfr_modf (xi, xf, x, MPFR_RNDN);
      gflags = __gmpfr_flags;
      set_emax (emax);
      if (MPFR_NOTZERO (xi) || MPFR_IS_NEG (xi) ||
          mpfr_cmp_str1 (xf, s) != 0)
        {
          printf ("Error in check_special_exprange (ov = %d):"
                  " expected 0 and %s, got\n", ov, s);
          mpfr_out_str (stdout, 2, 0, xi, MPFR_RNDN);
          printf (" and ");
          mpfr_out_str (stdout, 2, 0, xf, MPFR_RNDN);
          printf ("\n");
          exit (1);
        }
      if (inexact != 4)
        {
          printf ("Bad inexact value in check_special_exprange (ov = %d):"
                  " expected 4, got %d\n", ov, inexact);
          exit (1);
        }
      eflags = MPFR_FLAGS_INEXACT | (ov ? MPFR_FLAGS_OVERFLOW : 0);
      if (gflags != eflags)
        {
          printf ("Bad flags in check_special_exprange (ov = %d):"
                  " expected %u, got %u\n", ov, eflags, gflags);
          exit (1);
        }
    }

  /* Test if an overflow occurs in mpfr_set for ope >= opq. */
  mpfr_set_emax (MPFR_EMAX_MAX);
  mpfr_set_inf (x, 1);
  mpfr_nextbelow (x);
  mpfr_clear_flags ();
  inexact = mpfr_modf (xi, xf, x, MPFR_RNDN);
  gflags = __gmpfr_flags;
  if (mpfr_cmp_str1 (xi, "@Inf@") != 0 ||
      MPFR_NOTZERO (xf) || MPFR_IS_NEG (xf))
    {
      printf ("Error in check_special_exprange:"
              " expected 0 and @Inf@, got\n");
      mpfr_out_str (stdout, 2, 0, xi, MPFR_RNDN);
      printf (" and ");
      mpfr_out_str (stdout, 2, 0, xf, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }
  if (inexact != 1)
    {
      printf ("Bad inexact value in check_special_exprange:"
              " expected 1, got %d\n", inexact);
      exit (1);
    }
  eflags = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
  if (gflags != eflags)
    {
      printf ("Bad flags in check_special_exprange:"
              " expected %u, got %u\n", eflags, gflags);
      exit (1);
    }
  set_emax (emax);

  /* Test if an underflow occurs in the general case. TODO */

  mpfr_clears (xi, xf, x, (mpfr_ptr) 0);
}
Пример #16
0
static void
check_nans (void)
{
  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_div_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_div_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_div_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));

  /* 0.0 / 0.0 is nan */
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
  MPFR_ASSERTN (mpfr_nan_p (y));

  /* 1.0 / 0.0 == +inf */
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (MPFR_IS_POS (y));

  /* -1.0 / 0.0 == -inf */
  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (MPFR_IS_NEG (y));

  mpfr_clear (x);
  mpfr_clear (y);
}
Пример #17
0
static void
check_max(void)
{
  mpfr_t xx, yy, zz;
  mpfr_exp_t emin;

  mpfr_init2(xx, 4);
  mpfr_init2(yy, 4);
  mpfr_init2(zz, 4);
  mpfr_set_str1 (xx, "0.68750");
  mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, MPFR_RNDN);
  mpfr_set_str1 (yy, "0.68750");
  mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, MPFR_RNDN);
  mpfr_clear_flags();
  test_mul(zz, xx, yy, MPFR_RNDU);
  if (!(mpfr_overflow_p() && MPFR_IS_INF(zz)))
    {
      printf("check_max failed (should be an overflow)\n");
      exit(1);
    }

  mpfr_clear_flags();
  test_mul(zz, xx, yy, MPFR_RNDD);
  if (mpfr_overflow_p() || MPFR_IS_INF(zz))
    {
      printf("check_max failed (should NOT be an overflow)\n");
      exit(1);
    }
  mpfr_set_str1 (xx, "0.93750");
  mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, MPFR_RNDN);
  if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz)))
    {
      printf("check_max failed (internal error)\n");
      exit(1);
    }
  if (mpfr_cmp(xx, zz) != 0)
    {
      printf("check_max failed: got ");
      mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ);
      printf(" instead of ");
      mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ);
      printf("\n");
      exit(1);
    }

  /* check underflow */
  emin = mpfr_get_emin ();
  set_emin (0);
  mpfr_set_str_binary (xx, "0.1E0");
  mpfr_set_str_binary (yy, "0.1E0");
  test_mul (zz, xx, yy, MPFR_RNDN);
  /* exact result is 0.1E-1, which should round to 0 */
  MPFR_ASSERTN(mpfr_cmp_ui (zz, 0) == 0 && MPFR_IS_POS(zz));
  set_emin (emin);

  /* coverage test for mpfr_powerof2_raw */
  emin = mpfr_get_emin ();
  set_emin (0);
  mpfr_set_prec (xx, mp_bits_per_limb + 1);
  mpfr_set_str_binary (xx, "0.1E0");
  mpfr_nextabove (xx);
  mpfr_set_str_binary (yy, "0.1E0");
  test_mul (zz, xx, yy, MPFR_RNDN);
  /* exact result is just above 0.1E-1, which should round to minfloat */
  MPFR_ASSERTN(mpfr_cmp (zz, yy) == 0);
  set_emin (emin);

  mpfr_clear(xx);
  mpfr_clear(yy);
  mpfr_clear(zz);
}
Пример #18
0
int
main (void)
{
  mpfr_t x;
  mpfr_exp_t emin;

  tests_start_mpfr ();
  emin = mpfr_get_emin ();

  mpfr_init2 (x, IEEE_DBL_MANT_DIG);

  mpfr_set_d (x, 2.34763465, MPFR_RNDN);
  if (mpfr_cmp_d (x, 2.34763465) != 0)
    {
      printf ("Error in mpfr_cmp_d 2.34763465 and ");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
      exit (1);
    }
  if (mpfr_cmp_d (x, 2.345) <= 0)
    {
      printf ("Error in mpfr_cmp_d 2.345 and ");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
      exit (1);
    }
  if (mpfr_cmp_d (x, 2.4) >= 0)
    {
      printf ("Error in mpfr_cmp_d 2.4 and ");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDZ);
  mpfr_neg (x, x, MPFR_RNDZ);
  if (mpfr_cmp_d (x, 0.0))
    {
      printf ("Error in mpfr_cmp_d 0.0 and ");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_ui_div (x, 1, x, MPFR_RNDU);
  if (mpfr_cmp_d (x, 0.0) == 0)
    {
      printf ("Error in mpfr_cmp_d (Inf, 0)\n");
      exit (1);
    }

  /* Test in reduced exponent range. */
  set_emin (1);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  if (mpfr_cmp_d (x, 0.9) <= 0)
    {
      printf ("Error in reduced exponent range.\n");
      exit (1);
    }
  set_emin (emin);

#if !defined(MPFR_ERRDIVZERO)
  /* Check NAN */
  {
    int c;

    mpfr_clear_flags ();
    c = mpfr_cmp_d (x, DBL_NAN);
    if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
      {
        printf ("ERROR for NAN (1)\n");
        printf ("Expected 0, got %d\n", c);
        printf ("Expected flags:");
        flags_out (MPFR_FLAGS_ERANGE);
        printf ("Got flags:     ");
        flags_out (__gmpfr_flags);
#ifdef MPFR_NANISNAN
        printf ("The reason is that NAN == NAN. Please look at the configure "
                "output\nand Section \"In case of problem\" of the INSTALL "
                "file.\n");
#endif
        exit (1);
      }

    mpfr_set_nan (x);
    mpfr_clear_flags ();
    c = mpfr_cmp_d (x, 2.0);
    if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
      {
        printf ("ERROR for NAN (2)\n");
        printf ("Expected 0, got %d\n", c);
        printf ("Expected flags:");
        flags_out (MPFR_FLAGS_ERANGE);
        printf ("Got flags:     ");
        flags_out (__gmpfr_flags);
#ifdef MPFR_NANISNAN
        printf ("The reason is that NAN == NAN. Please look at the configure "
                "output\nand Section \"In case of problem\" of the INSTALL "
                "file.\n");
#endif
        exit (1);
      }
  }
#endif  /* MPFR_ERRDIVZERO */

  mpfr_clear (x);

  tests_end_mpfr ();
  return 0;
}
Пример #19
0
Файл: tatan.c Проект: Canar/mpfr
static void
special_overflow (void)
{
    mpfr_t x, y;
    mpfr_exp_t emin, emax;

    emin = mpfr_get_emin ();
    emax = mpfr_get_emax ();

    set_emin (-125);
    set_emax (128);
    mpfr_init2 (x, 24);
    mpfr_init2 (y, 48);
    mpfr_set_str_binary (x, "0.101101010001001101111010E0");
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_str (y, "0.100111011001100111000010111101000111010101011110E0",
                      2, MPFR_RNDN))
    {
        printf("Special Overflow error.\n");
        mpfr_dump (y);
        exit (1);
    }

    /* intermediate Pi overflows while atan(+Inf) = Pi/2 is representable */
    set_emax (1);
    mpfr_set_inf (x, +1);
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_str (y, "C90FDAA22169p-47", 16, MPFR_RNDN)
            || mpfr_overflow_p ())
    {
        printf("atan(+Inf) = Pi/2 should not overflow when emax = %ld\n",
               (long int) mpfr_get_emax ());
        mpfr_dump (y);
        exit (1);
    }

    /* atan(+Inf) = Pi/2 underflows */
    set_emax (128);
    set_emin (3);
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
    {
        printf("atan(+Inf) = Pi/2 should underflow when emin = %ld\n",
               (long int) mpfr_get_emin ());
        mpfr_dump (y);
        exit (1);
    }

    /* intermediate Pi overflows while atan(+1) = Pi/4 is representable */
    set_emax (1);
    set_emin (-128);
    mpfr_set_ui (x, 1, MPFR_RNDN);
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_str (y, "C90FDAA22169p-48", 16, MPFR_RNDN)
            || mpfr_overflow_p ())
    {
        printf("atan(+1) = Pi/4 should not overflow when emax = %ld\n",
               (long int) mpfr_get_emax ());
        mpfr_dump (y);
        exit (1);
    }

    /* atan(+1) = Pi/4 underflows and is rounded up to 1 */
    set_emax (128);
    set_emin (1);
    mpfr_set_prec (y, 2);
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 1) || !mpfr_underflow_p ())
    {
        printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
               (long int) mpfr_get_emin ());
        mpfr_dump (y);
        exit (1);
    }

    /* atan(+1) = Pi/4 underflows and is rounded down to 0 */
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDD);
    if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
    {
        printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
               (long int) mpfr_get_emin ());
        mpfr_dump (y);
        exit (1);
    }

    mpfr_clear (y);
    mpfr_clear (x);
    set_emin (emin);
    set_emax (emax);
}
Пример #20
0
int
mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode)
{
  mpfr_t x;
  int inexact;

  MPFR_LOG_FUNC (("x[%#R]=%R rnd=%d", xt, xt, rnd_mode),
                 ("y[%#R]=%R inexact=%d", y, y, inexact));

  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (xt)))
    {
      if (MPFR_IS_NAN (xt))
        {
          MPFR_SET_NAN (y);
          MPFR_RET_NAN;
        }
      else if (MPFR_IS_INF (xt))
        {
          MPFR_SET_INF (y);
          MPFR_SET_SAME_SIGN (y, xt);
          MPFR_RET (0);
        }
      else /* xt is zero */
        {
          MPFR_ASSERTD (MPFR_IS_ZERO (xt));
          MPFR_SET_ZERO (y);   /* sinh(0) = 0 */
          MPFR_SET_SAME_SIGN (y, xt);
          MPFR_RET (0);
        }
    }

  /* sinh(x) = x + x^3/6 + ... so the error is < 2^(3*EXP(x)-2) */
  MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, xt, -2 * MPFR_GET_EXP(xt), 2, 1,
                                    rnd_mode, {});

  MPFR_TMP_INIT_ABS (x, xt);

  {
    mpfr_t t, ti;
    mp_exp_t d;
    mp_prec_t Nt;    /* Precision of the intermediary variable */
    long int err;    /* Precision of error */
    MPFR_ZIV_DECL (loop);
    MPFR_SAVE_EXPO_DECL (expo);
    MPFR_GROUP_DECL (group);

    MPFR_SAVE_EXPO_MARK (expo);

    /* compute the precision of intermediary variable */
    Nt = MAX (MPFR_PREC (x), MPFR_PREC (y));
    /* the optimal number of bits : see algorithms.ps */
    Nt = Nt + MPFR_INT_CEIL_LOG2 (Nt) + 4;
    /* If x is near 0, exp(x) - 1/exp(x) = 2*x+x^3/3+O(x^5) */
    if (MPFR_GET_EXP (x) < 0)
      Nt -= 2*MPFR_GET_EXP (x);

    /* initialise of intermediary variables */
    MPFR_GROUP_INIT_2 (group, Nt, t, ti);

    /* First computation of sinh */
    MPFR_ZIV_INIT (loop, Nt);
    for (;;) {
      /* compute sinh */
      mpfr_clear_flags ();
      mpfr_exp (t, x, GMP_RNDD);        /* exp(x) */
      /* exp(x) can overflow! */
      /* BUG/TODO/FIXME: exp can overflow but sinh may be representable! */
      if (MPFR_UNLIKELY (mpfr_overflow_p ())) {
        inexact = mpfr_overflow (y, rnd_mode, MPFR_SIGN (xt));
        MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
        break;
      }
      d = MPFR_GET_EXP (t);
      mpfr_ui_div (ti, 1, t, GMP_RNDU); /* 1/exp(x) */
      mpfr_sub (t, t, ti, GMP_RNDN);    /* exp(x) - 1/exp(x) */
      mpfr_div_2ui (t, t, 1, GMP_RNDN);  /* 1/2(exp(x) - 1/exp(x)) */

      /* it may be that t is zero (in fact, it can only occur when te=1,
         and thus ti=1 too) */
      if (MPFR_IS_ZERO (t))
        err = Nt; /* double the precision */
      else
        {
          /* calculation of the error */
          d = d - MPFR_GET_EXP (t) + 2;
          /* error estimate: err = Nt-(__gmpfr_ceil_log2(1+pow(2,d)));*/
          err = Nt - (MAX (d, 0) + 1);
          if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, MPFR_PREC (y), rnd_mode)))
            {
              inexact = mpfr_set4 (y, t, rnd_mode, MPFR_SIGN (xt));
              break;
            }
        }
      /* actualisation of the precision */
      Nt += err;
      MPFR_ZIV_NEXT (loop, Nt);
      MPFR_GROUP_REPREC_2 (group, Nt, t, ti);
    }
    MPFR_ZIV_FREE (loop);
    MPFR_GROUP_CLEAR (group);
    MPFR_SAVE_EXPO_FREE (expo);
  }

  return mpfr_check_range (y, inexact, rnd_mode);
}
Пример #21
0
int
main (int argc, char *argv[])
{
  mpfr_t x;
  long k, z, d, N;
  unsigned long zl, dl;
  int inex;
  int r;
  mpfr_exp_t emin, emax;
  int flag;

  tests_start_mpfr ();

  mpfr_init2 (x, 100);

  N = (argc==1) ? 100000 : atol (argv[1]);

  for (k = 1; k <= N; k++)
    {
      z = (long) (randlimb () & LONG_MAX) + LONG_MIN / 2;
      inex = mpfr_set_si (x, z, MPFR_RNDZ);
      d = mpfr_get_si (x, MPFR_RNDZ);
      if (d != z)
        {
          printf ("Error in mpfr_set_si: expected %ld got %ld\n", z, d);
          exit (1);
        }
      if (inex)
        {
          printf ("Error in mpfr_set_si: inex value incorrect for %ld: %d\n",
                  z, inex);
          exit (1);
        }
    }

  for (k = 1; k <= N; k++)
    {
      zl = randlimb ();
      inex = mpfr_set_ui (x, zl, MPFR_RNDZ);
      dl = mpfr_get_ui (x, MPFR_RNDZ);
      if (dl != zl)
        {
          printf ("Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl);
          exit (1);
        }
      if (inex)
        {
          printf ("Error in mpfr_set_ui: inex value incorrect for %lu: %d\n",
                  zl, inex);
          exit (1);
        }
    }

  mpfr_set_prec (x, 2);
  if (mpfr_set_si (x, 5, MPFR_RNDZ) >= 0)
    {
      printf ("Wrong inexact flag for x=5, rnd=MPFR_RNDZ\n");
      exit (1);
    }

  mpfr_set_prec (x, 2);
  if (mpfr_set_si (x, -5, MPFR_RNDZ) <= 0)
    {
      printf ("Wrong inexact flag for x=-5, rnd=MPFR_RNDZ\n");
      exit (1);
    }

  mpfr_set_prec (x, 3);
  inex = mpfr_set_si (x, 77617, MPFR_RNDD); /* should be 65536 */
  if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
      || inex >= 0)
    {
      printf ("Error in mpfr_set_si(x:3, 77617, MPFR_RNDD)\n");
      mpfr_print_binary (x);
      puts ("");
      exit (1);
    }
  inex = mpfr_set_ui (x, 77617, MPFR_RNDD); /* should be 65536 */
  if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
      || inex >= 0)
    {
      printf ("Error in mpfr_set_ui(x:3, 77617, MPFR_RNDD)\n");
      mpfr_print_binary (x);
      puts ("");
      exit (1);
    }

  mpfr_set_prec (x, 2);
  inex = mpfr_set_si (x, 33096, MPFR_RNDU);
  if (mpfr_get_si (x, MPFR_RNDZ) != 49152 || inex <= 0)
    {
      printf ("Error in mpfr_set_si, exp. 49152, got %ld, inex %d\n",
              mpfr_get_si (x, MPFR_RNDZ), inex);
      exit (1);
    }
  inex = mpfr_set_ui (x, 33096, MPFR_RNDU);
  if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
    {
      printf ("Error in mpfr_set_ui, exp. 49152, got %ld, inex %d\n",
              mpfr_get_si (x, MPFR_RNDZ), inex);
      exit (1);
    }
  /* Also test the mpfr_set_ui function (instead of macro). */
  inex = (mpfr_set_ui) (x, 33096, MPFR_RNDU);
  if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
    {
      printf ("Error in mpfr_set_ui function, exp. 49152, got %ld, inex %d\n",
              mpfr_get_si (x, MPFR_RNDZ), inex);
      exit (1);
    }

  for (r = 0 ; r < MPFR_RND_MAX ; r++)
    {
      mpfr_set_si (x, -1, (mpfr_rnd_t) r);
      mpfr_set_ui (x, 0, (mpfr_rnd_t) r);
      if (MPFR_IS_NEG (x) || mpfr_get_ui (x, (mpfr_rnd_t) r) != 0)
        {
          printf ("mpfr_set_ui (x, 0) gives -0 for %s\n",
                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
          exit (1);
        }

      mpfr_set_si (x, -1, (mpfr_rnd_t) r);
      mpfr_set_si (x, 0, (mpfr_rnd_t) r);
      if (MPFR_IS_NEG (x) || mpfr_get_si (x, (mpfr_rnd_t) r) != 0)
        {
          printf ("mpfr_set_si (x, 0) gives -0 for %s\n",
                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
          exit (1);
        }
    }

  /* check potential bug in case mp_limb_t is unsigned */
  emax = mpfr_get_emax ();
  set_emax (0);
  mpfr_set_si (x, -1, MPFR_RNDN);
  if (mpfr_sgn (x) >= 0)
    {
      printf ("mpfr_set_si (x, -1) fails\n");
      exit (1);
    }
  set_emax (emax);

  emax = mpfr_get_emax ();
  set_emax (5);
  mpfr_set_prec (x, 2);
  mpfr_set_si (x, -31, MPFR_RNDN);
  if (mpfr_sgn (x) >= 0)
    {
      printf ("mpfr_set_si (x, -31) fails\n");
      exit (1);
    }
  set_emax (emax);

  /* test for get_ui */
  mpfr_set_ui (x, 0, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_get_ui (x, MPFR_RNDN) == 0);
  mpfr_set_ui (x, ULONG_MAX, MPFR_RNDU);
  mpfr_nextabove (x);
  mpfr_get_ui (x, MPFR_RNDU);

  /* another test for get_ui */
  mpfr_set_prec (x, 10);
  mpfr_set_str_binary (x, "10.101");
  dl = mpfr_get_ui (x, MPFR_RNDN);
  MPFR_ASSERTN (dl == 3);

  mpfr_set_str_binary (x, "-1.0");
  mpfr_get_ui (x, MPFR_RNDN);

  mpfr_set_str_binary (x, "0.1");
  dl = mpfr_get_ui (x, MPFR_RNDN);
  MPFR_ASSERTN (dl == 0);
  dl = mpfr_get_ui (x, MPFR_RNDZ);
  MPFR_ASSERTN (dl == 0);
  dl = mpfr_get_ui (x, MPFR_RNDD);
  MPFR_ASSERTN (dl == 0);
  dl = mpfr_get_ui (x, MPFR_RNDU);
  MPFR_ASSERTN (dl == 1);

  /* coverage tests */
  mpfr_set_prec (x, 2);
  mpfr_set_si (x, -7, MPFR_RNDD);
  MPFR_ASSERTN(mpfr_cmp_si (x, -8) == 0);
  mpfr_set_prec (x, 2);
  mpfr_set_ui (x, 7, MPFR_RNDU);
  MPFR_ASSERTN(mpfr_cmp_ui (x, 8) == 0);
  emax = mpfr_get_emax ();
  set_emax (3);
  mpfr_set_ui (x, 7, MPFR_RNDU);
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
  set_emax (1);
  MPFR_ASSERTN( mpfr_set_ui (x, 7, MPFR_RNDU) );
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
  set_emax (emax);
  mpfr_set_ui_2exp (x, 17, -50, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_get_ui (x, MPFR_RNDD) == 0);
  MPFR_ASSERTN (mpfr_get_si (x, MPFR_RNDD) == 0);

  /* Test for ERANGE flag + correct behaviour if overflow */
  mpfr_set_prec (x, 256);
  mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  dl = mpfr_get_ui (x, MPFR_RNDN);
  if (dl != ULONG_MAX || mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_ui + ERANGE + ULONG_MAX (1)\n");
      exit (1);
    }
  mpfr_add_ui (x, x, 1, MPFR_RNDN);
  dl = mpfr_get_ui (x, MPFR_RNDN);
  if (dl != ULONG_MAX || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_ui + ERANGE + ULONG_MAX (2)\n");
      exit (1);
    }
  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  dl = mpfr_get_ui (x, MPFR_RNDN);
  if (dl != 0 || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_ui + ERANGE + -1 \n");
      exit (1);
    }
  mpfr_set_si (x, LONG_MAX, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != LONG_MAX || mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + ERANGE + LONG_MAX (1): %ld\n", d);
      exit (1);
    }
  mpfr_add_ui (x, x, 1, MPFR_RNDN);
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != LONG_MAX || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + ERANGE + LONG_MAX (2)\n");
      exit (1);
    }
  mpfr_set_si (x, LONG_MIN, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != LONG_MIN || mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + ERANGE + LONG_MIN (1)\n");
      exit (1);
    }
  mpfr_sub_ui (x, x, 1, MPFR_RNDN);
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != LONG_MIN || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + ERANGE + LONG_MIN (2)\n");
      exit (1);
    }

  mpfr_set_nan (x);
  mpfr_clear_erangeflag ();
  d = mpfr_get_ui (x, MPFR_RNDN);
  if (d != 0 || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_ui + NaN\n");
      exit (1);
    }
  mpfr_clear_erangeflag ();
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != 0 || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + NaN\n");
      exit (1);
    }

  emin = mpfr_get_emin ();
  mpfr_set_prec (x, 2);

  mpfr_set_emin (4);
  mpfr_clear_flags ();
  mpfr_set_ui (x, 7, MPFR_RNDU);
  flag = mpfr_underflow_p ();
  mpfr_set_emin (emin);
  if (mpfr_cmp_ui (x, 8) != 0)
    {
      printf ("Error for mpfr_set_ui (x, 7, MPFR_RNDU), prec = 2, emin = 4\n");
      exit (1);
    }
  if (flag)
    {
      printf ("mpfr_set_ui (x, 7, MPFR_RNDU) should not underflow "
              "with prec = 2, emin = 4\n");
      exit (1);
    }

  mpfr_set_emin (4);
  mpfr_clear_flags ();
  mpfr_set_si (x, -7, MPFR_RNDD);
  flag = mpfr_underflow_p ();
  mpfr_set_emin (emin);
  if (mpfr_cmp_si (x, -8) != 0)
    {
      printf ("Error for mpfr_set_si (x, -7, MPFR_RNDD), prec = 2, emin = 4\n");
      exit (1);
    }
  if (flag)
    {
      printf ("mpfr_set_si (x, -7, MPFR_RNDD) should not underflow "
              "with prec = 2, emin = 4\n");
      exit (1);
    }

  mpfr_clear (x);

  test_2exp ();
  test_macros ();
  test_macros_keyword ();
  tests_end_mpfr ();
  return 0;
}
Пример #22
0
int
mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
    int inexact;
    long xint;
    mpfr_t xfrac;
    MPFR_SAVE_EXPO_DECL (expo);

    MPFR_LOG_FUNC
    (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
     ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y,
      inexact));

    if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
    {
        if (MPFR_IS_NAN (x))
        {
            MPFR_SET_NAN (y);
            MPFR_RET_NAN;
        }
        else if (MPFR_IS_INF (x))
        {
            if (MPFR_IS_POS (x))
                MPFR_SET_INF (y);
            else
                MPFR_SET_ZERO (y);
            MPFR_SET_POS (y);
            MPFR_RET (0);
        }
        else /* 2^0 = 1 */
        {
            MPFR_ASSERTD (MPFR_IS_ZERO(x));
            return mpfr_set_ui (y, 1, rnd_mode);
        }
    }

    /* since the smallest representable non-zero float is 1/2*2^__gmpfr_emin,
       if x < __gmpfr_emin - 1, the result is either 1/2*2^__gmpfr_emin or 0 */
    MPFR_ASSERTN (MPFR_EMIN_MIN >= LONG_MIN + 2);
    if (MPFR_UNLIKELY (mpfr_cmp_si (x, __gmpfr_emin - 1) < 0))
    {
        mpfr_rnd_t rnd2 = rnd_mode;
        /* in round to nearest mode, round to zero when x <= __gmpfr_emin-2 */
        if (rnd_mode == MPFR_RNDN &&
                mpfr_cmp_si_2exp (x, __gmpfr_emin - 2, 0) <= 0)
            rnd2 = MPFR_RNDZ;
        return mpfr_underflow (y, rnd2, 1);
    }

    MPFR_ASSERTN (MPFR_EMAX_MAX <= LONG_MAX);
    if (MPFR_UNLIKELY (mpfr_cmp_si (x, __gmpfr_emax) >= 0))
        return mpfr_overflow (y, rnd_mode, 1);

    /* We now know that emin - 1 <= x < emax. */

    MPFR_SAVE_EXPO_MARK (expo);

    /* 2^x = 1 + x*log(2) + O(x^2) for x near zero, and for |x| <= 1 we have
       |2^x - 1| <= x < 2^EXP(x). If x > 0 we must round away from 0 (dir=1);
       if x < 0 we must round toward 0 (dir=0). */
    MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (y, __gmpfr_one, - MPFR_GET_EXP (x), 0,
                                      MPFR_SIGN(x) > 0, rnd_mode, expo, {});

    xint = mpfr_get_si (x, MPFR_RNDZ);
    mpfr_init2 (xfrac, MPFR_PREC (x));
    mpfr_sub_si (xfrac, x, xint, MPFR_RNDN); /* exact */

    if (MPFR_IS_ZERO (xfrac))
    {
        mpfr_set_ui (y, 1, MPFR_RNDN);
        inexact = 0;
    }
    else
    {
        /* Declaration of the intermediary variable */
        mpfr_t t;

        /* Declaration of the size variable */
        mpfr_prec_t Ny = MPFR_PREC(y);              /* target precision */
        mpfr_prec_t Nt;                             /* working precision */
        mpfr_exp_t err;                             /* error */
        MPFR_ZIV_DECL (loop);

        /* compute the precision of intermediary variable */
        /* the optimal number of bits : see algorithms.tex */
        Nt = Ny + 5 + MPFR_INT_CEIL_LOG2 (Ny);

        /* initialise of intermediary variable */
        mpfr_init2 (t, Nt);

        /* First computation */
        MPFR_ZIV_INIT (loop, Nt);
        for (;;)
        {
            /* compute exp(x*ln(2))*/
            mpfr_const_log2 (t, MPFR_RNDU);       /* ln(2) */
            mpfr_mul (t, xfrac, t, MPFR_RNDU);    /* xfrac * ln(2) */
            err = Nt - (MPFR_GET_EXP (t) + 2);   /* Estimate of the error */
            mpfr_exp (t, t, MPFR_RNDN);           /* exp(xfrac * ln(2)) */

            if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
                break;

            /* Actualisation of the precision */
            MPFR_ZIV_NEXT (loop, Nt);
            mpfr_set_prec (t, Nt);
        }
        MPFR_ZIV_FREE (loop);

        inexact = mpfr_set (y, t, rnd_mode);

        mpfr_clear (t);
    }

    mpfr_clear (xfrac);
    mpfr_clear_flags ();
    mpfr_mul_2si (y, y, xint, MPFR_RNDN); /* exact or overflow */
    /* Note: We can have an overflow only when t was rounded up to 2. */
    MPFR_ASSERTD (MPFR_IS_PURE_FP (y) || inexact > 0);
    MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
    MPFR_SAVE_EXPO_FREE (expo);
    return mpfr_check_range (y, inexact, rnd_mode);
}
Пример #23
0
Файл: tj0.c Проект: epowers/mpfr
int
main (int argc, char *argv[])
{
  mpfr_t x, y;
  int inex;

  tests_start_mpfr ();

  mpfr_init (x);
  mpfr_init (y);

  /* special values */
  mpfr_set_nan (x);
  mpfr_j0 (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_nan_p (y));

  mpfr_set_inf (x, 1); /* +Inf */
  mpfr_j0 (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));

  mpfr_set_inf (x, -1); /* -Inf */
  mpfr_j0 (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));

  mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */
  mpfr_j0 (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(+0)=1 */

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_neg (x, x, MPFR_RNDN); /* -0 */
  mpfr_j0 (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(-0)=1 */

  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_j0 (y, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_j0 for x=1, rnd=MPFR_RNDN\n");
      printf ("Expected "); mpfr_dump (x);
      printf ("Got      "); mpfr_dump (y);
      exit (1);
    }

  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_j0 (y, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_j0 for x=-1, rnd=MPFR_RNDN\n");
      printf ("Expected "); mpfr_dump (x);
      printf ("Got      "); mpfr_dump (y);
      exit (1);
    }

  /* Bug reported on 2007-07-03 by Sisyphus (assertion failed in r4619) */
  mpfr_set_si (x, 70000, MPFR_RNDN);
  mpfr_j0 (y, x, MPFR_RNDN);

  /* Bug reported by Kevin Rauch on 27 Oct 2007 */
  mpfr_set_prec (x, 7);
  mpfr_set_prec (y, 7);
  mpfr_set_si (x, -100, MPFR_RNDN);
  mpfr_j0 (y, x, MPFR_RNDN);
  MPFR_ASSERTN (! mpfr_nan_p (y) && mpfr_cmp_ui_2exp (y, 41, -11) == 0);

  /* Case for which s = 0 in mpfr_jn */
  mpfr_set_prec (x, 44);
  mpfr_set_prec (y, 44);
  mpfr_set_si (x, 2, MPFR_RNDN);
  mpfr_clear_flags ();
  inex = mpfr_j0 (y, x, MPFR_RNDN);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_INEXACT);
  mpfr_set_str (x, "0x.e5439fd9267p-2", 0, MPFR_RNDN);
  if (! mpfr_equal_p (y, x))
    {
      printf ("Error on 2:\n");
      printf ("Expected ");
      mpfr_dump (x);
      printf ("Got      ");
      mpfr_dump (y);
      exit (1);
    }
  if (inex >= 0)
    {
      printf ("Bad ternary value on 2: expected negative, got %d\n", inex);
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);

  test_generic (2, 100, 10);

  data_check ("data/j0", mpfr_j0, "mpfr_j0");

  tests_end_mpfr ();

  return 0;
}
Пример #24
0
static void
special (void)
{
  mpfr_t x, y;
  int i;

  mpfr_init (x);
  mpfr_init (y);

  mpfr_set_nan (x);
  test_expm1 (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for expm1(NaN)\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  test_expm1 (y, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for expm1(+Inf)\n");
      exit (1);
    }

  mpfr_set_inf (x, -1);
  test_expm1 (y, x, MPFR_RNDN);
  if (mpfr_cmp_si (y, -1))
    {
      printf ("Error for expm1(-Inf)\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  test_expm1 (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
      printf ("Error for expm1(+0)\n");
      exit (1);
    }

  mpfr_neg (x, x, MPFR_RNDN);
  test_expm1 (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
    {
      printf ("Error for expm1(-0)\n");
      exit (1);
    }

  /* Check overflow of expm1(x) */
  mpfr_clear_flags ();
  mpfr_set_str_binary (x, "1.1E1000000000");
  i = test_expm1 (x, x, MPFR_RNDN);
  MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
  MPFR_ASSERTN (mpfr_overflow_p ());
  MPFR_ASSERTN (i == 1);

  mpfr_clear_flags ();
  mpfr_set_str_binary (x, "1.1E1000000000");
  i = test_expm1 (x, x, MPFR_RNDU);
  MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
  MPFR_ASSERTN (mpfr_overflow_p ());
  MPFR_ASSERTN (i == 1);

  mpfr_clear_flags ();
  mpfr_set_str_binary (x, "1.1E1000000000");
  i = test_expm1 (x, x, MPFR_RNDD);
  MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
  MPFR_ASSERTN (mpfr_overflow_p ());
  MPFR_ASSERTN (i == -1);

  /* Check internal underflow of expm1 (x) */
  mpfr_set_prec (x, 2);
  mpfr_clear_flags ();
  mpfr_set_str_binary (x, "-1.1E1000000000");
  i = test_expm1 (x, x, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0);
  MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
  MPFR_ASSERTN (i == -1);

  mpfr_set_str_binary (x, "-1.1E1000000000");
  i = test_expm1 (x, x, MPFR_RNDD);
  MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0);
  MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
  MPFR_ASSERTN (i == -1);

  mpfr_set_str_binary (x, "-1.1E1000000000");
  i = test_expm1 (x, x, MPFR_RNDZ);
  MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0);
  MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
  MPFR_ASSERTN (i == 1);

  mpfr_set_str_binary (x, "-1.1E1000000000");
  i = test_expm1 (x, x, MPFR_RNDU);
  MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0);
  MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
  MPFR_ASSERTN (i == 1);

  mpfr_clear (x);
  mpfr_clear (y);
}
Пример #25
0
static void
overflowed_fac0 (void)
{
  mpfr_t x, y;
  int inex, rnd, err = 0;
  mp_exp_t old_emax;

  old_emax = mpfr_get_emax ();

  mpfr_init2 (x, 8);
  mpfr_init2 (y, 8);

  mpfr_set_ui (y, 1, GMP_RNDN);
  mpfr_nextbelow (y);
  set_emax (0);  /* 1 is not representable. */
  RND_LOOP (rnd)
    {
      mpfr_clear_flags ();
      inex = mpfr_fac_ui (x, 0, rnd);
      if (! mpfr_overflow_p ())
        {
          printf ("Error in overflowed_fac0 (rnd = %s):\n"
                  "  The overflow flag is not set.\n",
                  mpfr_print_rnd_mode (rnd));
          err = 1;
        }
      if (rnd == GMP_RNDZ || rnd == GMP_RNDD)
        {
          if (inex >= 0)
            {
              printf ("Error in overflowed_fac0 (rnd = %s):\n"
                      "  The inexact value must be negative.\n",
                      mpfr_print_rnd_mode (rnd));
              err = 1;
            }
          if (! mpfr_equal_p (x, y))
            {
              printf ("Error in overflowed_fac0 (rnd = %s):\n"
                      "  Got ", mpfr_print_rnd_mode (rnd));
              mpfr_print_binary (x);
              printf (" instead of 0.11111111E0.\n");
              err = 1;
            }
        }
      else
        {
          if (inex <= 0)
            {
              printf ("Error in overflowed_fac0 (rnd = %s):\n"
                      "  The inexact value must be positive.\n",
                      mpfr_print_rnd_mode (rnd));
              err = 1;
            }
          if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
            {
              printf ("Error in overflowed_fac0 (rnd = %s):\n"
                      "  Got ", mpfr_print_rnd_mode (rnd));
              mpfr_print_binary (x);
              printf (" instead of +Inf.\n");
              err = 1;
            }
        }
    }
  set_emax (old_emax);

  if (err)
    exit (1);
  mpfr_clear (x);
  mpfr_clear (y);
}
Пример #26
0
static PyObject *
GMPy_Context_Fsum(PyObject *self, PyObject *other)
{
    MPFR_Object *temp, *result;
    mpfr_ptr *tab;
    int errcode;
    Py_ssize_t i, seq_length = 0;
    CTXT_Object *context = NULL;

    if (self && CTXT_Check(self)) {
        context = (CTXT_Object*)self;
    }
    else {
        CHECK_CONTEXT(context);
    }

    if (!(result = GMPy_MPFR_New(0, context))) {
        return NULL;
    }

    if (!(other = PySequence_List(other))) {
        Py_DECREF((PyObject*)result);
        TYPE_ERROR("argument must be an iterable");
        return NULL;
    }

    /* other contains a new list containing all the values from the
     * iterable. Now make sure each item in the list is an mpfr.
     */

    seq_length = PyList_GET_SIZE(other);
    for (i=0; i < seq_length; i++) {
        if (!(temp = GMPy_MPFR_From_Real(PyList_GET_ITEM(other, i), 1, context))) {
            Py_DECREF(other);
            Py_DECREF((PyObject*)result);
            TYPE_ERROR("all items in iterable must be real numbers");
            return NULL;
        }

        errcode = PyList_SetItem(other, i,(PyObject*)temp);
        if (errcode < 0) {
            Py_DECREF(other);
            Py_DECREF((PyObject*)result);
            TYPE_ERROR("all items in iterable must be real numbers");
            return NULL;
        }
    }

    /* create an array of pointers to the mpfr_t field of a Pympfr object */

    if (!(tab = (mpfr_ptr *)GMPY_MALLOC((sizeof(mpfr_srcptr) * seq_length)))) {
        Py_DECREF(other);
        Py_DECREF((PyObject*)result);
        return PyErr_NoMemory();
    }
    for (i=0; i < seq_length; i++) {
        temp = (MPFR_Object*)PyList_GET_ITEM(other, i);
        tab[i] = temp->f;
    }

    mpfr_clear_flags();
    result->rc = mpfr_sum(result->f, tab, seq_length, GET_MPFR_ROUND(context));
    Py_DECREF(other);
    GMPY_FREE(tab);

    _GMPy_MPFR_Cleanup(&result, context);
    return (PyObject*)result;
}
Пример #27
0
static void
test_overflow2 (void)
{
  mpfr_t x, y, z, r;
  int i, inex, rnd, err = 0;

  mpfr_inits2 (8, x, y, z, r, (void *) 0);

  MPFR_SET_POS (x);
  mpfr_setmin (x, mpfr_get_emax ());  /* x = 0.1@emax */
  mpfr_set_si (y, -2, GMP_RNDN);      /* y = -2 */
  /* The intermediate multiplication x * y will overflow. */

  for (i = -9; i <= 9; i++)
    RND_LOOP (rnd)
      {
        int inf, overflow;

        inf = rnd == GMP_RNDN || rnd == GMP_RNDD;
        overflow = inf || i <= 0;

        inex = mpfr_set_si_2exp (z, i, mpfr_get_emin (), GMP_RNDN);
        MPFR_ASSERTN (inex == 0);

        mpfr_clear_flags ();
        /* One has: x * y = -1@emax exactly (but not representable). */
        inex = mpfr_fma (r, x, y, z, rnd);
        if (overflow ^ (mpfr_overflow_p () != 0))
          {
            printf ("Error in test_overflow2 (i = %d, %s): wrong overflow"
                    " flag (should be %d)\n", i, mpfr_print_rnd_mode (rnd),
                    overflow);
            err = 1;
          }
        if (mpfr_nanflag_p ())
          {
            printf ("Error in test_overflow2 (i = %d, %s): NaN flag should"
                    " not be set\n", i, mpfr_print_rnd_mode (rnd));
            err = 1;
          }
        if (mpfr_nan_p (r))
          {
            printf ("Error in test_overflow2 (i = %d, %s): got NaN\n",
                    i, mpfr_print_rnd_mode (rnd));
            err = 1;
          }
        else if (MPFR_SIGN (r) >= 0)
          {
            printf ("Error in test_overflow2 (i = %d, %s): wrong sign "
                    "(+ instead of -)\n", i, mpfr_print_rnd_mode (rnd));
            err = 1;
          }
        else if (inf && ! mpfr_inf_p (r))
          {
            printf ("Error in test_overflow2 (i = %d, %s): expected -Inf,"
                    " got\n", i, mpfr_print_rnd_mode (rnd));
            mpfr_dump (r);
            err = 1;
          }
        else if (!inf && (mpfr_inf_p (r) ||
                          (mpfr_nextbelow (r), ! mpfr_inf_p (r))))
          {
            printf ("Error in test_overflow2 (i = %d, %s): expected -MAX,"
                    " got\n", i, mpfr_print_rnd_mode (rnd));
            mpfr_dump (r);
            err = 1;
          }
        if (inf ? inex >= 0 : inex <= 0)
          {
            printf ("Error in test_overflow2 (i = %d, %s): wrong inexact"
                    " flag (got %d)\n", i, mpfr_print_rnd_mode (rnd), inex);
            err = 1;
          }

      }

  if (err)
    exit (1);
  mpfr_clears (x, y, z, r, (void *) 0);
}
Пример #28
0
/* Test n random bad cases. A precision py in [pymin,pymax] and
 * a number y of precision py are chosen randomly. One computes
 * x = inv(y) in precision px = py + psup (rounded to nearest).
 * Then (in general), y is a bad case for fct in precision py (in
 * the directed rounding modes, but also in the rounding-to-nearest
 * mode for some lower precision: see data_check).
 * fct, inv, name: data related to the function.
 * pos, emin, emax: arguments for tests_default_random.
 */
void
bad_cases (int (*fct)(FLIST), int (*inv)(FLIST), const char *name,
           int pos, mpfr_exp_t emin, mpfr_exp_t emax,
           mpfr_prec_t pymin, mpfr_prec_t pymax, mpfr_prec_t psup,
           int n)
{
  mpfr_t x, y, z;
  char *dbgenv;
  int i, dbg;
  mpfr_exp_t old_emin, old_emax;

  old_emin = mpfr_get_emin ();
  old_emax = mpfr_get_emax ();

  dbgenv = getenv ("MPFR_DEBUG_BADCASES");
  dbg = dbgenv != 0 ? atoi (dbgenv) : 0;  /* debug level */
  mpfr_inits (x, y, z, (mpfr_ptr) 0);
  for (i = 0; i < n; i++)
    {
      mpfr_prec_t px, py, pz;
      int inex;

      if (dbg)
        printf ("bad_cases: i = %d\n", i);
      py = pymin + (randlimb () % (pymax - pymin + 1));
      mpfr_set_prec (y, py);
      tests_default_random (y, pos, emin, emax);
      if (dbg)
        {
          printf ("bad_cases: yprec =%4ld, y = ", (long) py);
          mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
          printf ("\n");
        }
      px = py + psup;
      mpfr_set_prec (x, px);
      mpfr_clear_flags ();
      inv (x, y, MPFR_RNDN);
      if (mpfr_nanflag_p () || mpfr_overflow_p () || mpfr_underflow_p ())
        {
          if (dbg)
            printf ("bad_cases: no normal inverse\n");
          goto next_i;
        }
      if (dbg > 1)
        {
          printf ("bad_cases: x = ");
          mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
          printf ("\n");
        }
      pz = px;
      do
        {
          pz += 32;
          mpfr_set_prec (z, pz);
          if (fct (z, x, MPFR_RNDN) == 0)
            {
              if (dbg)
                printf ("bad_cases: exact case\n");
              goto next_i;
            }
          if (dbg)
            {
              if (dbg > 1)
                {
                  printf ("bad_cases: %s(x) ~= ", name);
                  mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
                }
              else
                {
                  printf ("bad_cases:   [MPFR_RNDZ]  ~= ");
                  mpfr_out_str (stdout, 16, 40, z, MPFR_RNDZ);
                }
              printf ("\n");
            }
          inex = mpfr_prec_round (z, py, MPFR_RNDN);
          if (mpfr_nanflag_p () || mpfr_overflow_p () || mpfr_underflow_p ()
              || ! mpfr_equal_p (z, y))
            {
              if (dbg)
                printf ("bad_cases: inverse doesn't match\n");
              goto next_i;
            }
        }
      while (inex == 0);
      /* We really have a bad case. */
      do
        py--;
      while (py >= MPFR_PREC_MIN && mpfr_prec_round (z, py, MPFR_RNDZ) == 0);
      py++;
      /* py is now the smallest output precision such that we have
         a bad case in the directed rounding modes. */
      if (mpfr_prec_round (y, py, MPFR_RNDZ) != 0)
        {
          printf ("Internal error for i = %d\n", i);
          exit (1);
        }
      if ((inex > 0 && MPFR_IS_POS (z)) ||
          (inex < 0 && MPFR_IS_NEG (z)))
        {
          mpfr_nexttozero (y);
          if (mpfr_zero_p (y))
            goto next_i;
        }
      if (dbg)
        {
          printf ("bad_cases: yprec =%4ld, y = ", (long) py);
          mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
          printf ("\n");
        }
      /* Note: y is now the expected result rounded toward zero. */
      test5rm (fct, x, y, z, MPFR_RNDZ, 0, name);
    next_i:
      /* In case the exponent range has been changed by
         tests_default_random()... */
      mpfr_set_emin (old_emin);
      mpfr_set_emax (old_emax);
    }
  mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
Пример #29
0
static void
overflowed_sec0 (void)
{
  mpfr_t x, y;
  int emax, i, inex, rnd, err = 0;
  mpfr_exp_t old_emax;

  old_emax = mpfr_get_emax ();

  mpfr_init2 (x, 8);
  mpfr_init2 (y, 8);

  for (emax = -1; emax <= 0; emax++)
    {
      mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
      mpfr_nextbelow (y);
      set_emax (emax);  /* 1 is not representable. */
      for (i = -1; i <= 1; i++)
        RND_LOOP (rnd)
          {
            mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
            mpfr_clear_flags ();
            inex = mpfr_sec (x, x, (mpfr_rnd_t) rnd);
            if (! mpfr_overflow_p ())
              {
                printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
                        "  The overflow flag is not set.\n",
                        i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                err = 1;
              }
            if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
              {
                if (inex >= 0)
                  {
                    printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
                            "  The inexact value must be negative.\n",
                            i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                    err = 1;
                  }
                if (! mpfr_equal_p (x, y))
                  {
                    printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
                            "  Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                    mpfr_print_binary (x);
                    printf (" instead of 0.11111111E%d.\n", emax);
                    err = 1;
                  }
              }
            else
              {
                if (inex <= 0)
                  {
                    printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
                            "  The inexact value must be positive.\n",
                            i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                    err = 1;
                  }
                if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
                  {
                    printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
                            "  Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                    mpfr_print_binary (x);
                    printf (" instead of +Inf.\n");
                    err = 1;
                  }
              }
          }
      set_emax (old_emax);
    }

  if (err)
    exit (1);
  mpfr_clear (x);
  mpfr_clear (y);
}
Пример #30
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);
}