Esempio n. 1
0
/**
 * Rootfinding by interval bisection.
 *
 * Brent's method is faster though.
 */
int RootFinder::bisection(double t_begin, double t_end, double* root) {
    double t_mid;
    double f_t_begin = f(t_begin);
    double f_t_end = f(t_end);
    double f_t_mid;
    uint32_t i = 2;

    if (SAME_SIGN(f_t_begin, f_t_end))
	return false;
    
    while (i++ < MAX_ITER) {
	t_mid = 0.5 * (t_begin + t_end);
	f_t_mid = f(t_mid);

	if (fabs(f_t_mid) < tolerance) {
	    *root = t_mid;
	    return i;
	}

	if (SAME_SIGN(f_t_begin, f_t_mid)) {
	    t_begin = t_mid;
	    f_t_begin = f_t_mid;
	} else {
	    t_end = t_mid;
	    f_t_end = f_t_mid;
	}

    }
    return false;
}
Esempio n. 2
0
int RootFinder::regula_falsi(double t_begin, double t_end, double* root) {
    double t_mid;
    double f_t_begin = f(t_begin);
    double f_t_end = f(t_end);
    double f_t_mid;
    uint32_t i = 2;

    if (SAME_SIGN(f_t_begin, f_t_end))
	return false;

    while (i++ < MAX_ITER) {
	t_mid = ( f_t_end * t_begin - f_t_begin * t_end ) / ( f_t_end - f_t_begin );
	f_t_mid = f(t_mid);

	if (fabs(f_t_mid) < tolerance) {
	    *root = t_mid;
	    return i;
	}

	if (SAME_SIGN(f_t_begin, f_t_mid)) {
	    t_begin = t_mid;
	    f_t_begin = f_t_mid;
	} else {
	    t_end = t_mid;
	    f_t_end = f_t_mid;
	}
    }
    return false;
}
Esempio n. 3
0
static void
test_underflow3 (int n)
{
  mpfr_t x, y, z, t1, t2;
  int sign, k, s, rnd, inex1, inex2;
  mpfr_exp_t e;
  mpfr_flags_t flags1, flags2;

  mpfr_inits2 (4, x, z, t1, t2, (mpfr_ptr) 0);
  mpfr_init2 (y, 6);

  e = mpfr_get_emin () - 1;

  for (sign = 1; sign >= -1; sign -= 2)
    for (k = 1; k <= 7; k++)
      for (s = -1; s <= 1; s++)
        {
          mpfr_set_si_2exp (x, sign, e, MPFR_RNDN);
          mpfr_set_si_2exp (y, 8*k+s, -6, MPFR_RNDN);
          mpfr_neg (z, x, MPFR_RNDN);
          /* x = sign * 2^(emin-1)
             y = (8 * k + s) * 2^(-6) = k / 8 + s * 2^(-6)
             z = -x = -sign * 2^(emin-1)
             FMA(x,y,z) = sign * ((k-8) * 2^(emin-4) + s * 2^(emin-7)) exactly.
             Note: The purpose of the s * 2^(emin-7) term is to yield
             double rounding when scaling for k = 4, s != 0, MPFR_RNDN. */

          RND_LOOP (rnd)
            {
              mpfr_clear_flags ();
              inex1 = mpfr_set_si_2exp (t1, sign * (8*k+s-64), e-6,
                                        (mpfr_rnd_t) rnd);
              flags1 = __gmpfr_flags;

              mpfr_clear_flags ();
              inex2 = mpfr_fma (t2, x, y, z, (mpfr_rnd_t) rnd);
              flags2 = __gmpfr_flags;

              if (! (mpfr_equal_p (t1, t2) &&
                     SAME_SIGN (inex1, inex2) &&
                     flags1 == flags2))
                {
                  printf ("Error in test_underflow3, n = %d, sign = %d,"
                          " k = %d, s = %d, %s\n", n, sign, k, s,
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  printf ("Expected ");
                  mpfr_dump (t1);
                  printf ("  with inex ~ %d, flags =", inex1);
                  flags_out (flags1);
                  printf ("Got      ");
                  mpfr_dump (t2);
                  printf ("  with inex ~ %d, flags =", inex2);
                  flags_out (flags2);
                  exit (1);
                }
            }
        }

  mpfr_clears (x, y, z, t1, t2, (mpfr_ptr) 0);
}
Esempio n. 4
0
static void
check (long int n, long int d, mpfr_rnd_t rnd, const char *ys)
{
  mpq_t q;
  mpfr_t x, t;
  int inexact, compare;
  unsigned int flags, ex_flags;

  mpfr_init2 (x, 53);
  mpfr_init2 (t, mpfr_get_prec (x) + mp_bits_per_limb);
  mpq_init (q);
  mpq_set_si (q, n, d);
  mpfr_clear_flags ();
  inexact = mpfr_set_q (x, q, rnd);
  flags = __gmpfr_flags;

  /* check values */
  if (mpfr_cmp_str1 (x, ys))
    {
      printf ("Error for q = %ld/%ld and rnd = %s\n", n, d,
              mpfr_print_rnd_mode (rnd));
      printf ("correct result is %s, mpfr_set_q gives ", ys);
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }

  /* check inexact flag */
  if (mpfr_mul_ui (t, x, (d < 0) ? (-d) : d, rnd))
    {
      printf ("t <- x * d should be exact\n");
      exit (1);
    }
  compare = mpfr_cmp_si (t, n);
  if (! SAME_SIGN (inexact, compare))
    {
      printf ("Wrong ternary value for q = %ld/%ld and rnd = %s:\n"
              "expected %d or equivalent, got %d\n",
              n, d, mpfr_print_rnd_mode (rnd), compare, inexact);
      exit (1);
    }

  ex_flags = compare == 0 ? 0 : MPFR_FLAGS_INEXACT;
  if (flags != ex_flags)
    {
      printf ("Wrong flags for q = %ld/%ld and rnd = %s:\n",
              n, d, mpfr_print_rnd_mode (rnd));
      printf ("Expected flags:");
      flags_out (ex_flags);
      printf ("Got flags:     ");
      flags_out (flags);
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (t);
  mpq_clear (q);
}
Esempio n. 5
0
static void
check_one (mpz_ptr z)
{
  int    inex;
  int    sh, neg;
  mpfr_t f;
  mpz_t  got;

  mpfr_init2 (f, MAX( mpz_sizeinbase (z, 2), MPFR_PREC_MIN) );
  mpz_init (got);

  for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++)
    {
      for (neg = 0; neg <= 1; neg++)
        {
          mpz_neg (z, z);
          mpfr_set_z (f, z, MPFR_RNDN);

          if (sh < 0)
            {
              mpz_tdiv_q_2exp (z, z, -sh);
              mpfr_div_2exp (f, f, -sh, MPFR_RNDN);
            }
          else
            {
              mpz_mul_2exp (z, z, sh);
              mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
            }

          inex = mpfr_get_z (got, f, MPFR_RNDZ);

          if (mpz_cmp (got, z) != 0)
            {
              printf ("Wrong result for shift=%d\n", sh);
              printf ("     f "); mpfr_dump (f);
              printf ("   got "); mpz_dump (got);
              printf ("  want "); mpz_dump (z);
              exit (1);
            }
          if (! SAME_SIGN (inex, - mpfr_cmp_z (f, z)))
            {
              printf ("Wrong inexact value for shift=%d\n", sh);
              printf ("    f "); mpfr_dump (f);
              printf ("  got %+d\n", inex);
              printf (" want %+d\n", -mpfr_cmp_z (f, z));
              exit (1);
            }
        }
    }

  mpfr_clear (f);
  mpz_clear (got);
}
Esempio n. 6
0
static void
check_overflow (void)
{
  mpfr_t sum1, sum2, x, y;
  mpfr_ptr t[2 * NOVFL];
  mpfr_exp_t emin, emax;
  int i, r;

  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();
  set_emin (MPFR_EMIN_MIN);
  set_emax (MPFR_EMAX_MAX);

  mpfr_inits2 (32, sum1, sum2, x, y, (mpfr_ptr) 0);
  mpfr_setmax (x, mpfr_get_emax ());
  mpfr_neg (y, x, MPFR_RNDN);

  for (i = 0; i < 2 * NOVFL; i++)
    t[i] = i < NOVFL ? x : y;

  /* Two kinds of test:
   *   i = 1: overflow.
   *   i = 2: intermediate overflow (exact sum is 0).
   */
  for (i = 1; i <= 2; i++)
    RND_LOOP(r)
      {
        int inex1, inex2;

        inex1 = mpfr_add (sum1, x, i == 1 ? x : y, (mpfr_rnd_t) r);
        inex2 = mpfr_sum (sum2, t, i * NOVFL, (mpfr_rnd_t) r);
        MPFR_ASSERTN (mpfr_check (sum1));
        MPFR_ASSERTN (mpfr_check (sum2));
        if (!(mpfr_equal_p (sum1, sum2) && SAME_SIGN (inex1, inex2)))
          {
            printf ("Error in check_overflow on %s, i = %d\n",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
            printf ("Expected ");
            mpfr_dump (sum1);
            printf ("with inex = %d\n", inex1);
            printf ("Got      ");
            mpfr_dump (sum2);
            printf ("with inex = %d\n", inex2);
            exit (1);
          }
      }

  mpfr_clears (sum1, sum2, x, y, (mpfr_ptr) 0);

  set_emin (emin);
  set_emax (emax);
}
Esempio n. 7
0
/* Arguments:
 *   spx: non-zero if px is a stringm zero if px is a MPFR number.
 *   px: value of x (string or MPFR number).
 *   sy: value of y (string).
 *   rnd: rounding mode.
 *   z1: expected result (null pointer if unknown pure FP value).
 *   inex1: expected ternary value (if z1 is not a null pointer).
 *   z2: computed result.
 *   inex2: computed ternary value.
 *   flags1: expected flags (computed flags in __gmpfr_flags).
 *   s1, s2: strings about the context.
 */
static void
cmpres (int spx, const void *px, const char *sy, mpfr_rnd_t rnd,
        mpfr_srcptr z1, int inex1, mpfr_srcptr z2, int inex2,
        unsigned int flags1, const char *s1, const char *s2)
{
  unsigned int flags2 = __gmpfr_flags;

  if (flags1 == flags2)
    {
      /* Note: the test on the sign of z1 and z2 is needed
         in case they are both zeros. */
      if (z1 == NULL)
        {
          if (MPFR_IS_PURE_FP (z2))
            return;
        }
      else if (SAME_SIGN (inex1, inex2) &&
               ((MPFR_IS_NAN (z1) && MPFR_IS_NAN (z2)) ||
                ((MPFR_IS_NEG (z1) ^ MPFR_IS_NEG (z2)) == 0 &&
                 mpfr_equal_p (z1, z2))))
        return;
    }

  printf ("Error in %s\nwith %s%s\nx = ", s1, s2,
          ext ? ", extended exponent range" : "");
  if (spx)
    printf ("%s, ", (char *) px);
  else
    {
      mpfr_out_str (stdout, 16, 0, (mpfr_ptr) px, MPFR_RNDN);
      puts (",");
    }
  printf ("y = %s, %s\n", sy, mpfr_print_rnd_mode (rnd));
  printf ("Expected ");
  if (z1 == NULL)
    {
      printf ("pure FP value, flags = %u\n", flags1);
    }
  else
    {
      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);
  if (all_cmpres_errors != 0)
    all_cmpres_errors = -1;
  else
    exit (1);
}
Esempio n. 8
0
int SturmSequence::signChanges(double x) const {
    uint32_t num = f.size() - 1; // Ignore last polynomial that is constant 0.

    double values[num];
    eval(x,values);

    uint32_t result = 0;
    for(uint32_t i = 1; i < num; i++) {
	if (!SAME_SIGN(values[i], values[i-1])) {
	    result++;
	}
    }
    return result;
}
Esempio n. 9
0
/* Occurs in branches/new-sum/src/sum.c@9344 on a 64-bit machine. */
static void
bug20150327 (void)
{
  mpfr_t sum1, sum2, t[3];
  mpfr_ptr p[3];
  char *s[3] = { "0.10000111110101000010101011100001", "1E-100", "0.1E95" };
  int i, r;

  mpfr_inits2 (58, sum1, sum2, (mpfr_ptr) 0);

  for (i = 0; i < 3; i++)
    {
      mpfr_init2 (t[i], 64);
      mpfr_set_str (t[i], s[i], 2, MPFR_RNDN);
      p[i] = t[i];
    }

  RND_LOOP(r)
    {
      int inex1, inex2;

      mpfr_set (sum1, t[2], MPFR_RNDN);
      inex1 = -1;
      if (MPFR_IS_LIKE_RNDU ((mpfr_rnd_t) r, 1))
        {
          mpfr_nextabove (sum1);
          inex1 = 1;
        }

      inex2 = mpfr_sum (sum2, p, 3, (mpfr_rnd_t) r);

      if (!(mpfr_equal_p (sum1, sum2) && SAME_SIGN (inex1, inex2)))
        {
          printf ("mpfr_sum incorrect in bug20150327 for %s:\n",
                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
          printf ("Expected ");
          mpfr_dump (sum1);
          printf ("with inex = %d\n", inex1);
          printf ("Got      ");
          mpfr_dump (sum2);
          printf ("with inex = %d\n", inex2);
          exit (1);
        }
    }

  for (i = 0; i < 3; i++)
    mpfr_clear (t[i]);
  mpfr_clears (sum1, sum2, (mpfr_ptr) 0);
}
static void
bug20081028 (void)
{
  int i;
  int inexact, res;
  mpfr_rnd_t rnd;
  mpfr_t x, y;
  char *s;

  mpfr_init2 (x, 32);
  mpfr_init2 (y, 32);
  for (i = 0 ; i < numberof (Bug20081028Table) ; i++)
    {
      rnd     = Bug20081028Table[i].rnd;
      inexact = Bug20081028Table[i].inexact;
      mpfr_set_str_binary (x, Bug20081028Table[i].binstr);
      res = mpfr_strtofr (y, Bug20081028Table[i].str, &s, 10, rnd);
      if (s == NULL || *s != 0)
        {
          printf ("Error in Bug20081028: strtofr didn't parse entire input\n"
                  "for (i=%d) Str=\"%s\"", i, Bug20081028Table[i].str);
          exit (1);
        }
      if (! SAME_SIGN (res, inexact))
        {
          printf ("Error in Bug20081028: expected %s ternary value, "
                  "got %d\nfor (i=%d) Rnd=%s Str=\"%s\"\n Set binary gives: ",
                  inexact > 0 ? "positive" : "negative",
                  res, i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
          mpfr_dump (x);
          printf (" strtofr    gives: ");
          mpfr_dump (y);
          exit (1);
        }
      if (mpfr_cmp (x, y))
        {
          printf ("Error in Bug20081028: Results differ between strtofr and "
                  "set_binary\nfor (i=%d) Rnd=%s Str=\"%s\"\n"
                  " Set binary gives: ",
                  i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
          mpfr_dump (x);
          printf (" strtofr    gives: ");
          mpfr_dump (y);
          exit (1);
        }
    }
  mpfr_clear (y);
  mpfr_clear (x);
}
Esempio n. 11
0
File: thypot.c Progetto: Kirija/XPIR
static void
test_small (void)
{
  mpfr_t x, y, z1, z2;
  int inex1, inex2;
  unsigned int flags;

  /* Test hypot(x,x) with x = 2^(emin-1). Result is x * sqrt(2). */
  mpfr_inits2 (8, x, y, z1, z2, (mpfr_ptr) 0);
  mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN);
  mpfr_set_si_2exp (y, 1, mpfr_get_emin () - 1, MPFR_RNDN);
  mpfr_set_ui (z1, 2, MPFR_RNDN);
  inex1 = mpfr_sqrt (z1, z1, MPFR_RNDN);
  inex2 = mpfr_mul (z1, z1, x, MPFR_RNDN);
  MPFR_ASSERTN (inex2 == 0);
  mpfr_clear_flags ();
  inex2 = mpfr_hypot (z2, x, y, MPFR_RNDN);
  flags = __gmpfr_flags;
  if (mpfr_cmp (z1, z2) != 0)
    {
      printf ("Error in test_small%s\nExpected ",
              ext ? ", extended exponent range" : "");
      mpfr_out_str (stdout, 2, 0, z1, MPFR_RNDN);
      printf ("\nGot      ");
      mpfr_out_str (stdout, 2, 0, z2, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }
  if (! SAME_SIGN (inex1, inex2))
    {
      printf ("Bad ternary value in test_small%s\nExpected %d, got %d\n",
              ext ? ", extended exponent range" : "", inex1, inex2);
      exit (1);
    }
  if (flags != MPFR_FLAGS_INEXACT)
    {
      printf ("Bad flags in test_small%s\nExpected %u, got %u\n",
              ext ? ", extended exponent range" : "",
              (unsigned int) MPFR_FLAGS_INEXACT, flags);
      exit (1);
    }
  mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
}
Esempio n. 12
0
/* TODO: A test with more inputs (but can't be compared to mpfr_add). */
static void
check_extreme (void)
{
  mpfr_t u, v, w, x, y;
  mpfr_ptr t[2];
  int i, inex1, inex2, r;

  t[0] = u;
  t[1] = v;

  mpfr_inits2 (32, u, v, w, x, y, (mpfr_ptr) 0);
  mpfr_setmin (u, mpfr_get_emax ());
  mpfr_setmax (v, mpfr_get_emin ());
  mpfr_setmin (w, mpfr_get_emax () - 40);
  RND_LOOP (r)
    for (i = 0; i < 2; i++)
      {
        mpfr_set_prec (x, 64);
        inex1 = mpfr_add (x, u, w, MPFR_RNDN);
        MPFR_ASSERTN (inex1 == 0);
        inex1 = mpfr_prec_round (x, 32, (mpfr_rnd_t) r);
        inex2 = mpfr_sum (y, t, 2, (mpfr_rnd_t) r);
        if (!(mpfr_equal_p (x, y) && SAME_SIGN (inex1, inex2)))
          {
            printf ("Error in check_extreme (%s, i = %d)\n",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
            printf ("Expected ");
            mpfr_dump (x);
            printf ("with inex = %d\n", inex1);
            printf ("Got      ");
            mpfr_dump (y);
            printf ("with inex = %d\n", inex2);
            exit (1);
          }
        mpfr_neg (v, v, MPFR_RNDN);
        mpfr_neg (w, w, MPFR_RNDN);
      }
  mpfr_clears (u, v, w, x, y, (mpfr_ptr) 0);
}
Esempio n. 13
0
static void
check_underflow (void)
{
  mpfr_t sum1, sum2, t[NUNFL];
  mpfr_ptr p[NUNFL];
  mpfr_prec_t precmax = 444;
  mpfr_exp_t emin, emax;
  unsigned int ex_flags, flags;
  int c, i;

  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();
  set_emin (MPFR_EMIN_MIN);
  set_emax (MPFR_EMAX_MAX);

  ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;

  mpfr_init2 (sum1, MPFR_PREC_MIN);
  mpfr_init2 (sum2, precmax);

  for (i = 0; i < NUNFL; i++)
    {
      mpfr_init2 (t[i], precmax);
      p[i] = t[i];
    }

  for (c = 0; c < 8; c++)
    {
      mpfr_prec_t fprec;
      int n, neg, r;

      fprec = MPFR_PREC_MIN + (randlimb () % (precmax - MPFR_PREC_MIN + 1));
      n = 3 + (randlimb () % (NUNFL - 2));
      MPFR_ASSERTN (n <= NUNFL);

      mpfr_set_prec (sum2, (randlimb () & 1) ? MPFR_PREC_MIN : precmax);
      mpfr_set_prec (t[0], fprec + 64);
      mpfr_set_zero (t[0], 1);

      for (i = 1; i < n; i++)
        {
          int inex;

          mpfr_set_prec (t[i], MPFR_PREC_MIN +
                         (randlimb () % (fprec - MPFR_PREC_MIN + 1)));
          do
            mpfr_urandomb (t[i], RANDS);
          while (MPFR_IS_ZERO (t[i]));
          mpfr_set_exp (t[i], MPFR_EMIN_MIN);
          inex = mpfr_sub (t[0], t[0], t[i], MPFR_RNDN);
          MPFR_ASSERTN (inex == 0);
        }

      neg = randlimb () & 1;
      if (neg)
        mpfr_nextbelow (t[0]);
      else
        mpfr_nextabove (t[0]);

      RND_LOOP(r)
        {
          int inex1, inex2;

          mpfr_set_zero (sum1, 1);
          if (neg)
            mpfr_nextbelow (sum1);
          else
            mpfr_nextabove (sum1);
          inex1 = mpfr_div_2ui (sum1, sum1, 2, (mpfr_rnd_t) r);

          mpfr_clear_flags ();
          inex2 = mpfr_sum (sum2, p, n, (mpfr_rnd_t) r);
          flags = __gmpfr_flags;

          MPFR_ASSERTN (mpfr_check (sum1));
          MPFR_ASSERTN (mpfr_check (sum2));

          if (flags != ex_flags)
            {
              printf ("Bad flags in check_underflow on %s, c = %d\n",
                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), c);
              printf ("Expected flags:");
              flags_out (ex_flags);
              printf ("Got flags:     ");
              flags_out (flags);
              printf ("sum = ");
              mpfr_dump (sum2);
              exit (1);
            }

          if (!(mpfr_equal_p (sum1, sum2) && SAME_SIGN (inex1, inex2)))
            {
              printf ("Error in check_underflow on %s, c = %d\n",
                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), c);
              printf ("Expected ");
              mpfr_dump (sum1);
              printf ("with inex = %d\n", inex1);
              printf ("Got      ");
              mpfr_dump (sum2);
              printf ("with inex = %d\n", inex2);
              exit (1);
            }
        }
    }

  for (i = 0; i < NUNFL; i++)
    mpfr_clear (t[i]);
  mpfr_clears (sum1, sum2, (mpfr_ptr) 0);

  set_emin (emin);
  set_emax (emax);
}
Esempio n. 14
0
/* i * 2^(46+h) + j * 2^(45+h) + k * 2^(44+h) + f * 2^(-2),
   with -1 <= i, j, k <= 1, i != 0, -3 <= f <= 3, and
   * prec set up so that ulp(exact sum) = 2^0, then
   * prec set up so that ulp(exact sum) = 2^(44+h) when possible,
     i.e. when prec >= MPFR_PREC_MIN.
   ------
   Some explanations:
   ulp(exact sum) = 2^q means EXP(exact sum) - prec = q where prec is
   the precision of the output. Thus ulp(exact sum) = 2^0 is achieved
   by setting prec = EXP(s3), where s3 is the exact sum (computed with
   mpfr_add's and sufficient precision). Then ulp(exact sum) = 2^(44+h)
   is achieved by subtracting 44+h from prec. The loop on prec does
   this. Since EXP(s3) <= 47+h, prec <= 3 at the second iteration,
   thus there will be at most 2 iterations. Whether a second iteration
   is done or not depends on EXP(s3), i.e. the values of the parameters,
   and the value of MPFR_PREC_MIN. */
static void
check1 (int h)
{
  mpfr_t sum1, sum2, s1, s2, s3, t[4];
  mpfr_ptr p[4];
  int i, j, k, f, prec, r, inex1, inex2;

  mpfr_init2 (sum1, 47 + h);
  mpfr_init2 (sum2, 47 + h);
  mpfr_init2 (s1, 3);
  mpfr_init2 (s2, 3);
  mpfr_init2 (s3, 49 + h);
  for (i = 0; i < 4; i++)
    {
      mpfr_init2 (t[i], 2);
      p[i] = t[i];
    }

  for (i = -1; i <= 1; i += 2)
    {
      mpfr_set_si_2exp (t[0], i, 46 + h, MPFR_RNDN);
      for (j = -1; j <= 1; j++)
        {
          mpfr_set_si_2exp (t[1], j, 45 + h, MPFR_RNDN);
          inex1 = mpfr_add (s1, t[0], t[1], MPFR_RNDN);
          MPFR_ASSERTN (inex1 == 0);
          for (k = -1; k <= 1; k++)
            {
              mpfr_set_si_2exp (t[2], k, 44 + h, MPFR_RNDN);
              inex1 = mpfr_add (s2, s1, t[2], MPFR_RNDN);
              MPFR_ASSERTN (inex1 == 0);
              for (f = -3; f <= 3; f++)
                {
                  mpfr_set_si_2exp (t[3], f, -2, MPFR_RNDN);
                  inex1 = mpfr_add (s3, s2, t[3], MPFR_RNDN);
                  MPFR_ASSERTN (inex1 == 0);
                  for (prec = mpfr_get_exp (s3);
                       prec >= MPFR_PREC_MIN;
                       prec -= 44 + h)
                    {
                      mpfr_set_prec (sum1, prec);
                      mpfr_set_prec (sum2, prec);
                      RND_LOOP (r)
                        {
                          inex1 = mpfr_set (sum1, s3, (mpfr_rnd_t) r);
                          inex2 = mpfr_sum (sum2, p, 4, (mpfr_rnd_t) r);
                          MPFR_ASSERTN (mpfr_check (sum1));
                          MPFR_ASSERTN (mpfr_check (sum2));
                          if (!(mpfr_equal_p (sum1, sum2) &&
                                SAME_SIGN (inex1, inex2)))
                            {
                              printf ("Error in check1 on %s, prec = %d, "
                                      "i = %d, j = %d, k = %d, f = %d, "
                                      "h = %d\n",
                                      mpfr_print_rnd_mode ((mpfr_rnd_t) r),
                                      prec, i, j, k, f, h);
                              printf ("Expected ");
                              mpfr_dump (sum1);
                              printf ("with inex = %d\n", inex1);
                              printf ("Got      ");
                              mpfr_dump (sum2);
                              printf ("with inex = %d\n", inex2);
                              exit (1);
                            }
                        }
                    }
                }
            }
        }
    }

  for (i = 0; i < 4; i++)
    mpfr_clear (t[i]);
  mpfr_clears (sum1, sum2, s1, s2, s3, (mpfr_ptr) 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
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);
}
Esempio n. 17
0
/* With N = 2 * GMP_NUMB_BITS:
   i * 2^N + j + k * 2^(-1) + f1 * 2^(-N) + f2 * 2^(-N),
   with i = -1 or 1, j = 0 or i, -1 <= k <= 1, -1 <= f1 <= 1, -1 <= f2 <= 1
   ulp(exact sum) = 2^0. */
static void
check2 (void)
{
  mpfr_t sum1, sum2, s1, s2, s3, s4, t[5];
  mpfr_ptr p[5];
  int i, j, k, f1, f2, prec, r, inex1, inex2;

#define N (2 * GMP_NUMB_BITS)

  mpfr_init2 (sum1, N+1);
  mpfr_init2 (sum2, N+1);
  mpfr_init2 (s1, N+1);
  mpfr_init2 (s2, N+2);
  mpfr_init2 (s3, 2*N+1);
  mpfr_init2 (s4, 2*N+1);
  for (i = 0; i < 5; i++)
    {
      mpfr_init2 (t[i], 2);
      p[i] = t[i];
    }

  for (i = -1; i <= 1; i += 2)
    {
      mpfr_set_si_2exp (t[0], i, N, MPFR_RNDN);
      for (j = 0; j != 2*i; j += i)
        {
          mpfr_set_si (t[1], j, MPFR_RNDN);
          inex1 = mpfr_add (s1, t[0], t[1], MPFR_RNDN);
          MPFR_ASSERTN (inex1 == 0);
          for (k = -1; k <= 1; k++)
            {
              mpfr_set_si_2exp (t[2], k, -1, MPFR_RNDN);
              inex1 = mpfr_add (s2, s1, t[2], MPFR_RNDN);
              MPFR_ASSERTN (inex1 == 0);
              for (f1 = -1; f1 <= 1; f1++)
                {
                  mpfr_set_si_2exp (t[3], f1, -N, MPFR_RNDN);
                  inex1 = mpfr_add (s3, s2, t[3], MPFR_RNDN);
                  MPFR_ASSERTN (inex1 == 0);
                  for (f2 = -1; f2 <= 1; f2++)
                    {
                      mpfr_set_si_2exp (t[4], f2, -N, MPFR_RNDN);
                      inex1 = mpfr_add (s4, s3, t[4], MPFR_RNDN);
                      MPFR_ASSERTN (inex1 == 0);
                      prec = mpfr_get_exp (s4);
                      mpfr_set_prec (sum1, prec);
                      mpfr_set_prec (sum2, prec);
                      RND_LOOP (r)
                        {
                          inex1 = mpfr_set (sum1, s4, (mpfr_rnd_t) r);
                          inex2 = mpfr_sum (sum2, p, 5, (mpfr_rnd_t) r);
                          MPFR_ASSERTN (mpfr_check (sum1));
                          MPFR_ASSERTN (mpfr_check (sum2));
                          if (!(mpfr_equal_p (sum1, sum2) &&
                                SAME_SIGN (inex1, inex2)))
                            {
                              printf ("Error in check2 on %s, prec = %d, "
                                      "i = %d, j = %d, k = %d, f1 = %d, "
                                      "f2 = %d\n",
                                      mpfr_print_rnd_mode ((mpfr_rnd_t) r),
                                      prec, i, j, k, f1, f2);
                              printf ("Expected ");
                              mpfr_dump (sum1);
                              printf ("with inex = %d\n", inex1);
                              printf ("Got      ");
                              mpfr_dump (sum2);
                              printf ("with inex = %d\n", inex2);
                              exit (1);
                            }
                        }
                    }
                }
            }
        }
    }

  for (i = 0; i < 5; i++)
    mpfr_clear (t[i]);
  mpfr_clears (sum1, sum2, s1, s2, s3, s4, (mpfr_ptr) 0);
}
Esempio n. 18
0
static void
test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
{
  mpfr_prec_t prec, xprec, yprec;
  mpfr_t x, y, z, t, w;
#if defined(TWO_ARGS_ALL)
  mpfr_t u;
#endif
#if defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  double d;
#endif
#if defined(ULONG_ARG1) || defined(ULONG_ARG2)
  unsigned long i;
#endif
  mpfr_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n;
  unsigned long ctrt = 0, ctrn = 0;
  int test_of = 1, test_uf = 1;
  mpfr_exp_t old_emin, old_emax;

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

  mpfr_inits2 (MPFR_PREC_MIN, x, y, z, t, w, (mpfr_ptr) 0);
#if defined(TWO_ARGS_ALL)
  mpfr_init2 (u, MPFR_PREC_MIN);
#endif

  /* generic test */
  for (prec = p0; prec <= p1; prec++)
    {
      mpfr_set_prec (z, prec);
      mpfr_set_prec (t, prec);
      yprec = prec + 10;
      mpfr_set_prec (y, yprec);
      mpfr_set_prec (w, yprec);

      /* Note: in precision p1, we test 4 special cases. */
      for (n = 0; n < (prec == p1 ? nmax + 4 : nmax); n++)
        {
          int infinite_input = 0;
          unsigned int flags;
          mpfr_exp_t oemin, oemax;

          xprec = prec;
          if (randlimb () & 1)
            {
              xprec *= (double) randlimb () / MP_LIMB_T_MAX;
              if (xprec < MPFR_PREC_MIN)
                xprec = MPFR_PREC_MIN;
            }
          mpfr_set_prec (x, xprec);
#if defined(TWO_ARGS)
          mpfr_set_prec (u, xprec);
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
          mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
#elif defined(ULONG_ARG1) || defined(ULONG_ARG2)
          mpfr_set_prec (u, sizeof (unsigned long) * CHAR_BIT);
#endif

          if (n > 3 || prec < p1)
            {
#if defined(RAND_FUNCTION)
              RAND_FUNCTION (x);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
              RAND_FUNCTION (u);
#endif
#else  /* ! defined(RAND_FUNCTION) */
              tests_default_random (x, TEST_RANDOM_POS,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
                                    TEST_RANDOM_ALWAYS_SCALE);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
              tests_default_random (u, TEST_RANDOM_POS2,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
                                    TEST_RANDOM_ALWAYS_SCALE);
#endif
#endif  /* ! defined(RAND_FUNCTION) */
            }
          else
            {
              /* Special cases tested in precision p1 if n <= 3. They are
                 useful really in the extended exponent range. */
#if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO)
              goto next_n;
#endif
              set_emin (MPFR_EMIN_MIN);
              set_emax (MPFR_EMAX_MAX);
              if (n <= 1)
                {
                  mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_set_exp (x, mpfr_get_emin ());
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_set_exp (u, mpfr_get_emin ());
#endif
                }
              else  /* 2 <= n <= 3 */
                {
                  if (getenv ("MPFR_CHECK_MAX") == NULL)
                    goto next_n;
                  mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_setmax (x, REDUCE_EMAX);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_setmax (u, mpfr_get_emax ());
#endif
                }
            }

#if defined(ULONG_ARG1) || defined(ULONG_ARG2)
          i = randlimb ();
          inexact = mpfr_set_ui (u, i, MPFR_RNDN);
          MPFR_ASSERTN (inexact == 0);
#endif

          /* Exponent range for the test. */
          oemin = mpfr_get_emin ();
          oemax = mpfr_get_emax ();

          rnd = RND_RAND ();
          mpfr_clear_flags ();
#ifdef DEBUG_TGENERIC
          TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y));
#endif
#if defined(TWO_ARGS)
          compare = TEST_FUNCTION (y, x, u, rnd);
#elif defined(DOUBLE_ARG1)
          d = mpfr_get_d (u, rnd);
          compare = TEST_FUNCTION (y, d, x, rnd);
          /* d can be infinite due to overflow in mpfr_get_d */
          infinite_input |= DOUBLE_ISINF (d);
#elif defined(DOUBLE_ARG2)
          d = mpfr_get_d (u, rnd);
          compare = TEST_FUNCTION (y, x, d, rnd);
          /* d can be infinite due to overflow in mpfr_get_d */
          infinite_input |= DOUBLE_ISINF (d);
#elif defined(ULONG_ARG1)
          compare = TEST_FUNCTION (y, i, x, rnd);
#elif defined(ULONG_ARG2)
          compare = TEST_FUNCTION (y, x, i, rnd);
#else
          compare = TEST_FUNCTION (y, x, rnd);
#endif
          flags = __gmpfr_flags;
          if (mpfr_get_emin () != oemin ||
              mpfr_get_emax () != oemax)
            {
              printf ("tgeneric: the exponent range has been modified"
                      " by the tested function!\n");
              exit (1);
            }
          TGENERIC_CHECK ("bad inexact flag",
                          (compare != 0) ^ (mpfr_inexflag_p () == 0));
          ctrt++;

          /* Tests in a reduced exponent range. */
          {
            unsigned int oldflags = flags;
            mpfr_exp_t e, emin, emax;

            /* Determine the smallest exponent range containing the
               exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
               and output (y). */
            emin = MPFR_EMAX_MAX;
            emax = MPFR_EMIN_MIN;
            if (MPFR_IS_PURE_FP (x))
              {
                e = MPFR_GET_EXP (x);
                if (e < emin)
                  emin = e;
                if (e > emax)
                  emax = e;
              }
#if defined(TWO_ARGS)
            if (MPFR_IS_PURE_FP (u))
              {
                e = MPFR_GET_EXP (u);
                if (e < emin)
                  emin = e;
                if (e > emax)
                  emax = e;
              }
#endif
            if (MPFR_IS_PURE_FP (y))
              {
                e = MPFR_GET_EXP (y);
                if (test_of && e - 1 >= emax)
                  {
                    unsigned int ex_flags;

                    mpfr_set_emax (e - 1);
                    mpfr_clear_flags ();
#if defined(TWO_ARGS)
                    inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
                    inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
                    inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
                    inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
                    inexact = TEST_FUNCTION (w, x, i, rnd);
#else
                    inexact = TEST_FUNCTION (w, x, rnd);
#endif
                    flags = __gmpfr_flags;
                    mpfr_set_emax (oemax);
                    ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
                    if (flags != ex_flags)
                      {
                        printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
                                ", reduced exponent range [%"
                                MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
                                "d] (overflow test) on:\n",
                                (mpfr_eexp_t) oemin, (mpfr_eexp_t) e - 1);
                        printf ("x = ");
                        mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                        printf ("u = ");
                        mpfr_dump (u);
#endif
                        printf ("yprec = %u, rnd_mode = %s\n",
                                (unsigned int) yprec,
                                mpfr_print_rnd_mode (rnd));
                        printf ("Expected flags =");
                        flags_out (ex_flags);
                        printf ("     got flags =");
                        flags_out (flags);
                        printf ("inex = %d, w = ", inexact);
                        mpfr_dump (w);
                        exit (1);
                      }
                    test_of = 0;  /* Overflow is tested only once. */
                  }
                if (test_uf && e + 1 <= emin)
                  {
                    unsigned int ex_flags;

                    mpfr_set_emin (e + 1);
                    mpfr_clear_flags ();
#if defined(TWO_ARGS)
                    inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
                    inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
                    inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
                    inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
                    inexact = TEST_FUNCTION (w, x, i, rnd);
#else
                    inexact = TEST_FUNCTION (w, x, rnd);
#endif
                    flags = __gmpfr_flags;
                    mpfr_set_emin (oemin);
                    ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
                    if (flags != ex_flags)
                      {
                        printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
                                ", reduced exponent range [%"
                                MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
                                "d] (underflow test) on:\n",
                                (mpfr_eexp_t) e + 1, (mpfr_eexp_t) oemax);
                        printf ("x = ");
                        mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                        printf ("u = ");
                        mpfr_dump (u);
#endif
                        printf ("yprec = %u, rnd_mode = %s\n",
                                (unsigned int) yprec,
                                mpfr_print_rnd_mode (rnd));
                        printf ("Expected flags =");
                        flags_out (ex_flags);
                        printf ("     got flags =");
                        flags_out (flags);
                        printf ("inex = %d, w = ", inexact);
                        mpfr_dump (w);
                        exit (1);
                      }
                    test_uf = 0;  /* Underflow is tested only once. */
                  }
                if (e < emin)
                  emin = e;
                if (e > emax)
                  emax = e;
              }
            if (emin > emax)
              emin = emax;  /* case where all values are singular */
            /* Consistency test in a reduced exponent range. Doing it
               for the first 10 samples and for prec == p1 (which has
               some special cases) should be sufficient. */
            if (ctrt <= 10 || prec == p1)
              {
                mpfr_set_emin (emin);
                mpfr_set_emax (emax);
#ifdef DEBUG_TGENERIC
                /* Useful information in case of assertion failure. */
                printf ("tgeneric: reduced exponent range [%"
                        MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
                        (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
#endif
                mpfr_clear_flags ();
#if defined(TWO_ARGS)
                inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
                inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
                inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
                inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
                inexact = TEST_FUNCTION (w, x, i, rnd);
#else
                inexact = TEST_FUNCTION (w, x, rnd);
#endif
                flags = __gmpfr_flags;
                mpfr_set_emin (oemin);
                mpfr_set_emax (oemax);
                if (! (SAME_VAL (w, y) &&
                       SAME_SIGN (inexact, compare) &&
                       flags == oldflags))
                  {
                    printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
                            ", reduced exponent range [%"
                            MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
                            (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
                    printf ("x = ");
                    mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                    printf ("u = ");
                    mpfr_dump (u);
#endif
                    printf ("yprec = %u, rnd_mode = %s\n",
                            (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
                    printf ("Expected:\n  y = ");
                    mpfr_dump (y);
                    printf ("  inex = %d, flags =", compare);
                    flags_out (oldflags);
                    printf ("Got:\n  w = ");
                    mpfr_dump (w);
                    printf ("  inex = %d, flags =", inexact);
                    flags_out (flags);
                    exit (1);
                  }
              }
            __gmpfr_flags = oldflags;  /* restore the flags */
          }

          if (MPFR_IS_SINGULAR (y))
            {
              if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())
                TGENERIC_CHECK ("bad NaN flag",
                                MPFR_IS_NAN (y) && mpfr_nanflag_p ());
              else if (MPFR_IS_INF (y))
                {
                  TGENERIC_CHECK ("bad overflow flag",
                                  (compare != 0) ^ (mpfr_overflow_p () == 0));
                  TGENERIC_CHECK ("bad divide-by-zero flag",
                                  (compare == 0 && !infinite_input) ^
                                  (mpfr_divby0_p () == 0));
                }
              else if (MPFR_IS_ZERO (y))
                TGENERIC_CHECK ("bad underflow flag",
                                (compare != 0) ^ (mpfr_underflow_p () == 0));
            }
          else if (mpfr_divby0_p ())
            {
              TGENERIC_CHECK ("both overflow and divide-by-zero",
                              ! mpfr_overflow_p ());
              TGENERIC_CHECK ("both underflow and divide-by-zero",
                              ! mpfr_underflow_p ());
              TGENERIC_CHECK ("bad compare value (divide-by-zero)",
                              compare == 0);
            }
          else if (mpfr_overflow_p ())
            {
              TGENERIC_CHECK ("both underflow and overflow",
                              ! mpfr_underflow_p ());
              TGENERIC_CHECK ("bad compare value (overflow)", compare != 0);
              mpfr_nexttoinf (y);
              TGENERIC_CHECK ("should have been max MPFR number (overflow)",
                              MPFR_IS_INF (y));
            }
          else if (mpfr_underflow_p ())
            {
              TGENERIC_CHECK ("bad compare value (underflow)", compare != 0);
              mpfr_nexttozero (y);
              TGENERIC_CHECK ("should have been min MPFR number (underflow)",
                              MPFR_IS_ZERO (y));
            }
          else if (mpfr_can_round (y, yprec, rnd, rnd, prec))
            {
              ctrn++;
              mpfr_set (t, y, rnd);
              /* Risk of failures are known when some flags are already set
                 before the function call. Do not set the erange flag, as
                 it will remain set after the function call and no checks
                 are performed in such a case (see the mpfr_erangeflag_p
                 test below). */
              if (randlimb () & 1)
                __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
#ifdef DEBUG_TGENERIC
              TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z));
#endif
              /* Let's increase the precision of the inputs in a random way.
                 In most cases, this doesn't make any difference, but for
                 the mpfr_fmod bug fixed in r6230, this triggers the bug. */
              mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
                               MPFR_RNDN);
#if defined(TWO_ARGS)
              mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
                               MPFR_RNDN);
              inexact = TEST_FUNCTION (z, x, u, rnd);
#elif defined(DOUBLE_ARG1)
              inexact = TEST_FUNCTION (z, d, x, rnd);
#elif defined(DOUBLE_ARG2)
              inexact = TEST_FUNCTION (z, x, d, rnd);
#elif defined(ULONG_ARG1)
              inexact = TEST_FUNCTION (z, i, x, rnd);
#elif defined(ULONG_ARG2)
              inexact = TEST_FUNCTION (z, x, i, rnd);
#else
              inexact = TEST_FUNCTION (z, x, rnd);
#endif
              if (mpfr_erangeflag_p ())
                goto next_n;
              if (! mpfr_equal_p (t, z))
                {
                  printf ("tgeneric: results differ for "
                          MAKE_STR(TEST_FUNCTION) " on\n  x = ");
                  mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                  printf ("  u = ");
                  mpfr_dump (u);
#endif
                  printf ("  prec = %u, rnd_mode = %s\n",
                          (unsigned int) prec, mpfr_print_rnd_mode (rnd));
                  printf ("Got      ");
                  mpfr_dump (z);
                  printf ("Expected ");
                  mpfr_dump (t);
                  printf ("Approx   ");
                  mpfr_dump (y);
                  exit (1);
                }
              compare2 = mpfr_cmp (t, y);
              /* if rounding to nearest, cannot know the sign of t - f(x)
                 because of composed rounding: y = o(f(x)) and t = o(y) */
              if (compare * compare2 >= 0)
                compare = compare + compare2;
              else
                compare = inexact; /* cannot determine sign(t-f(x)) */
              if (! SAME_SIGN (inexact, compare))
                {
                  printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
                          "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
                  printf ("x = ");
                  mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                  printf ("u = ");
                  mpfr_dump (u);
#endif
                  printf ("y = ");
                  mpfr_dump (y);
                  printf ("t = ");
                  mpfr_dump (t);
                  exit (1);
                }
            }
          else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL)
            {
              /* For developers only! */
              MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
              mpfr_nexttoinf (y);
              if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))
                  && !mpfr_overflow_p () && TGENERIC_SO_TEST)
                {
                  printf ("Possible bug! |y| is the maximum finite number "
                          "and has been obtained when\nrounding toward zero"
                          " (%s). Thus there is a very probable overflow,\n"
                          "but the overflow flag is not set!\n",
                          mpfr_print_rnd_mode (rnd));
                  printf ("x = ");
                  mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                  printf ("u = ");
                  mpfr_dump (u);
#endif
                  exit (1);
                }
            }

        next_n:
          /* In case the exponent range has been changed by
             tests_default_random() or for special values... */
          mpfr_set_emin (old_emin);
          mpfr_set_emax (old_emax);
        }
    }

#ifndef TGENERIC_NOWARNING
  if (3 * ctrn < 2 * ctrt)
    printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n",
            ctrn, ctrt);
#endif

  mpfr_clears (x, y, z, t, w, (mpfr_ptr) 0);
#if defined(TWO_ARGS_ALL)
  mpfr_clear (u);
#endif
}
Esempio n. 19
0
static int
mpfr_all_div (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t r)
{
  mpfr_t a2;
  unsigned int oldflags, newflags;
  int inex, inex2;

  oldflags = __gmpfr_flags;
  inex = mpfr_div (a, b, c, r);

  if (a == b || a == c)
    return inex;

  newflags = __gmpfr_flags;

  mpfr_init2 (a2, MPFR_PREC (a));

  if (mpfr_integer_p (b) && ! (MPFR_IS_ZERO (b) && MPFR_IS_NEG (b)))
    {
      /* b is an integer, but not -0 (-0 is rejected as
         it becomes +0 when converted to an integer). */
      if (mpfr_fits_ulong_p (b, MPFR_RNDA))
        {
          __gmpfr_flags = oldflags;
          inex2 = mpfr_ui_div (a2, mpfr_get_ui (b, MPFR_RNDN), c, r);
          MPFR_ASSERTN (SAME_SIGN (inex2, inex));
          MPFR_ASSERTN (__gmpfr_flags == newflags);
          check_equal (a, a2, "mpfr_ui_div", b, c, r);
        }
      if (mpfr_fits_slong_p (b, MPFR_RNDA))
        {
          __gmpfr_flags = oldflags;
          inex2 = mpfr_si_div (a2, mpfr_get_si (b, MPFR_RNDN), c, r);
          MPFR_ASSERTN (SAME_SIGN (inex2, inex));
          MPFR_ASSERTN (__gmpfr_flags == newflags);
          check_equal (a, a2, "mpfr_si_div", b, c, r);
        }
    }

  if (mpfr_integer_p (c) && ! (MPFR_IS_ZERO (c) && MPFR_IS_NEG (c)))
    {
      /* c is an integer, but not -0 (-0 is rejected as
         it becomes +0 when converted to an integer). */
      if (mpfr_fits_ulong_p (c, MPFR_RNDA))
        {
          __gmpfr_flags = oldflags;
          inex2 = mpfr_div_ui (a2, b, mpfr_get_ui (c, MPFR_RNDN), r);
          MPFR_ASSERTN (SAME_SIGN (inex2, inex));
          MPFR_ASSERTN (__gmpfr_flags == newflags);
          check_equal (a, a2, "mpfr_div_ui", b, c, r);
        }
      if (mpfr_fits_slong_p (c, MPFR_RNDA))
        {
          __gmpfr_flags = oldflags;
          inex2 = mpfr_div_si (a2, b, mpfr_get_si (c, MPFR_RNDN), r);
          MPFR_ASSERTN (SAME_SIGN (inex2, inex));
          MPFR_ASSERTN (__gmpfr_flags == newflags);
          check_equal (a, a2, "mpfr_div_si", b, c, r);
        }
    }

  mpfr_clear (a2);

  return inex;
}
Esempio n. 20
0
/**
 * Brent's method is a root-finding algorithm which combines root 
 * bracketing, interval bisection, and inverse quadratic interpolation. 
 * It is sometimes known as the van Wijngaarden-Deker-Brent method.
 *
 * Using the algorithm from Numerical Recipes in FORTRAN.
 *
 * @see http://www.library.cornell.edu/nr/cbookfpdf.html
 */
int RootFinder::brents_method(double x1, double x2, double* root) {
    double a,b,c;
    double r,s;
    double p,q;
    double fa,fb,fc;
    double tol,m;
    bool ac_equal;
    double e,d;

    d = x2 - x1;
    e = d;

    a = x1;
    b = x2;
    c = b;

    fa = f(a);
    fb = f(b);
    fc = f(c);

    if (SAME_SIGN(fa, fb))
	return false;

    uint32_t i = 3;
    while(i++ < MAX_ITER) {
	ac_equal = false;

	if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0)) {
	    ac_equal = true;
	    c = a;
	    fc = fa;
	    d = b - a;
	    e = b - a;
	}

	if (fabs(fc) < fabs(fb)) {
	    ac_equal = true;
	    a = b;
	    b = c;
	    c = a;
	    fa = fb;
	    fb = fc;
	    fc = fa;
	}

	//tol = 0.5 * DBL_EPSILON * fabs (b) + 0.5 * tolerance;
	tol = 0.5 * DBL_EPSILON * fabs (b);
	
	m = 0.5 * (c - b);

	if (fabs(fb) < tolerance) {
	    *root = b;
	    return i;
	}

	/*
	if (fabs(m) < tol) {
	    *root = b;
	    return i;
	}
	*/

	if (fabs(e) < tol || fabs(fa) <= fabs(fb)) {
	    // Using bisection
	    d = m;
	    e = m;
	} else {
	    // Use inverse cubic interpolation
	    s = fb / fa;

	    if (ac_equal) {
		p = 2 * m * s;
		q = 1 - s;
	    } else {
		q = fa / fb;
		r = fb / fc;
		p = s * (2 * m * q * (q - r) - (b - a) * (r - 1));
		q = (q - 1) * (r - 1) * (s - 1);
	    }

	    if (p > 0) {
		q = -q;
	    } else {
		p = -p;
	    }

	    if (2 * p < MIN(3 * m * q - fabs(tol * q), fabs (e * q)))
	    {
		e = d;
		d = p / q;
	    } else {
		// interpolation failed, fall back to bisection
		d = m;
		e = m;
	    }
	}

	a = b;
	fa = fb;

	if (fabs (d) > tol) {
	    b += d;
	} else {
	    //b += (m > 0 ? +tol : -tol);
	    b += copysign(tol,m);
	}

	fb = f(b);
    }
    return false;
}
Esempio n. 21
0
/* t[i] = (2^17 - 1) * 2^(17*(i-8)) for 0 <= i <= 16.
 * t[17] = 2^(17*9+1) * j for -4 <= j <= 4.
 * t[18] = 2^(-1) * k for -1 <= k <= 1.
 * t[19] = 2^(-17*8) * m for -3 <= m <= 3.
 * prec = MPFR_PREC_MIN and 17*9+4
 */
static void
check3 (void)
{
  mpfr_t sum1, sum2, s1, s2, s3, s4, t[20];
  mpfr_ptr p[20];
  mpfr_flags_t flags1, flags2;
  int i, s, j, k, m, q, r, inex1, inex2;
  int prec[2] = { MPFR_PREC_MIN, 17*9+4 };

  mpfr_init2 (s1, 17*17);
  mpfr_init2 (s2, 17*17+4);
  mpfr_init2 (s3, 17*17+4);
  mpfr_init2 (s4, 17*17+5);
  mpfr_set_ui (s1, 0, MPFR_RNDN);
  for (i = 0; i < 20; i++)
    {
      mpfr_init2 (t[i], 20);
      p[i] = t[i];
      if (i < 17)
        {
          mpfr_set_ui_2exp (t[i], 0x1ffff, 17*(i-8), MPFR_RNDN);
          inex1 = mpfr_add (s1, s1, t[i], MPFR_RNDN);
          MPFR_ASSERTN (inex1 == 0);
        }
    }

  for (s = 1; s >= -1; s -= 2)
    {
      for (j = -4; j <= 4; j++)
        {
          mpfr_set_si_2exp (t[17], j, 17*9+1, MPFR_RNDN);
          inex1 = mpfr_add (s2, s1, t[17], MPFR_RNDN);
          MPFR_ASSERTN (inex1 == 0);
          for (k = -1; k <= 1; k++)
            {
              mpfr_set_si_2exp (t[18], k, -1, MPFR_RNDN);
              inex1 = mpfr_add (s3, s2, t[18], MPFR_RNDN);
              MPFR_ASSERTN (inex1 == 0);
              for (m = -3; m <= 3; m++)
                {
                  mpfr_set_si_2exp (t[19], m, -17*8, MPFR_RNDN);
                  inex1 = mpfr_add (s4, s3, t[19], MPFR_RNDN);
                  MPFR_ASSERTN (inex1 == 0);
                  for (q = 0; q < 2; q++)
                    {
                      mpfr_inits2 (prec[q], sum1, sum2, (mpfr_ptr) 0);
                      RND_LOOP (r)
                        {
                          mpfr_clear_flags ();
                          inex1 = mpfr_set (sum1, s4, (mpfr_rnd_t) r);
                          flags1 = __gmpfr_flags;
                          mpfr_clear_flags ();
                          inex2 = mpfr_sum (sum2, p, 20, (mpfr_rnd_t) r);
                          flags2 = __gmpfr_flags;
                          MPFR_ASSERTN (mpfr_check (sum1));
                          MPFR_ASSERTN (mpfr_check (sum2));
                          if (!(mpfr_equal_p (sum1, sum2) &&
                                SAME_SIGN (inex1, inex2) &&
                                flags1 == flags2))
                            {
                              printf ("Error in check3 on %s, "
                                      "s = %d, j = %d, k = %d, m = %d\n",
                                      mpfr_print_rnd_mode ((mpfr_rnd_t) r),
                                      s, j, k, m);
                              printf ("Expected ");
                              mpfr_dump (sum1);
                              printf ("with inex = %d and flags =", inex1);
                              flags_out (flags1);
                              printf ("Got      ");
                              mpfr_dump (sum2);
                              printf ("with inex = %d and flags =", inex2);
                              flags_out (flags2);
                              exit (1);
                            }
                        }
                      mpfr_clears (sum1, sum2, (mpfr_ptr) 0);
                    }  /* q */
                }  /* m */
            }  /* k */
        }  /* j */
      for (i = 0; i < 17; i++)
        mpfr_neg (t[i], t[i], MPFR_RNDN);
      mpfr_neg (s1, s1, MPFR_RNDN);
    }  /* s */

  for (i = 0; i < 20; i++)
    mpfr_clear (t[i]);
  mpfr_clears (s1, s2, s3, s4, (mpfr_ptr) 0);
}
Esempio n. 22
0
/* Test of s * (q * 2^(n-1) - 2^k) + h + i * 2^(-2) + j * 2^(-2)
 * with h = -1 or 1, -1 <= i odd <= j <= 3, 2 <= q <= 3, s = -1 or 1,
 * prec n-k.
 * On a 64-bit machine:
 * MPFR_RNDN, tmd=2, rbit=0, sst=0, negative is checked with the inputs
 *   -3*2^58, 2^5, -1, 2^(-2), 3*2^(-2)
 * MPFR_RNDN, tmd=2, rbit=0, sst=1, negative is checked with the inputs
 *   -3*2^58, 2^5, -1, 3*2^(-2), 3*2^(-2)
 *
 * Note: This test detects an error in a result when "sq + 3" is replaced
 * by "sq + 2" (11th argument of the first sum_raw invocation) and the
 * corresponding assertion d >= 3 is removed, confirming that one cannot
 * decrease this proved error bound.
 */
static void
check4 (void)
{
  mpfr_t sum1, sum2, s1, s2, s3, s4, t[5];
  mpfr_ptr p[5];
  int h, i, j, k, n, q, r, s, prec, inex1, inex2;

  mpfr_inits2 (257, sum1, sum2, s1, s2, s3, s4, (mpfr_ptr) 0);
  for (i = 0; i < 5; i++)
    {
      mpfr_init2 (t[i], 2);
      p[i] = t[i];
    }

  /* No GNU style for the many nested loops... */
  for (k = 1; k <= 64; k++) {
    mpfr_set_si_2exp (t[0], -1, k, MPFR_RNDN);
    for (n = k + MPFR_PREC_MIN; n <= k + 65; n++) {
      prec = n - k;
      mpfr_set_prec (sum1, prec);
      mpfr_set_prec (sum2, prec);
      for (q = 2; q <= 3; q++) {
        mpfr_set_si_2exp (t[1], q, n - 1, MPFR_RNDN);
        inex1 = mpfr_add (s1, t[0], t[1], MPFR_RNDN);
        MPFR_ASSERTN (inex1 == 0);
        for (s = -1; s <= 1; s += 2) {
          mpfr_neg (t[0], t[0], MPFR_RNDN);
          mpfr_neg (t[1], t[1], MPFR_RNDN);
          mpfr_neg (s1, s1, MPFR_RNDN);
          for (h = -1; h <= 1; h += 2) {
            mpfr_set_si (t[2], h, MPFR_RNDN);
            inex1 = mpfr_add (s2, s1, t[2], MPFR_RNDN);
            MPFR_ASSERTN (inex1 == 0);
            for (i = -1; i <= 3; i += 2) {
              mpfr_set_si_2exp (t[3], i, -2, MPFR_RNDN);
              inex1 = mpfr_add (s3, s2, t[3], MPFR_RNDN);
              MPFR_ASSERTN (inex1 == 0);
              for (j = i; j <= 3; j++) {
                mpfr_set_si_2exp (t[4], j, -2, MPFR_RNDN);
                inex1 = mpfr_add (s4, s3, t[4], MPFR_RNDN);
                MPFR_ASSERTN (inex1 == 0);
                RND_LOOP (r) {
                  inex1 = mpfr_set (sum1, s4, (mpfr_rnd_t) r);
                  inex2 = mpfr_sum (sum2, p, 5, (mpfr_rnd_t) r);
                  MPFR_ASSERTN (mpfr_check (sum1));
                  MPFR_ASSERTN (mpfr_check (sum2));
                  if (!(mpfr_equal_p (sum1, sum2) &&
                        SAME_SIGN (inex1, inex2)))
                    {
                      printf ("Error in check4 on %s, "
                              "k = %d, n = %d (prec %d), "
                              "q = %d, s = %d, h = %d, i = %d, j = %d\n",
                              mpfr_print_rnd_mode ((mpfr_rnd_t) r),
                              k, n, prec, q, s, h, i, j);
                      printf ("Expected ");
                      mpfr_dump (sum1);
                      printf ("with inex = %d\n", inex1);
                      printf ("Got      ");
                      mpfr_dump (sum2);
                      printf ("with inex = %d\n", inex2);
                      exit (1);
                    }
                }
              }
            }
          }
        }
      }
    }
  }

  for (i = 0; i < 5; i++)
    mpfr_clear (t[i]);
  mpfr_clears (sum1, sum2, s1, s2, s3, s4, (mpfr_ptr) 0);
}
Esempio n. 23
0
int
mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  mpfr_t xf;
  mp_limb_t xf_limb[(53 - 1) / GMP_NUMB_BITS + 1];
  int inex, large;
  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, inex));

  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)) /* erf(+inf) = +1, erf(-inf) = -1 */
        return mpfr_set_si (y, MPFR_INT_SIGN (x), MPFR_RNDN);
      else /* erf(+0) = +0, erf(-0) = -0 */
        {
          MPFR_ASSERTD (MPFR_IS_ZERO (x));
          return mpfr_set (y, x, MPFR_RNDN); /* should keep the sign of x */
        }
    }

  /* now x is neither NaN, Inf nor 0 */

  /* first try expansion at x=0 when x is small, or asymptotic expansion
     where x is large */

  MPFR_SAVE_EXPO_MARK (expo);

  /* around x=0, we have erf(x) = 2x/sqrt(Pi) (1 - x^2/3 + ...),
     with 1 - x^2/3 <= sqrt(Pi)*erf(x)/2/x <= 1 for x >= 0. This means that
     if x^2/3 < 2^(-PREC(y)-1) we can decide of the correct rounding,
     unless we have a worst-case for 2x/sqrt(Pi). */
  if (MPFR_EXP(x) < - (mpfr_exp_t) (MPFR_PREC(y) / 2))
    {
      /* we use 2x/sqrt(Pi) (1 - x^2/3) <= erf(x) <= 2x/sqrt(Pi) for x > 0
         and 2x/sqrt(Pi) <= erf(x) <= 2x/sqrt(Pi) (1 - x^2/3) for x < 0.
         In both cases |2x/sqrt(Pi) (1 - x^2/3)| <= |erf(x)| <= |2x/sqrt(Pi)|.
         We will compute l and h such that l <= |2x/sqrt(Pi) (1 - x^2/3)|
         and |2x/sqrt(Pi)| <= h. If l and h round to the same value to
         precision PREC(y) and rounding rnd_mode, then we are done. */
      mpfr_t l, h; /* lower and upper bounds for erf(x) */
      int ok, inex2;

      mpfr_init2 (l, MPFR_PREC(y) + 17);
      mpfr_init2 (h, MPFR_PREC(y) + 17);
      /* first compute l */
      mpfr_mul (l, x, x, MPFR_RNDU);
      mpfr_div_ui (l, l, 3, MPFR_RNDU); /* upper bound on x^2/3 */
      mpfr_ui_sub (l, 1, l, MPFR_RNDZ); /* lower bound on 1 - x^2/3 */
      mpfr_const_pi (h, MPFR_RNDU); /* upper bound of Pi */
      mpfr_sqrt (h, h, MPFR_RNDU); /* upper bound on sqrt(Pi) */
      mpfr_div (l, l, h, MPFR_RNDZ); /* lower bound on 1/sqrt(Pi) (1 - x^2/3) */
      mpfr_mul_2ui (l, l, 1, MPFR_RNDZ); /* 2/sqrt(Pi) (1 - x^2/3) */
      mpfr_mul (l, l, x, MPFR_RNDZ); /* |l| is a lower bound on
                                       |2x/sqrt(Pi) (1 - x^2/3)| */
      /* now compute h */
      mpfr_const_pi (h, MPFR_RNDD); /* lower bound on Pi */
      mpfr_sqrt (h, h, MPFR_RNDD); /* lower bound on sqrt(Pi) */
      mpfr_div_2ui (h, h, 1, MPFR_RNDD); /* lower bound on sqrt(Pi)/2 */
      /* since sqrt(Pi)/2 < 1, the following should not underflow */
      mpfr_div (h, x, h, MPFR_IS_POS(x) ? MPFR_RNDU : MPFR_RNDD);
      /* round l and h to precision PREC(y) */
      inex = mpfr_prec_round (l, MPFR_PREC(y), rnd_mode);
      inex2 = mpfr_prec_round (h, MPFR_PREC(y), rnd_mode);
      /* Caution: we also need inex=inex2 (inex might be 0). */
      ok = SAME_SIGN (inex, inex2) && mpfr_cmp (l, h) == 0;
      if (ok)
        mpfr_set (y, h, rnd_mode);
      mpfr_clear (l);
      mpfr_clear (h);
      if (ok)
        goto end;
      /* this test can still fail for small precision, for example
         for x=-0.100E-2 with a target precision of 3 bits, since
         the error term x^2/3 is not that small. */
    }

  MPFR_TMP_INIT1(xf_limb, xf, 53);
  mpfr_div (xf, x, __gmpfr_const_log2_RNDU, MPFR_RNDZ); /* round to zero
                        ensures we get a lower bound of |x/log(2)| */
  mpfr_mul (xf, xf, x, MPFR_RNDZ);
  large = mpfr_cmp_ui (xf, MPFR_PREC (y) + 1) > 0;

  /* when x goes to infinity, we have erf(x) = 1 - 1/sqrt(Pi)/exp(x^2)/x + ...
     and |erf(x) - 1| <= exp(-x^2) is true for any x >= 0, thus if
     exp(-x^2) < 2^(-PREC(y)-1) the result is 1 or 1-epsilon.
     This rewrites as x^2/log(2) > p+1. */
  if (MPFR_UNLIKELY (large))
    /* |erf x| = 1 or 1- */
    {
      mpfr_rnd_t rnd2 = MPFR_IS_POS (x) ? rnd_mode : MPFR_INVERT_RND(rnd_mode);
      if (rnd2 == MPFR_RNDN || rnd2 == MPFR_RNDU || rnd2 == MPFR_RNDA)
        {
          inex = MPFR_INT_SIGN (x);
          mpfr_set_si (y, inex, rnd2);
        }
      else /* round to zero */
        {
          inex = -MPFR_INT_SIGN (x);
          mpfr_setmax (y, 0); /* warning: setmax keeps the old sign of y */
          MPFR_SET_SAME_SIGN (y, x);
        }
    }
  else  /* use Taylor */
    {
      double xf2;

      /* FIXME: get rid of doubles/mpfr_get_d here */
      xf2 = mpfr_get_d (x, MPFR_RNDN);
      xf2 = xf2 * xf2; /* xf2 ~ x^2 */
      inex = mpfr_erf_0 (y, x, xf2, rnd_mode);
    }

 end:
  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (y, inex, rnd_mode);
}
Esempio n. 24
0
static void
check1 (void)
{
  mpfr_t x;
  int i, j, k, s, old_inex, tiny, expj;
  mpfr_exp_t emin, emax;
  unsigned int expflags, flags;

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

  mpfr_set_default_prec (9);
  mpfr_set_emin (-10);
  mpfr_set_emax (10);

  mpfr_init (x);
  for (i = 0; i < numberof (tab); i++)
    for (s = 0; s <= (tab[i].rnd == MPFR_RNDN); s++)
      for (k = 0; k <= 1; k++)
        {
          mpfr_set_str (x, tab[i].in, 2, MPFR_RNDN);
          old_inex = tab[i].i;
          expj = tab[i].j;
          if (s)
            {
              mpfr_neg (x, x, MPFR_RNDN);
              old_inex = - old_inex;
              expj = - expj;
            }
          if (k && old_inex)
            old_inex = old_inex < 0 ? INT_MIN : INT_MAX;
          tiny = MPFR_GET_EXP (x) <= -3;
          mpfr_clear_flags ();
          j = mpfr_subnormalize (x, old_inex, tab[i].rnd);
          expflags =
            (tiny ? MPFR_FLAGS_UNDERFLOW : 0) |
            (expj ? MPFR_FLAGS_INEXACT : 0);
          flags = __gmpfr_flags;
          if (s)
            mpfr_neg (x, x, MPFR_RNDN);
          if (mpfr_cmp_str (x, tab[i].out, 2, MPFR_RNDN) != 0 ||
              flags != expflags || ! SAME_SIGN (j, expj))
            {
              const char *sgn = s ? "-" : "";
              printf ("Error for i = %d (old_inex = %d), k = %d, x = %s%s\n"
                      "Expected: %s%s\nGot:      ", i, old_inex, k,
                      sgn, tab[i].in, sgn, tab[i].out);
              if (s)
                mpfr_neg (x, x, MPFR_RNDN);
              mpfr_dump (x);
              printf ("Expected flags = %u, got %u\n", expflags, flags);
              printf ("Expected ternary value = %d, got %d\n", expj, j);
              exit (1);
            }
        }
  mpfr_clear (x);

  MPFR_ASSERTN (mpfr_get_emin () == -10);
  MPFR_ASSERTN (mpfr_get_emax () == 10);

  set_emin (emin);
  set_emax (emax);
}
Esempio n. 25
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y, z, s;
  mpfr_exp_t emin, emax;

  tests_start_mpfr ();

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

  bug20101018 ();

  mpfr_init (x);
  mpfr_init (s);
  mpfr_init (y);
  mpfr_init (z);

  /* check special cases */
  mpfr_set_prec (x, 2);
  mpfr_set_prec (y, 2);
  mpfr_set_prec (z, 2);
  mpfr_set_prec (s, 2);
  mpfr_set_str (x, "-0.75", 10, MPFR_RNDN);
  mpfr_set_str (y, "0.5", 10, MPFR_RNDN);
  mpfr_set_str (z, "0.375", 10, MPFR_RNDN);
  mpfr_fma (s, x, y, z, MPFR_RNDU); /* result is 0 */
  if (mpfr_cmp_ui (s, 0))
    {
      printf ("Error: -0.75 * 0.5 + 0.375 should be equal to 0 for prec=2\n");
      printf ("got instead ");
      mpfr_dump (s);
      exit (1);
    }

  mpfr_set_prec (x, 27);
  mpfr_set_prec (y, 27);
  mpfr_set_prec (z, 27);
  mpfr_set_prec (s, 27);
  mpfr_set_str_binary (x, "1.11111111111111111111111111e-1");
  mpfr_set (y, x, MPFR_RNDN);
  mpfr_set_str_binary (z, "-1.00011110100011001011001001e-1");
  if (mpfr_fma (s, x, y, z, MPFR_RNDN) >= 0)
    {
      printf ("Wrong inexact flag for x=y=1-2^(-27)\n");
      exit (1);
    }

  mpfr_set_nan (x);
  mpfr_urandomb (y, RANDS);
  mpfr_urandomb (z, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_nan_p (s))
    {
      printf ("evaluation of function in x=NAN does not return NAN\n");
      exit (1);
    }

  mpfr_set_nan (y);
  mpfr_urandomb (x, RANDS);
  mpfr_urandomb (z, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_nan_p(s))
    {
      printf ("evaluation of function in y=NAN does not return NAN\n");
      exit (1);
    }

  mpfr_set_nan (z);
  mpfr_urandomb (y, RANDS);
  mpfr_urandomb (x, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_nan_p (s))
    {
      printf ("evaluation of function in z=NAN does not return NAN\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_set_inf (y, 1);
  mpfr_set_inf (z, 1);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
    {
      printf ("Error for (+inf) * (+inf) + (+inf)\n");
      exit (1);
    }

  mpfr_set_inf (x, -1);
  mpfr_set_inf (y, -1);
  mpfr_set_inf (z, 1);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
    {
      printf ("Error for (-inf) * (-inf) + (+inf)\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_set_inf (y, -1);
  mpfr_set_inf (z, -1);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0)
    {
      printf ("Error for (+inf) * (-inf) + (-inf)\n");
      exit (1);
    }

  mpfr_set_inf (x, -1);
  mpfr_set_inf (y, 1);
  mpfr_set_inf (z, -1);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0)
    {
      printf ("Error for (-inf) * (+inf) + (-inf)\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_set_ui (y, 0, MPFR_RNDN);
  mpfr_urandomb (z, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_nan_p (s))
    {
      printf ("evaluation of function in x=INF y=0  does not return NAN\n");
      exit (1);
    }

  mpfr_set_inf (y, 1);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_urandomb (z, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_nan_p (s))
    {
      printf ("evaluation of function in x=0 y=INF does not return NAN\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_urandomb (y, RANDS); /* always positive */
  mpfr_set_inf (z, -1);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_nan_p (s))
    {
      printf ("evaluation of function in x=INF y>0 z=-INF does not return NAN\n");
      exit (1);
    }

  mpfr_set_inf (y, 1);
  mpfr_urandomb (x, RANDS);
  mpfr_set_inf (z, -1);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_nan_p (s))
    {
      printf ("evaluation of function in x>0 y=INF z=-INF does not return NAN\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  do mpfr_urandomb (y, RANDS); while (MPFR_IS_ZERO(y));
  mpfr_urandomb (z, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
    {
      printf ("evaluation of function in x=INF does not return INF\n");
      exit (1);
    }

  mpfr_set_inf (y, 1);
  do mpfr_urandomb (x, RANDS); while (MPFR_IS_ZERO(x));
  mpfr_urandomb (z, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
    {
      printf ("evaluation of function at y=INF does not return INF\n");
      exit (1);
    }

  mpfr_set_inf (z, 1);
  mpfr_urandomb (x, RANDS);
  mpfr_urandomb (y, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
    {
      printf ("evaluation of function in z=INF does not return INF\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_urandomb (y, RANDS);
  mpfr_urandomb (z, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (! mpfr_equal_p (s, z))
    {
      printf ("evaluation of function in x=0 does not return z\n");
      exit (1);
    }

  mpfr_set_ui (y, 0, MPFR_RNDN);
  mpfr_urandomb (x, RANDS);
  mpfr_urandomb (z, RANDS);
  mpfr_fma (s, x, y, z, MPFR_RNDN);
  if (! mpfr_equal_p (s, z))
    {
      printf ("evaluation of function in y=0 does not return z\n");
      exit (1);
    }

  {
    mpfr_prec_t prec;
    mpfr_t t, slong;
    mpfr_rnd_t rnd;
    int inexact, compare;
    unsigned int n;

    mpfr_prec_t p0 = 2, p1 = 200;
    unsigned int N = 200;

    mpfr_init (t);
    mpfr_init (slong);

    /* generic test */
    for (prec = p0; prec <= p1; prec++)
      {
        mpfr_set_prec (x, prec);
        mpfr_set_prec (y, prec);
        mpfr_set_prec (z, prec);
        mpfr_set_prec (s, prec);
        mpfr_set_prec (t, prec);

        for (n = 0; n < N; n++)
          {
            mpfr_urandomb (x, RANDS);
            mpfr_urandomb (y, RANDS);
            mpfr_urandomb (z, RANDS);

            if (randlimb () % 2)
              mpfr_neg (x, x, MPFR_RNDN);
            if (randlimb () % 2)
              mpfr_neg (y, y, MPFR_RNDN);
            if (randlimb () % 2)
              mpfr_neg (z, z, MPFR_RNDN);

            rnd = RND_RAND ();
            mpfr_set_prec (slong, 2 * prec);
            if (mpfr_mul (slong, x, y, rnd))
              {
                printf ("x*y should be exact\n");
                exit (1);
              }
            compare = mpfr_add (t, slong, z, rnd);
            inexact = mpfr_fma (s, x, y, z, rnd);
            if (! mpfr_equal_p (s, t))
              {
                printf ("results differ for x=");
                mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
                printf ("  y=");
                mpfr_out_str (stdout, 2, prec, y, MPFR_RNDN);
                printf ("  z=");
                mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
                printf (" prec=%u rnd_mode=%s\n", (unsigned int) prec,
                        mpfr_print_rnd_mode (rnd));
                printf ("got      ");
                mpfr_out_str (stdout, 2, prec, s, MPFR_RNDN);
                puts ("");
                printf ("expected ");
                mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
                puts ("");
                printf ("approx  ");
                mpfr_print_binary (slong);
                puts ("");
                exit (1);
              }
            if (! SAME_SIGN (inexact, compare))
              {
                printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n",
                        mpfr_print_rnd_mode (rnd), compare, inexact);
                printf (" x="); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
                printf (" y="); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
                printf (" z="); mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
                printf (" s="); mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN);
                printf ("\n");
                exit (1);
              }
          }
      }
    mpfr_clear (t);
    mpfr_clear (slong);

  }
  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (s);

  test_exact ();

  test_overflow1 ();
  test_overflow2 ();
  test_underflow1 ();
  test_underflow2 ();
  test_underflow3 (1);

  set_emin (MPFR_EMIN_MIN);
  set_emax (MPFR_EMAX_MAX);
  test_overflow1 ();
  test_overflow2 ();
  test_underflow1 ();
  test_underflow2 ();
  test_underflow3 (2);
  set_emin (emin);
  set_emax (emax);

  tests_end_mpfr ();
  return 0;
}
Esempio n. 26
0
static void
generic_tests (void)
{
  mpfr_t exact_sum, sum1, sum2;
  mpfr_t *t;
  mpfr_ptr *p;
  mpfr_prec_t precmax = 444;
  int i, m, nmax = 500;
  int rnd_mode;

  t = (mpfr_t *) tests_allocate (nmax * sizeof(mpfr_t));
  p = (mpfr_ptr *) tests_allocate (nmax * sizeof(mpfr_ptr));
  for (i = 0; i < nmax; i++)
    {
      mpfr_init2 (t[i], precmax);
      p[i] = t[i];
    }
  mpfr_inits2 (precmax, exact_sum, sum1, sum2, (mpfr_ptr) 0);

  for (m = 0; m < 4000; m++)
    {
      int non_uniform, n;
      mpfr_prec_t prec;

      non_uniform = randlimb () % 10;
      n = (randlimb () % nmax) + 1;
      prec = MPFR_PREC_MIN + (randlimb () % (precmax - MPFR_PREC_MIN + 1));
      mpfr_set_prec (sum1, prec);
      mpfr_set_prec (sum2, prec);

      for (i = 0; i < n; i++)
        {
          mpfr_set_prec (t[i], MPFR_PREC_MIN +
                         (randlimb () % (precmax - MPFR_PREC_MIN + 1)));
          mpfr_urandomb (t[i], RANDS);
          if (m % 8 != 0 && (m % 8 == 1 || (randlimb () & 1)))
            mpfr_neg (t[i], t[i], MPFR_RNDN);
          if (non_uniform && MPFR_NOTZERO (t[i]))
            mpfr_set_exp (t[i], randlimb () % 1000);
          /* putchar ("-0+"[SIGN (mpfr_sgn (t[i])) + 1]); */
        }
      /* putchar ('\n'); */
      get_exact_sum (exact_sum, t, n);
      RND_LOOP (rnd_mode)
        {
          int inex1, inex2;

          inex1 = mpfr_set (sum1, exact_sum, (mpfr_rnd_t) rnd_mode);
          inex2 = mpfr_sum (sum2, p, n, (mpfr_rnd_t) rnd_mode);
          if (!(mpfr_equal_p (sum1, sum2) && SAME_SIGN (inex1, inex2)))
            {
              printf ("generic_tests failed on m = %d, %s\n", m,
                      mpfr_print_rnd_mode ((mpfr_rnd_t) rnd_mode));
              printf ("Expected ");
              mpfr_dump (sum1);
              printf ("with inex = %d\n", inex1);
              printf ("Got      ");
              mpfr_dump (sum2);
              printf ("with inex = %d\n", inex2);
              exit (1);
            }
        }
    }

  for (i = 0; i < nmax; i++)
    mpfr_clear (t[i]);
  mpfr_clears (exact_sum, sum1, sum2, (mpfr_ptr) 0);
  tests_free (t, nmax * sizeof(mpfr_t));
  tests_free (p, nmax * sizeof(mpfr_ptr));
}
Esempio n. 27
0
File: thypot.c Progetto: Kirija/XPIR
static void
test_large_small (void)
{
  mpfr_t x, y, z;
  int inexact, inex2, r;

  mpfr_init2 (x, 3);
  mpfr_init2 (y, 2);
  mpfr_init2 (z, 2);

  mpfr_set_ui_2exp (x, 1, mpfr_get_emax () / 2, MPFR_RNDN);
  mpfr_set_ui_2exp (y, 1, -1, MPFR_RNDN);
  inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
  if (inexact >= 0 || mpfr_cmp (x, z))
    {
      printf ("Error 1 in test_large_small%s\n",
              ext ? ", extended exponent range" : "");
      exit (1);
    }

  mpfr_mul_ui (x, x, 5, MPFR_RNDN);
  inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
  if (mpfr_cmp (x, z) >= 0)
    {
      printf ("Error 2 in test_large_small%s\n",
              ext ? ", extended exponent range" : "");
      printf ("x = ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      printf ("y = ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\n");
      printf ("z = ");
      mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
      printf (" (in precision 2) instead of\n    ");
      mpfr_out_str (stdout, 2, 2, x, MPFR_RNDU);
      printf ("\n");
      exit (1);
    }

  RND_LOOP(r)
    {
      mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
      mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN);
      inexact = mpfr_hypot (z, x, y, (mpfr_rnd_t) r);
      inex2 = mpfr_add_ui (y, x, 1, (mpfr_rnd_t) r);
      if (! mpfr_equal_p (y, z) || ! SAME_SIGN (inexact, inex2))
        {
          printf ("Error 3 in test_large_small, %s%s\n",
                  mpfr_print_rnd_mode ((mpfr_rnd_t) r),
                  ext ? ", extended exponent range" : "");
          printf ("Expected ");
          mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
          printf (", inex = %d\n", inex2);
          printf ("Got      ");
          mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
          printf (", inex = %d\n", inexact);
          exit (1);
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Esempio n. 28
0
static void
ternary_test (void)
{
  int prec;
  int rnd;
  int inex, expected_inex;
  mpf_t x;
  mpfr_t y;

  mpf_init2 (x, 256);
  mpfr_init2 (y, 256);

  for (prec = 2; prec <= 256; prec++)
    {

      mpf_set_prec (x, prec);
      mpfr_set_prec (y, PREC (x) * GMP_NUMB_BITS + 1);

      /* y == 1 */
      mpfr_set_ui_2exp (y, 1, prec, MPFR_RNDN);

      RND_LOOP (rnd)
      {
        inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd);

        if (inex != 0 || mpfr_cmp_f (y, x) !=0)
          {
            printf ("Error in mpfr_get_f (x, y, %s)\nx = ",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            mpf_out_str (stdout, 2, 0, x);
            printf ("\ny = ");
            mpfr_dump (y);
            if (inex != 0)
              printf ("got ternary value = %+d, expected: 0\n", inex);

            exit (1);
          }
      }

      /* y == 1 + epsilon */
      mpfr_nextbelow (y);

      RND_LOOP (rnd)
      {
        switch (rnd)
          {
          case MPFR_RNDU: case MPFR_RNDA:
          case MPFR_RNDN:
            expected_inex = +1;
            break;
          default :
            expected_inex = -1;
          }

        inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd);

        if (! SAME_SIGN (expected_inex, inex)
            || SAME_SIGN (expected_inex, mpfr_cmp_f (y, x)))
          {
            printf ("Error in mpfr_get_f (x, y, %s)\nx = ",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            mpf_out_str (stdout, 2, 0, x);
            printf ("\ny = ");
            mpfr_dump (y);
            if (! SAME_SIGN (expected_inex, inex))
              printf ("got ternary value = %+d, expected: %+d\n",
                      inex, expected_inex);

            exit (1);
          }
      }

      /* y == positive random float */
      mpfr_random2 (y, MPFR_LIMB_SIZE (y), 1024, RANDS);

      RND_LOOP (rnd)
      {
        inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd);

        if (! SAME_SIGN (inex, -mpfr_cmp_f (y, x)))
          {
            printf ("Error in mpfr_get_f (x, y, %s)\nx = ",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            mpf_out_str (stdout, 2, 0, x);
            printf ("\ny = ");
            mpfr_dump (y);
            printf ("got ternary value = %+d, expected: %+d\n",
                    inex, -mpfr_cmp_f (y, x));

            exit (1);
          }
      }
    }

  mpf_clear (x);
  mpfr_clear (y);
}
Esempio n. 29
0
static void
check_one (mpz_ptr z)
{
  int    inex, ex_inex, same;
  int    sh, neg;
  mpfr_t f;
  mpz_t  got, ex;

  mpfr_init2 (f, MAX (mpz_sizeinbase (z, 2), MPFR_PREC_MIN));
  mpz_init (got);
  mpz_init (ex);

  for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++)
    {
      inex = mpfr_set_z (f, z, MPFR_RNDN);  /* exact */
      MPFR_ASSERTN (inex == 0);

      if (sh < 0)
        {
          mpz_tdiv_q_2exp (ex, z, -sh);
          inex = mpfr_div_2exp (f, f, -sh, MPFR_RNDN);
        }
      else
        {
          mpz_mul_2exp (ex, z, sh);
          inex = mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
        }
      MPFR_ASSERTN (inex == 0);

      for (neg = 0; neg <= 1; neg++)
        {
          /* Test (-1)^neg * z * 2^sh */
          int fi;
          mpfr_flags_t flags[3] = { 0, MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE,
                                    MPFR_FLAGS_ALL }, ex_flags, gt_flags;

          for (fi = 0; fi < numberof (flags); fi++)
            {
              ex_inex = - mpfr_cmp_z (f, ex);
              ex_flags = __gmpfr_flags = flags[fi];
              if (ex_inex != 0)
                ex_flags |= MPFR_FLAGS_INEXACT;
              inex = mpfr_get_z (got, f, MPFR_RNDZ);
              gt_flags = __gmpfr_flags;
              same = SAME_SIGN (inex, ex_inex);

              if (mpz_cmp (got, ex) != 0 || !same || gt_flags != ex_flags)
                {
                  printf ("Error in check_one for sh=%d, fi=%d\n", sh, fi);
                  printf ("     f = "); mpfr_dump (f);
                  printf ("expected "); mpz_dump (ex);
                  printf ("     got "); mpz_dump (got);
                  printf ("Expected inex ~ %d, got %d (%s)\n",
                          inex, ex_inex, same ? "OK" : "wrong");
                  printf ("Flags:\n");
                  printf ("      in"); flags_out (gt_flags);
                  printf ("expected"); flags_out (ex_flags);
                  printf ("     got"); flags_out (gt_flags);
                  exit (1);
                }
            }

          mpz_neg (ex, ex);
          mpfr_neg (f, f, MPFR_RNDN);
        }
    }

  mpfr_clear (f);
  mpz_clear (got);
  mpz_clear (ex);
}
Esempio n. 30
0
int
main (void)
{
  mpf_t x;
  mpfr_t y, z;
  unsigned long i;
  mpfr_exp_t e;
  int inex;

  tests_start_mpfr ();

  mpfr_init (y);
  mpfr_init (z);
  mpf_init (x);

  i = 1;
  while (i)
    {
      mpfr_set_ui (y, i, MPFR_RNDN);
      if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_ui (x, i))
        {
          printf ("Error: mpfr_get_f(%lu) fails\n", i);
          exit (1);
        }
      if (i <= - (unsigned long) LONG_MIN)
        {
          long j = i < - (unsigned long) LONG_MIN ? - (long) i : LONG_MIN;
          mpfr_set_si (y, j, MPFR_RNDN);
          if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_si (x, j))
            {
              printf ("Error: mpfr_get_f(-%lu) fails\n", i);
              exit (1);
            }
        }
      i *= 2;
    }

  /* same tests, but with a larger precision for y, which requires to
     round it */
  mpfr_set_prec (y, 100);
  i = 1;
  while (i)
    {
      mpfr_set_ui (y, i, MPFR_RNDN);
      inex = mpfr_get_f (x, y, MPFR_RNDN);
      if (! SAME_SIGN (inex, - mpfr_cmp_f (y, x)) || mpf_cmp_ui (x, i))
        {
          printf ("Error: mpfr_get_f(%lu) fails\n", i);
          exit (1);
        }
      mpfr_set_si (y, (signed long) -i, MPFR_RNDN);
      inex = mpfr_get_f (x, y, MPFR_RNDN);
      if (! SAME_SIGN (inex, - mpfr_cmp_f (y, x))
          || mpf_cmp_si (x, (signed long) -i))
        {
          printf ("Error: mpfr_get_f(-%lu) fails\n", i);
          exit (1);
        }
      i *= 2;
    }

  /* bug reported by Jim White */
  for (e = 0; e <= 2 * GMP_NUMB_BITS; e++)
    {
      /* test with 2^(-e) */
      mpfr_set_ui (y, 1, MPFR_RNDN);
      mpfr_div_2exp (y, y, e, MPFR_RNDN);
      inex = mpfr_get_f (x, y, MPFR_RNDN);
      mpf_mul_2exp (x, x, e);
      if (inex != 0 || mpf_cmp_ui (x, 1) != 0)
        {
          printf ("Error: mpfr_get_f(x,y,MPFR_RNDN) fails\n");
          printf ("y=");
          mpfr_dump (y);
          printf ("x=");
          mpf_div_2exp (x, x, e);
          mpf_out_str (stdout, 2, 0, x);
          exit (1);
        }

      /* test with 2^(e) */
      mpfr_set_ui (y, 1, MPFR_RNDN);
      mpfr_mul_2exp (y, y, e, MPFR_RNDN);
      inex = mpfr_get_f (x, y, MPFR_RNDN);
      mpf_div_2exp (x, x, e);
      if (inex != 0 || mpf_cmp_ui (x, 1) != 0)
        {
          printf ("Error: mpfr_get_f(x,y,MPFR_RNDN) fails\n");
          printf ("y=");
          mpfr_dump (y);
          printf ("x=");
          mpf_mul_2exp (x, x, e);
          mpf_out_str (stdout, 2, 0, x);
          exit (1);
        }
    }

  /* Bug reported by Yury Lukach on 2006-04-05 */
  mpfr_set_prec (y, 32);
  mpfr_set_prec (z, 32);
  mpf_set_prec (x, 32);
  mpfr_set_ui_2exp (y, 0xc1234567, -30, MPFR_RNDN);
  mpfr_get_f (x, y, MPFR_RNDN);
  inex = mpfr_set_f (z, x, MPFR_RNDN);
  if (inex != 0 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in mpfr_get_f:\n  inex = %d, y = ", inex);
      mpfr_dump (z);
      printf ("Expected:\n  inex = 0, y = ");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_clear (y);
  mpfr_clear (z);
  mpf_clear (x);

  special_test ();
  prec_test ();
  ternary_test ();

  tests_end_mpfr ();
  return 0;
}