Пример #1
0
/* check that mpfr_sin_cos and test_mpfr_sincos_fast agree */
static void
test_mpfr_sincos_fast (void)
{
  mpfr_t x, y, z, yref, zref, h;
  mpfr_prec_t p = 1000;
  int i, inex, inexref;
  mpfr_rnd_t r;

  mpfr_init2 (x, p);
  mpfr_init2 (y, p);
  mpfr_init2 (z, p);
  mpfr_init2 (yref, p);
  mpfr_init2 (zref, p);
  mpfr_init2 (h, p);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  /* we generate a random value x, compute sin(x) and cos(x) with both
     mpfr_sin_cos and mpfr_sincos_fast, and check the values and the flags
     agree */
  for (i = 0; i < 100; i++)
    {
      mpfr_urandomb (h, RANDS);
      mpfr_add (x, x, h, MPFR_RNDN);
      r = RND_RAND ();
      inexref = mpfr_sin_cos (yref, zref, x, r);
      inex = mpfr_sincos_fast (y, z, x, r);
      if (mpfr_cmp (y, yref))
        {
          printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n");
          printf ("x="); mpfr_dump (x);
          printf ("rnd=%s\n", mpfr_print_rnd_mode (r));
          printf ("yref="); mpfr_dump (yref);
          printf ("y="); mpfr_dump (y);
          exit (1);
        }
      if (mpfr_cmp (z, zref))
        {
          printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n");
          printf ("x="); mpfr_dump (x);
          printf ("rnd=%s\n", mpfr_print_rnd_mode (r));
          printf ("zref="); mpfr_dump (zref);
          printf ("z="); mpfr_dump (z);
          exit (1);
        }
      if (inex != inexref)
        {
          printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n");
          printf ("x="); mpfr_dump (x);
          printf ("rnd=%s\n", mpfr_print_rnd_mode (r));
          printf ("inexref=%d inex=%d\n", inexref, inex);
          exit (1);
        }
    }
  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (yref);
  mpfr_clear (zref);
  mpfr_clear (h);
}
Пример #2
0
int
main (int argc, char *argv[])
{
  long j;

  tests_start_mpfr ();

  check (0, MPFR_RNDN);
  for (j = 0; j < 200000; j++)
    check (randlimb () & LONG_MAX, RND_RAND ());
  check0 ();

  tests_end_mpfr ();

  return 0;
}
Пример #3
0
static void
compare_exp2_exp3 (int n)
{
  mpfr_t x, y, z; int prec; mp_rnd_t rnd;

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  for (prec = 20; prec <= n; prec++)
    {
      mpfr_set_prec (x, prec);
      mpfr_set_prec (y, prec);
      mpfr_set_prec (z, prec);
      mpfr_random (x);
      rnd = (mp_rnd_t) RND_RAND();
      mpfr_exp_2 (y, x, rnd);
      mpfr_exp_3 (z, x, rnd);
      if (mpfr_cmp (y,z))
        {
          printf ("mpfr_exp_2 and mpfr_exp_3 disagree for rnd=%s and\nx=",
                  mpfr_print_rnd_mode (rnd));
          mpfr_print_binary (x);
          puts ("");
          printf ("mpfr_exp_2 gives  ");
          mpfr_print_binary (y);
          puts ("");
          printf ("mpfr_exp_3 gives ");
          mpfr_print_binary (z);
          puts ("");
          exit (1);
        }
  }

  /* bug found by Patrick Pe'lissier on 7 Jun 2004 */
  prec = 203780;
  mpfr_set_prec (x, prec);
  mpfr_set_prec (z, prec);
  mpfr_set_d (x, 3.0, GMP_RNDN);
  mpfr_sqrt (x, x, GMP_RNDN);
  mpfr_sub_ui (x, x, 1, GMP_RNDN);
  mpfr_exp_3 (z, x, GMP_RNDN);

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Пример #4
0
static void
consistency (void)
{
  mpfr_t x, y, z1, z2;
  int i;

  mpfr_inits (x, y, z1, z2, (mpfr_ptr) 0);

  for (i = 0; i < 10000; i++)
    {
      mpfr_rnd_t rnd;
      mpfr_prec_t px, py, pz, p;
      int inex1, inex2;

      rnd = RND_RAND ();
      px = (randlimb () % 256) + 2;
      py = (randlimb () % 128) + 2;
      pz = (randlimb () % 256) + 2;
      mpfr_set_prec (x, px);
      mpfr_set_prec (y, py);
      mpfr_set_prec (z1, pz);
      mpfr_set_prec (z2, pz);
      mpfr_urandomb (x, RANDS);
      do
        mpfr_urandomb (y, RANDS);
      while (mpfr_zero_p (y));
      inex1 = mpfr_div (z1, x, y, rnd);
      MPFR_ASSERTN (!MPFR_IS_NAN (z1));
      p = MAX (MAX (px, py), pz);
      if (mpfr_prec_round (x, p, MPFR_RNDN) != 0 ||
          mpfr_prec_round (y, p, MPFR_RNDN) != 0)
        {
          printf ("mpfr_prec_round error for i = %d\n", i);
          exit (1);
        }
      inex2 = mpfr_div (z2, x, y, rnd);
      MPFR_ASSERTN (!MPFR_IS_NAN (z2));
      if (inex1 != inex2 || mpfr_cmp (z1, z2) != 0)
        {
          printf ("Consistency error for i = %d\n", i);
          exit (1);
        }
    }

  mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
}
Пример #5
0
static void
compare_exp2_exp3 (mpfr_prec_t p0, mpfr_prec_t p1)
{
  mpfr_t x, y, z;
  mpfr_prec_t prec;
  mpfr_rnd_t rnd;

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  for (prec = p0; prec <= p1; prec ++)
    {
      mpfr_set_prec (x, prec);
      mpfr_set_prec (y, prec);
      mpfr_set_prec (z, prec);
      do
        mpfr_urandomb (x, RANDS);
      while (MPFR_IS_ZERO (x));  /* 0 is handled by mpfr_exp only */
      rnd = RND_RAND ();
      mpfr_exp_2 (y, x, rnd);
      mpfr_exp_3 (z, x, rnd);
      if (mpfr_cmp (y,z))
        {
          printf ("mpfr_exp_2 and mpfr_exp_3 disagree for rnd=%s and\nx=",
                  mpfr_print_rnd_mode (rnd));
          mpfr_print_binary (x);
          puts ("");
          printf ("mpfr_exp_2 gives ");
          mpfr_print_binary (y);
          puts ("");
          printf ("mpfr_exp_3 gives ");
          mpfr_print_binary (z);
          puts ("");
          exit (1);
        }
  }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Пример #6
0
static void
check (mp_prec_t p0, mp_prec_t p1)
{
  mpfr_t x, y, z;
  mp_rnd_t rnd;

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init2 (z, p1 + 10);
  mpfr_const_log2 (z, GMP_RNDN);
  mpfr_clear_cache (__gmpfr_cache_const_log2);

  for (; p0<=p1; p0++)
    {
      mpfr_set_prec (x, p0);
      mpfr_set_prec (y, p0);
        {
          rnd = (mp_rnd_t) RND_RAND ();
          mpfr_const_log2 (x, rnd);
          mpfr_set (y, z, rnd);
          if (mpfr_cmp (x, y) && mpfr_can_round (z, mpfr_get_prec(z), GMP_RNDN,
                                                 rnd, p0))
            {
              printf ("mpfr_const_log2 fails for prec=%u, rnd=%s\n",
                      (unsigned int) p0, mpfr_print_rnd_mode (rnd));
              printf ("expected ");
              mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
              printf ("\ngot      ");
              mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
              printf ("\n");
              exit (1);
            }
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Пример #7
0
static void
check (mpfr_prec_t p0, mpfr_prec_t p1)
{
  mpfr_t x, y, z;
  mpfr_rnd_t rnd;
  int dif;

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init2 (z, p1 + 10);
  mpfr_const_log2 (z, MPFR_RNDN);
  mpfr_clear_cache (__gmpfr_cache_const_log2);

  for (; p0<=p1; p0++)
    {
      mpfr_set_prec (x, p0);
      mpfr_set_prec (y, p0);
        {
          rnd = RND_RAND ();
          mpfr_const_log2 (x, rnd);
          mpfr_set (y, z, rnd);
          if ((dif = mpfr_cmp (x, y))
              && mpfr_can_round (z, mpfr_get_prec(z), MPFR_RNDN,
                                                 rnd, p0))
            {
              printf ("mpfr_const_log2 fails for prec=%u, rnd=%s Diff=%d\n",
                      (unsigned int) p0, mpfr_print_rnd_mode (rnd), dif);
              printf ("expected "), mpfr_dump (y);
              printf ("got      "), mpfr_dump (x);
              exit (1);
            }
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
static void
check_inexact (mpfr_prec_t p)
{
  mpfr_t x, y, z;
  mpfr_rnd_t rnd;
  int inexact, sign;

  mpfr_init2 (x, p);
  mpfr_init2 (y, p);
  mpfr_init2 (z, 2*p);
  mpfr_urandomb (x, RANDS);
  rnd = RND_RAND ();
  inexact = test_sqrt (y, x, rnd);
  if (mpfr_mul (z, y, y, rnd)) /* exact since prec(z) = 2*prec(y) */
    {
      printf ("Error: multiplication should be exact\n");
      exit (1);
    }
  mpfr_sub (z, z, x, rnd); /* exact also */
  sign = mpfr_cmp_ui (z, 0);
  if (((inexact == 0) && (sign)) ||
      ((inexact > 0) && (sign <= 0)) ||
      ((inexact < 0) && (sign >= 0)))
    {
      printf ("Error: wrong inexact flag, expected %d, got %d\n",
              sign, inexact);
      printf ("x=");
      mpfr_print_binary (x);
      printf (" rnd=%s\n", mpfr_print_rnd_mode (rnd));
      printf ("y="); mpfr_print_binary (y); puts ("");
      exit (1);
    }
  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Пример #9
0
static void
check_inexact (void)
{
  mpfr_t x, y, z, u;
  mpfr_prec_t px, py, pu;
  int inexact, cmp;
  mpfr_rnd_t rnd;

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  mpfr_init (u);

  mpfr_set_prec (x, 28);
  mpfr_set_prec (y, 28);
  mpfr_set_prec (z, 1023);
  mpfr_set_str_binary (x, "0.1000001001101101111100010011E0");
  mpfr_set_str (z, "48284762641021308813686974720835219181653367326353400027913400579340343320519877153813133510034402932651132854764198688352364361009429039801248971901380781746767119334993621199563870113045276395603170432175354501451429471578325545278975153148347684600400321033502982713296919861760382863826626093689036010394", 10, MPFR_RNDN);
  mpfr_div (x, x, z, MPFR_RNDN);
  mpfr_set_str_binary (y, "0.1111001011001101001001111100E-1023");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_div for prec=28, RNDN\n");
      printf ("Expected "); mpfr_dump (y);
      printf ("Got      "); mpfr_dump (x);
      exit (1);
    }

  mpfr_set_prec (x, 53);
  mpfr_set_str_binary (x, "0.11101100110010100011011000000100001111011111110010101E0");
  mpfr_set_prec (u, 127);
  mpfr_set_str_binary (u, "0.1000001100110110110101110110101101111000110000001111111110000000011111001010110100110010111111111101000001011011101011101101000E-2");
  mpfr_set_prec (y, 95);
  inexact = test_div (y, x, u, MPFR_RNDN);
  if (inexact != (cmp = get_inexact (y, x, u)))
    {
      printf ("Wrong inexact flag (0): expected %d, got %d\n", cmp, inexact);
      printf ("x="); mpfr_out_str (stdout, 10, 99, x, MPFR_RNDN); printf ("\n");
      printf ("u="); mpfr_out_str (stdout, 10, 99, u, MPFR_RNDN); printf ("\n");
      printf ("y="); mpfr_out_str (stdout, 10, 99, y, MPFR_RNDN); printf ("\n");
      exit (1);
    }

  mpfr_set_prec (x, 33);
  mpfr_set_str_binary (x, "0.101111100011011101010011101100001E0");
  mpfr_set_prec (u, 2);
  mpfr_set_str_binary (u, "0.1E0");
  mpfr_set_prec (y, 28);
  if ((inexact = test_div (y, x, u, MPFR_RNDN) >= 0))
    {
      printf ("Wrong inexact flag (1): expected -1, got %d\n",
              inexact);
      exit (1);
    }

  mpfr_set_prec (x, 129);
  mpfr_set_str_binary (x, "0.111110101111001100000101011100101100110011011101010001000110110101100101000010000001110110100001101010001010100010001111001101010E-2");
  mpfr_set_prec (u, 15);
  mpfr_set_str_binary (u, "0.101101000001100E-1");
  mpfr_set_prec (y, 92);
  if ((inexact = test_div (y, x, u, MPFR_RNDN)) <= 0)
    {
      printf ("Wrong inexact flag for rnd=MPFR_RNDN(1): expected 1, got %d\n",
              inexact);
      mpfr_dump (x);
      mpfr_dump (u);
      mpfr_dump (y);
      exit (1);
    }

  for (px=2; px<MAX_PREC; px++)
    {
      mpfr_set_prec (x, px);
      mpfr_urandomb (x, RANDS);
      for (pu=2; pu<=MAX_PREC; pu++)
        {
          mpfr_set_prec (u, pu);
          do { mpfr_urandomb (u, RANDS); } while (mpfr_cmp_ui (u, 0) == 0);
            {
              py = MPFR_PREC_MIN + (randlimb () % (MAX_PREC - MPFR_PREC_MIN));
              mpfr_set_prec (y, py);
              mpfr_set_prec (z, py + pu);
                {
                  rnd = RND_RAND ();
                  inexact = test_div (y, x, u, rnd);
                  if (mpfr_mul (z, y, u, rnd))
                    {
                      printf ("z <- y * u should be exact\n");
                      exit (1);
                    }
                  cmp = mpfr_cmp (z, x);
                  if (((inexact == 0) && (cmp != 0)) ||
                      ((inexact > 0) && (cmp <= 0)) ||
                      ((inexact < 0) && (cmp >= 0)))
                    {
                      printf ("Wrong inexact flag for rnd=%s\n",
                              mpfr_print_rnd_mode(rnd));
                      printf ("expected %d, got %d\n", cmp, inexact);
                      printf ("x="); mpfr_print_binary (x); puts ("");
                      printf ("u="); mpfr_print_binary (u); puts ("");
                      printf ("y="); mpfr_print_binary (y); puts ("");
                      printf ("y*u="); mpfr_print_binary (z); puts ("");
                      exit (1);
                    }
                }
            }
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (u);
}
static void
check_inexact (void)
{
  mpfr_t x, y, z, u;
  mpfr_prec_t px, py, pu, pz;
  int inexact, cmp;
  mpfr_rnd_t rnd;

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  mpfr_init (u);

  mpfr_set_prec (x, 2);
  mpfr_set_ui (x, 6, MPFR_RNDN);
  mpfr_div_2exp (x, x, 4, MPFR_RNDN); /* x = 6/16 */
  mpfr_set_prec (y, 2);
  mpfr_set_si (y, -1, MPFR_RNDN);
  mpfr_div_2exp (y, y, 4, MPFR_RNDN); /* y = -1/16 */
  inexact = test_sub (y, y, x, MPFR_RNDN); /* y = round(-7/16) = -1/2 */
  if (inexact >= 0)
    {
      printf ("Error: wrong inexact flag for -1/16 - (6/16)\n");
      exit (1);
    }

  for (px=2; px<MAX_PREC; px++)
    {
      mpfr_set_prec (x, px);
      do
        {
          mpfr_urandomb (x, RANDS);
        }
      while (mpfr_cmp_ui (x, 0) == 0);
      for (pu=2; pu<MAX_PREC; pu++)
        {
          mpfr_set_prec (u, pu);
          do
            {
              mpfr_urandomb (u, RANDS);
            }
          while (mpfr_cmp_ui (u, 0) == 0);
          {
              py = 2 + (randlimb () % (MAX_PREC - 2));
              mpfr_set_prec (y, py);
              /* warning: MPFR_EXP is undefined for 0 */
              pz =  (mpfr_cmpabs (x, u) >= 0) ? MPFR_EXP(x) - MPFR_EXP(u)
                : MPFR_EXP(u) - MPFR_EXP(x);
              pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u));
              mpfr_set_prec (z, pz);
              rnd = RND_RAND ();
              if (test_sub (z, x, u, rnd))
                {
                  printf ("z <- x - u should be exact\n");
                  exit (1);
                }
                {
                  rnd = RND_RAND ();
                  inexact = test_sub (y, x, u, rnd);
                  cmp = mpfr_cmp (y, z);
                  if (((inexact == 0) && (cmp != 0)) ||
                      ((inexact > 0) && (cmp <= 0)) ||
                      ((inexact < 0) && (cmp >= 0)))
                    {
                      printf ("Wrong inexact flag for rnd=%s\n",
                              mpfr_print_rnd_mode(rnd));
                      printf ("expected %d, got %d\n", cmp, inexact);
                      printf ("x="); mpfr_print_binary (x); puts ("");
                      printf ("u="); mpfr_print_binary (u); puts ("");
                      printf ("y=  "); mpfr_print_binary (y); puts ("");
                      printf ("x-u="); mpfr_print_binary (z); puts ("");
                      exit (1);
                    }
                }
            }
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (u);
}
Пример #11
0
/* checks that the inexact return value is correct */
static void
check_exact (void)
{
  mpfr_t a, b, c, d;
  mpfr_prec_t prec;
  int i, inexact;
  mpfr_rnd_t rnd;

  mpfr_init (a);
  mpfr_init (b);
  mpfr_init (c);
  mpfr_init (d);

  mpfr_set_prec (a, 17);
  mpfr_set_prec (b, 17);
  mpfr_set_prec (c, 32);
  mpfr_set_str_binary (a, "1.1000111011000100e-1");
  mpfr_set_str_binary (b, "1.0010001111100111e-1");
  if (test_mul (c, a, b, MPFR_RNDZ))
    {
      printf ("wrong return value (1)\n");
      exit (1);
    }

  for (prec = 2; prec < 100; prec++)
    {
      mpfr_set_prec (a, prec);
      mpfr_set_prec (b, prec);
      mpfr_set_prec (c, 2 * prec - 2);
      mpfr_set_prec (d, 2 * prec);
      for (i = 0; i < 1000; i++)
        {
          mpfr_urandomb (a, RANDS);
          mpfr_urandomb (b, RANDS);
          rnd = RND_RAND ();
          inexact = test_mul (c, a, b, rnd);
          if (test_mul (d, a, b, rnd)) /* should be always exact */
            {
              printf ("unexpected inexact return value\n");
              exit (1);
            }
          if ((inexact == 0) && mpfr_cmp (c, d))
            {
              printf ("inexact=0 but results differ\n");
              exit (1);
            }
          else if (inexact && (mpfr_cmp (c, d) == 0))
            {
              printf ("inexact!=0 but results agree\n");
              printf ("prec=%u rnd=%s a=", (unsigned int) prec,
                      mpfr_print_rnd_mode (rnd));
              mpfr_out_str (stdout, 2, 0, a, rnd);
              printf ("\nb=");
              mpfr_out_str (stdout, 2, 0, b, rnd);
              printf ("\nc=");
              mpfr_out_str (stdout, 2, 0, c, rnd);
              printf ("\nd=");
              mpfr_out_str (stdout, 2, 0, d, rnd);
              printf ("\n");
              exit (1);
            }
        }
    }

  mpfr_clear (a);
  mpfr_clear (b);
  mpfr_clear (c);
  mpfr_clear (d);
}
Пример #12
0
static void
test_generic (mp_prec_t p0, mp_prec_t p1, unsigned int N)
{
  mp_prec_t prec, xprec, yprec;
  mpfr_t x, y, z, t;
#ifdef TWO_ARGS
  mpfr_t u;
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  mpfr_t u;
  double d;
#endif
  mp_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n;
  unsigned long ctrt = 0, ctrn = 0;
  mp_exp_t old_emin, old_emax;

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

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  mpfr_init (t);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  mpfr_init (u);
#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);

      /* Note: in precision p1, we test 4 special cases. */
      for (n = 0; n < (prec == p1 ? N + 4 : N); n++)
        {
          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);
#ifdef TWO_ARGS
          mpfr_set_prec (u, xprec);
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
          mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
#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
              tests_default_random (x, TEST_RANDOM_POS,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
              tests_default_random (u, TEST_RANDOM_POS2,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX);
#endif
#endif
            }
          else
            {
              /* Special cases tested in precision p1 if n <= 3. They are
                 useful really in the extended exponent range. */
              set_emin (MPFR_EMIN_MIN);
              set_emax (MPFR_EMAX_MAX);
              if (n <= 1)
                {
                  mpfr_set_si (x, n == 0 ? 1 : -1, GMP_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, GMP_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, GMP_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, GMP_RNDN);
                  mpfr_setmax (u, mpfr_get_emax ());
#endif
                }
            }

          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);
#elif defined(DOUBLE_ARG2)
          d = mpfr_get_d (u, rnd);
          compare = TEST_FUNCTION (y, x, d, rnd);
#else
          compare = TEST_FUNCTION (y, x, rnd);
#endif
          TGENERIC_CHECK ("Bad inexact flag",
                          (compare != 0) ^ (mpfr_inexflag_p () == 0));
          ctrt++;
          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));
              else if (MPFR_IS_ZERO (y))
                TGENERIC_CHECK ("Bad underflow flag",
                                (compare != 0) ^ (mpfr_underflow_p () == 0));
            }
          else if (mpfr_overflow_p ())
            {
              TGENERIC_CHECK ("Bad compare value (overflow)", compare != 0);
              mpfr_nexttoinf (y);
              TGENERIC_CHECK ("Should have been max MPFR number",
                              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",
                              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 this
                 triggers the mpfr_fmod bug fixed in r6235. */
              mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
                               GMP_RNDN);
#if defined(TWO_ARGS)
              mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
                               GMP_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);
#else
              inexact = TEST_FUNCTION (z, x, rnd);
#endif
              if (mpfr_erangeflag_p ())
                goto next_n;
              if (mpfr_nan_p (z) || mpfr_cmp (t, z) != 0)
                {
                  printf ("results differ for x=");
                  mpfr_out_str (stdout, 2, xprec, x, GMP_RNDN);
#ifdef TWO_ARGS
                  printf ("\nu=");
                  mpfr_out_str (stdout, 2, xprec, u, GMP_RNDN);
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  printf ("\nu=");
                  mpfr_out_str (stdout, 2, IEEE_DBL_MANT_DIG, u, GMP_RNDN);
#endif
                  printf (" prec=%u rnd_mode=%s\n", (unsigned) prec,
                          mpfr_print_rnd_mode (rnd));
                  printf ("got      ");
                  mpfr_out_str (stdout, 2, prec, z, GMP_RNDN);
                  puts ("");
                  printf ("expected ");
                  mpfr_out_str (stdout, 2, prec, t, GMP_RNDN);
                  puts ("");
                  printf ("approx   ");
                  mpfr_print_binary (y);
                  puts ("");
                  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 (((inexact == 0) && (compare != 0)) ||
                  ((inexact > 0) && (compare <= 0)) ||
                  ((inexact < 0) && (compare >= 0)))
                {
                  printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
                          "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
                  printf ("x="); mpfr_print_binary (x); puts ("");
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  printf ("u="); mpfr_print_binary (u); puts ("");
#endif
                  printf ("y="); mpfr_print_binary (y); puts ("");
                  printf ("t="); mpfr_print_binary (t); puts ("");
                  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 ())
                {
                  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_print_binary (x); puts ("");
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  printf ("u="); mpfr_print_binary (u); puts ("");
#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_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (t);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  mpfr_clear (u);
#endif
}
Пример #13
0
Файл: tadd.c Проект: qsnake/mpfr
static void
check_1111 (void)
{
    mpfr_t one;
    long n;

    mpfr_init2 (one, MPFR_PREC_MIN);
    mpfr_set_ui (one, 1, MPFR_RNDN);
    for (n = 0; n < NUM; n++)
    {
        mpfr_prec_t prec_a, prec_b, prec_c;
        mpfr_exp_t tb=0, tc, diff;
        mpfr_t a, b, c, s;
        int m = 512;
        int sb, sc;
        int inex_a, inex_s;
        mpfr_rnd_t rnd_mode;

        prec_a = MPFR_PREC_MIN + (randlimb () % m);
        prec_b = MPFR_PREC_MIN + (randlimb () % m);
        prec_c = MPFR_PREC_MIN + (randlimb () % m);
        mpfr_init2 (a, prec_a);
        mpfr_init2 (b, prec_b);
        mpfr_init2 (c, prec_c);
        sb = randlimb () % 3;
        if (sb != 0)
        {
            tb = 1 + (randlimb () % (prec_b - (sb != 2)));
            mpfr_div_2ui (b, one, tb, MPFR_RNDN);
            if (sb == 2)
                mpfr_neg (b, b, MPFR_RNDN);
            test_add (b, b, one, MPFR_RNDN);
        }
        else
            mpfr_set (b, one, MPFR_RNDN);
        tc = 1 + (randlimb () % (prec_c - 1));
        mpfr_div_2ui (c, one, tc, MPFR_RNDN);
        sc = randlimb () % 2;
        if (sc)
            mpfr_neg (c, c, MPFR_RNDN);
        test_add (c, c, one, MPFR_RNDN);
        diff = (randlimb () % (2*m)) - m;
        mpfr_mul_2si (c, c, diff, MPFR_RNDN);
        rnd_mode = RND_RAND ();
        inex_a = test_add (a, b, c, rnd_mode);
        mpfr_init2 (s, MPFR_PREC_MIN + 2*m);
        inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */
        if (inex_s)
        {
            printf ("check_1111: result should have been exact.\n");
            exit (1);
        }
        inex_s = mpfr_prec_round (s, prec_a, rnd_mode);
        if ((inex_a < 0 && inex_s >= 0) ||
                (inex_a == 0 && inex_s != 0) ||
                (inex_a > 0 && inex_s <= 0) ||
                !mpfr_equal_p (a, s))
        {
            printf ("check_1111: results are different.\n");
            printf ("prec_a = %d, prec_b = %d, prec_c = %d\n",
                    (int) prec_a, (int) prec_b, (int) prec_c);
            printf ("tb = %d, tc = %d, diff = %d, rnd = %s\n",
                    (int) tb, (int) tc, (int) diff,
                    mpfr_print_rnd_mode (rnd_mode));
            printf ("sb = %d, sc = %d\n", sb, sc);
            printf ("a = ");
            mpfr_print_binary (a);
            puts ("");
            printf ("s = ");
            mpfr_print_binary (s);
            puts ("");
            printf ("inex_a = %d, inex_s = %d\n", inex_a, inex_s);
            exit (1);
        }
        mpfr_clear (a);
        mpfr_clear (b);
        mpfr_clear (c);
        mpfr_clear (s);
    }
    mpfr_clear (one);
}
Пример #14
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
}
Пример #15
0
static void
test_generic_ui (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N)
{
  mpfr_prec_t prec, yprec;
  mpfr_t x, y, z, t;
  INTEGER_TYPE u;
  mpfr_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n;

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  mpfr_init (t);

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

      for (n = 0; n <= N; n++)
        {
          if (n > 1 || prec < p1)
            RAND_FUNCTION (x);
          else
            {
              /* Special cases tested in precision p1 if n <= 1. */
              mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
              mpfr_set_exp (x, mpfr_get_emin ());
            }
          u = INT_RAND_FUNCTION ();
          rnd = RND_RAND ();
          mpfr_set_prec (y, yprec);
          compare = TEST_FUNCTION (y, x, u, rnd);
          if (mpfr_can_round (y, yprec, rnd, rnd, prec))
            {
              mpfr_set (t, y, rnd);
              inexact = TEST_FUNCTION (z, x, u, rnd);
              if (mpfr_cmp (t, z))
                {
                  printf ("results differ for x=");
                  mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
                  printf ("\nu=%lu", (unsigned long) u);
                  printf (" prec=%lu rnd_mode=%s\n",
                          (unsigned long ) prec, mpfr_print_rnd_mode (rnd));
#ifdef TEST_FUNCTION_NAME
                  printf ("Function: %s\n", TEST_FUNCTION_NAME);
#endif
                  printf ("got      ");
                  mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
                  puts ("");
                  printf ("expected ");
                  mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
                  puts ("");
                  printf ("approx  ");
                  mpfr_print_binary (y);
                  puts ("");
                  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 (((inexact == 0) && (compare != 0)) ||
                  ((inexact > 0) && (compare <= 0)) ||
                  ((inexact < 0) && (compare >= 0)))
                {
                  printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
                          "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
                  printf ("x="); mpfr_print_binary (x); puts ("");
                  printf ("u=%lu", (unsigned long) u);
                  printf ("y="); mpfr_print_binary (y); puts ("");
                  printf ("t="); mpfr_print_binary (t); puts ("");
                  exit (1);
                }
            }
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (t);
}
Пример #16
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y;
  unsigned long int n;

  tests_start_mpfr ();

  mpfr_init (x);
  mpfr_init (y);

  n = randlimb ();

  MPFR_SET_INF(x);
  mpfr_ui_pow (y, n, 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_ui_pow (y, n, x, MPFR_RNDN);
  if(!MPFR_IS_ZERO(y))
    {
      printf ("evaluation of function in -INF does not return 0");
      exit (1);
    }

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

  test1 ();

  {
  mpfr_t z, t;
  mpfr_prec_t prec;
  mpfr_rnd_t rnd;
  unsigned int n;

  mpfr_prec_t p0=2, p1=100;
  unsigned int N=20;

  mpfr_init2 (z, 38);
  mpfr_init2 (t, 6);

  /* check exact power */
  mpfr_set_str_binary (t, "0.110000E5");
  mpfr_ui_pow (z, 3, t, MPFR_RNDN);

  mpfr_set_prec (x, 2);
  mpfr_set_prec (y, 2);
  mpfr_set_str (x, "-0.5", 10, MPFR_RNDZ);
  mpfr_ui_pow (y, 4, x, MPFR_RNDD);
  if (mpfr_cmp_ui_2exp(y, 1, -1))
    {
      fprintf (stderr, "Error for 4^(-0.5), prec=2, MPFR_RNDD\n");
      fprintf (stderr, "expected 0.5, got ");
      mpfr_out_str (stderr, 2, 0, y, MPFR_RNDN);
      fprintf (stderr, "\n");
      exit (1);
    }

  /* problem found by Kevin on spe175.testdrive.compaq.com
     (03 Sep 2003), ia64 under HP-UX */
  mpfr_set_prec (x, 2);
  mpfr_set_prec (y, 2);
  mpfr_set_str (x, "0.5", 10, MPFR_RNDN);
  mpfr_ui_pow (y, 398441521, x, MPFR_RNDN);
  if (mpfr_cmp_ui_2exp(y, 1, 14))
    {
      fprintf (stderr, "Error for 398441521^(0.5), prec=2, MPFR_RNDN\n");
      fprintf (stderr, "expected 1.0e14, got ");
      mpfr_out_str (stderr, 2, 0, y, MPFR_RNDN);
      fprintf (stderr, "\n");
      exit (1);
    }

  mpfr_clear (z);
  mpfr_clear (t);

  mpfr_set_prec (x, 2);
  mpfr_set_str (x, "0.5", 10, MPFR_RNDN);
  check1 (x, 2, 398441521, MPFR_RNDN);  /* 398441521 = 19961^2 */

  /* generic test */
  for (prec = p0; prec <= p1; prec++)
    {
      mpfr_set_prec (x, prec);
      for (n=0; n<N; n++)
        {
          int nt;
          nt = randlimb () & INT_MAX;
          mpfr_urandomb (x, RANDS);
          rnd = RND_RAND ();
          check1 (x, prec, nt, rnd);
        }
    }
  }

  mpfr_clear (x);
  mpfr_clear (y);

  tests_end_mpfr ();
  return 0;
}
Пример #17
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y, z, s;

  tests_start_mpfr ();

  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, GMP_RNDN);
  mpfr_set_str (y, "0.5", 10, GMP_RNDN);
  mpfr_set_str (z, "0.375", 10, GMP_RNDN);
  mpfr_fma (s, x, y, z, GMP_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");
      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, GMP_RNDN);
  mpfr_set_str_binary (z, "-1.00011110100011001011001001e-1");
  if (mpfr_fma (s, x, y, z, GMP_RNDN) >= 0)
    {
      printf ("Wrong inexact flag for x=y=1-2^(-27)\n");
      exit (1);
    }

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

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

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

  mpfr_set_inf (x, 1);
  mpfr_set_inf (y, 1);
  mpfr_set_inf (z, 1);
  mpfr_fma (s, x, y, z, GMP_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, GMP_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, GMP_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, GMP_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, GMP_RNDN);
  mpfr_random (z);
  mpfr_fma (s, x, y, z, GMP_RNDN);
  if (!mpfr_nan_p (s))
    {
      printf ("evaluation of function in x=INF y=0  does not return NAN");
      exit (1);
    }

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

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

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

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

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

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

  mpfr_set_ui (x, 0, GMP_RNDN);
  mpfr_random (y);
  mpfr_random (z);
  mpfr_fma (s, x, y, z, GMP_RNDN);
  if (mpfr_cmp (s, z))
    {
      printf ("evaluation of function in x=0 does not return z\n");
      exit (1);
    }

  mpfr_set_ui (y, 0, GMP_RNDN);
  mpfr_random (x);
  mpfr_random (z);
  mpfr_fma (s, x, y, z, GMP_RNDN);
  if (mpfr_cmp (s, z))
    {
      printf ("evaluation of function in y=0 does not return z\n");
      exit (1);
    }

  {
    mp_prec_t prec;
    mpfr_t t, slong;
    mp_rnd_t rnd;
    int inexact, compare;
    unsigned int n;

    mp_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_random (x);
          mpfr_random (y);
          mpfr_random (z);

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

          rnd = (mp_rnd_t) 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_cmp (s, t))
            {
              printf ("results differ for x=");
              mpfr_out_str (stdout, 2, prec, x, GMP_RNDN);
              printf ("  y=");
              mpfr_out_str (stdout, 2, prec, y, GMP_RNDN);
              printf ("  z=");
              mpfr_out_str (stdout, 2, prec, z, GMP_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, GMP_RNDN);
              puts ("");
              printf ("expected ");
              mpfr_out_str (stdout, 2, prec, t, GMP_RNDN);
              puts ("");
              printf ("approx  ");
              mpfr_print_binary (slong);
              puts ("");
              exit (1);
            }
          if (((inexact == 0) && (compare != 0)) ||
              ((inexact < 0) && (compare >= 0)) ||
              ((inexact > 0) && (compare <= 0)))
            {
              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, GMP_RNDN);
              printf (" y="); mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
              printf (" z="); mpfr_out_str (stdout, 2, 0, z, GMP_RNDN);
              printf (" s="); mpfr_out_str (stdout, 2, 0, s, GMP_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 ();

  tests_end_mpfr ();
  return 0;
}
Пример #18
0
static void
test_genericq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
               int (*func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t),
               const char *op)
{
  mpfr_prec_t prec;
  mpfr_t arg1, dst_big, dst_small, tmp;
  mpq_t  arg2;
  mpfr_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n;

  mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
  mpq_init (arg2);

  for (prec = p0; prec <= p1; prec++)
    {
      mpfr_set_prec (arg1, prec);
      mpfr_set_prec (tmp, prec);
      mpfr_set_prec (dst_small, prec);

      for (n=0; n<N; n++)
        {
          mpfr_urandomb (arg1, RANDS);
          mpq_set_ui (arg2, randlimb (), randlimb() );
          mpq_canonicalize (arg2);
          rnd = RND_RAND ();
          mpfr_set_prec (dst_big, prec+10);
          compare = func(dst_big, arg1, arg2, rnd);
          if (mpfr_can_round (dst_big, prec+10, rnd, rnd, prec))
            {
              mpfr_set (tmp, dst_big, rnd);
              inexact = func(dst_small, arg1, arg2, rnd);
              if (mpfr_cmp (tmp, dst_small))
                {
                  printf ("Results differ for prec=%u rnd_mode=%s and %s_q:\n"
                          "arg1=",
                          (unsigned) prec, mpfr_print_rnd_mode (rnd), op);
                  mpfr_print_binary (arg1);
                  printf("\narg2=");
                  mpq_out_str(stdout, 2, arg2);
                  printf ("\ngot      ");
                  mpfr_print_binary (dst_small);
                  printf ("\nexpected ");
                  mpfr_print_binary (tmp);
                  printf ("\napprox  ");
                  mpfr_print_binary (dst_big);
                  putchar('\n');
                  exit (1);
                }
              compare2 = mpfr_cmp (tmp, dst_big);
              /* 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 (((inexact == 0) && (compare != 0)) ||
                  ((inexact > 0) && (compare <= 0)) ||
                  ((inexact < 0) && (compare >= 0)))
                {
                  printf ("Wrong inexact flag for rnd=%s and %s_q:\n"
                          "expected %d, got %d",
                          mpfr_print_rnd_mode (rnd), op, compare, inexact);
                  printf ("\narg1="); mpfr_print_binary (arg1);
                  printf ("\narg2="); mpq_out_str(stdout, 2, arg2);
                  printf ("\ndstl="); mpfr_print_binary (dst_big);
                  printf ("\ndsts="); mpfr_print_binary (dst_small);
                  printf ("\ntmp ="); mpfr_print_binary (tmp);
                  putchar('\n');
                  exit (1);
                }
            }
        }
    }

  mpq_clear (arg2);
  mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
}
Пример #19
0
static void
consistency (void)
{
  mpfr_t x, s1, s2, c1, c2;
  mpfr_exp_t emin, emax;
  mpfr_rnd_t rnd;
  unsigned int flags_sin, flags_cos, flags, flags_before, flags_ref;
  int inex_sin, is, inex_cos, ic, inex, inex_ref;
  int i;

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

  for (i = 0; i <= 10000; i++)
    {
      mpfr_init2 (x, MPFR_PREC_MIN + (randlimb () % 8));
      mpfr_inits2 (MPFR_PREC_MIN + (randlimb () % 8), s1, s2, c1, c2,
                   (mpfr_ptr) 0);
      if (i < 8 * MPFR_RND_MAX)
        {
          int j = i / MPFR_RND_MAX;
          if (j & 1)
            mpfr_set_emin (MPFR_EMIN_MIN);
          mpfr_set_si (x, (j & 2) ? 1 : -1, MPFR_RNDN);
          mpfr_set_exp (x, mpfr_get_emin ());
          rnd = (mpfr_rnd_t) (i % MPFR_RND_MAX);
          flags_before = 0;
          if (j & 4)
            mpfr_set_emax (-17);
        }
      else
        {
          tests_default_random (x, 256, -5, 50, 0);
          rnd = RND_RAND ();
          flags_before = (randlimb () & 1) ?
            (unsigned int) (MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE) :
            (unsigned int) 0;
        }
      __gmpfr_flags = flags_before;
      inex_sin = mpfr_sin (s1, x, rnd);
      is = inex_sin < 0 ? 2 : inex_sin > 0 ? 1 : 0;
      flags_sin = __gmpfr_flags;
      __gmpfr_flags = flags_before;
      inex_cos = mpfr_cos (c1, x, rnd);
      ic = inex_cos < 0 ? 2 : inex_cos > 0 ? 1 : 0;
      flags_cos = __gmpfr_flags;
      __gmpfr_flags = flags_before;
      inex = mpfr_sin_cos (s2, c2, x, rnd);
      flags = __gmpfr_flags;
      inex_ref = is + 4 * ic;
      flags_ref = flags_sin | flags_cos;
      if (!(mpfr_equal_p (s1, s2) && mpfr_equal_p (c1, c2)) ||
          inex != inex_ref || flags != flags_ref)
        {
          printf ("mpfr_sin_cos and mpfr_sin/mpfr_cos disagree on %s,"
                  " i = %d\nx = ", mpfr_print_rnd_mode (rnd), i);
          mpfr_dump (x);
          printf ("s1 = ");
          mpfr_dump (s1);
          printf ("s2 = ");
          mpfr_dump (s2);
          printf ("c1 = ");
          mpfr_dump (c1);
          printf ("c2 = ");
          mpfr_dump (c2);
          printf ("inex_sin = %d (s = %d), inex_cos = %d (c = %d), "
                  "inex = %d (expected %d)\n",
                  inex_sin, is, inex_cos, ic, inex, inex_ref);
          printf ("flags_sin = 0x%x, flags_cos = 0x%x, "
                  "flags = 0x%x (expected 0x%x)\n",
                  flags_sin, flags_cos, flags, flags_ref);
          exit (1);
        }
      mpfr_clears (x, s1, s2, c1, c2, (mpfr_ptr) 0);
      mpfr_set_emin (emin);
      mpfr_set_emax (emax);
    }
}
Пример #20
0
int
main (int argc, char *argv[])
{
  int b;
  mpfr_t x;
  mpfr_rnd_t r;
  char s[MAX_DIGITS + 2];
  mpfr_exp_t e, f;
  size_t m;
  mpfr_prec_t p;
  int i;

  tests_start_mpfr ();

  check_small ();

  check_special (2, 2);
  for (i = 0; i < ITER; i++)
    {
      p = 2 + (randlimb () % (MAX_DIGITS - 1));
      b = 2 + (randlimb () % 35);
      check_special (b, p);
    }

  mpfr_init2 (x, MAX_DIGITS);
  for (i = 0; i < ITER; i++)
    {
      m = 2 + (randlimb () % (MAX_DIGITS - 1));
      mpfr_urandomb (x, RANDS);
      e = (mpfr_exp_t) (randlimb () % 21) - 10;
      if (!MPFR_IS_ZERO(x))
        mpfr_set_exp (x, (e == -10) ? mpfr_get_emin () :
                      ((e == 10) ? mpfr_get_emax () : e));
      b = 2 + (randlimb () % 35);
      r = RND_RAND ();
      mpfr_get_str (s, &f, b, m, x, r);
    }
  mpfr_clear (x);

  check_large ();
  check3 ("4.059650008e-83", MPFR_RNDN, "40597");
  check3 ("-6.606499965302424244461355e233", MPFR_RNDN, "-66065");
  check3 ("-7.4", MPFR_RNDN, "-74000");
  check3 ("0.997", MPFR_RNDN, "99700");
  check3 ("-4.53063926135729747564e-308", MPFR_RNDN, "-45306");
  check3 ("2.14478198760196000000e+16", MPFR_RNDN, "21448");
  check3 ("7.02293374921793516813e-84", MPFR_RNDN, "70229");

  check3 ("-6.7274500420134077e-87", MPFR_RNDN, "-67275");
  check3 ("-6.7274500420134077e-87", MPFR_RNDZ, "-67274");
  check3 ("-6.7274500420134077e-87", MPFR_RNDU, "-67274");
  check3 ("-6.7274500420134077e-87", MPFR_RNDD, "-67275");
  check3 ("-6.7274500420134077e-87", MPFR_RNDA, "-67275");

  check3 ("6.7274500420134077e-87", MPFR_RNDN, "67275");
  check3 ("6.7274500420134077e-87", MPFR_RNDZ, "67274");
  check3 ("6.7274500420134077e-87", MPFR_RNDU, "67275");
  check3 ("6.7274500420134077e-87", MPFR_RNDD, "67274");
  check3 ("6.7274500420134077e-87", MPFR_RNDA, "67275");

  check_bug_base2k ();
  check_reduced_exprange ();

  tests_end_mpfr ();
  return 0;
}
Пример #21
0
/* Generic random tests with cancellations.
 *
 * In summary, we do 4000 tests of the following form:
 * 1. We set the first MPFR_NCANCEL members of an array to random values,
 *    with a random exponent taken in 4 ranges, depending on the value of
 *    i % 4 (see code below).
 * 2. For each of the next MPFR_NCANCEL iterations:
 *    A. we randomly permute some terms of the array (to make sure that a
 *       particular order doesn't have an influence on the result);
 *    B. we compute the sum in a random rounding mode;
 *    C. if this sum is zero, we end the current test (there is no longer
 *       anything interesting to test);
 *    D. we check that this sum is below some bound (chosen as infinite
 *       for the first iteration of (2), i.e. this test will be useful
 *       only for the next iterations, after cancellations);
 *    E. we put the opposite of this sum in the array, the goal being to
 *       introduce a chain of cancellations;
 *    F. we compute the bound for the next iteration, derived from (E).
 * 3. We do another iteration like (2), but with reusing a random element
 *    of the array. This last test allows one to check the support of
 *    reused arguments. Before this support (r10467), it triggers an
 *    assertion failure with (almost?) all seeds, and if assertions are
 *    not checked, tsum fails in most cases but not all.
 */
static void
cancel (void)
{
  mpfr_t x[2 * MPFR_NCANCEL], bound;
  mpfr_ptr px[2 * MPFR_NCANCEL];
  int i, j, k, n;

  mpfr_init2 (bound, 2);

  /* With 4000 tests, tsum will fail in most cases without support of
     reused arguments (before r10467). */
  for (i = 0; i < 4000; i++)
    {
      mpfr_set_inf (bound, 1);
      for (n = 0; n <= numberof (x); n++)
        {
          mpfr_prec_t p;
          mpfr_rnd_t rnd;

          if (n < numberof (x))
            {
              px[n] = x[n];
              p = MPFR_PREC_MIN + (randlimb () % 256);
              mpfr_init2 (x[n], p);
              k = n;
            }
          else
            {
              /* Reuse of a random member of the array. */
              k = randlimb () % n;
            }

          if (n < MPFR_NCANCEL)
            {
              mpfr_exp_t e;

              MPFR_ASSERTN (n < numberof (x));
              e = (i & 1) ? 0 : mpfr_get_emin ();
              tests_default_random (x[n], 256, e,
                                    ((i & 2) ? e + 2000 : mpfr_get_emax ()),
                                    0);
            }
          else
            {
              /* random permutation with n random transpositions */
              for (j = 0; j < n; j++)
                {
                  int k1, k2;

                  k1 = randlimb () % (n-1);
                  k2 = randlimb () % (n-1);
                  mpfr_swap (x[k1], x[k2]);
                }

              rnd = RND_RAND ();

#if DEBUG
              printf ("mpfr_sum cancellation test\n");
              for (j = 0; j < n; j++)
                {
                  printf ("  x%d[%3ld] = ", j, mpfr_get_prec(x[j]));
                  mpfr_out_str (stdout, 16, 0, x[j], MPFR_RNDN);
                  printf ("\n");
                }
              printf ("  rnd = %s, output prec = %ld\n",
                      mpfr_print_rnd_mode (rnd), mpfr_get_prec (x[n]));
#endif

              mpfr_sum (x[k], px, n, rnd);

              if (mpfr_zero_p (x[k]))
                {
                  if (k == n)
                    n++;
                  break;
                }

              if (mpfr_cmpabs (x[k], bound) > 0)
                {
                  printf ("Error in cancel on i = %d, n = %d\n", i, n);
                  printf ("Expected bound: ");
                  mpfr_dump (bound);
                  printf ("x[%d]: ", k);
                  mpfr_dump (x[k]);
                  exit (1);
                }

              if (k != n)
                break;

              /* For the bound, use MPFR_RNDU due to possible underflow.
                 It would be nice to add some specific underflow checks,
                 though there are already ones in check_underflow(). */
              mpfr_set_ui_2exp (bound, 1,
                                mpfr_get_exp (x[n]) - p - (rnd == MPFR_RNDN),
                                MPFR_RNDU);
              /* The next sum will be <= bound in absolute value
                 (the equality can be obtained in all rounding modes
                 since the sum will be rounded). */

              mpfr_neg (x[n], x[n], MPFR_RNDN);
            }
        }

      while (--n >= 0)
        mpfr_clear (x[n]);
    }

  mpfr_clear (bound);
}
Пример #22
0
Файл: tadd.c Проект: qsnake/mpfr
static void
check_inexact (void)
{
    mpfr_t x, y, z, u;
    mpfr_prec_t px, py, pu, pz;
    int inexact, cmp;
    mpfr_rnd_t rnd;

    mpfr_init (x);
    mpfr_init (y);
    mpfr_init (z);
    mpfr_init (u);

    mpfr_set_prec (x, 2);
    mpfr_set_str_binary (x, "0.1E-4");
    mpfr_set_prec (u, 33);
    mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1");
    mpfr_set_prec (y, 31);
    if ((inexact = test_add (y, x, u, MPFR_RNDN)))
    {
        printf ("Wrong inexact flag (2): expected 0, got %d\n", inexact);
        exit (1);
    }

    mpfr_set_prec (x, 2);
    mpfr_set_str_binary (x, "0.1E-4");
    mpfr_set_prec (u, 33);
    mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1");
    mpfr_set_prec (y, 28);
    if ((inexact = test_add (y, x, u, MPFR_RNDN)))
    {
        printf ("Wrong inexact flag (1): expected 0, got %d\n", inexact);
        exit (1);
    }

    for (px=2; px<MAX_PREC; px++)
    {
        mpfr_set_prec (x, px);
        do
        {
            mpfr_urandomb (x, RANDS);
        }
        while (mpfr_cmp_ui (x, 0) == 0);
        for (pu=2; pu<MAX_PREC; pu++)
        {
            mpfr_set_prec (u, pu);
            do
            {
                mpfr_urandomb (u, RANDS);
            }
            while (mpfr_cmp_ui (u, 0) == 0);
            {
                py = MPFR_PREC_MIN + (randlimb () % (MAX_PREC - 1));
                mpfr_set_prec (y, py);
                pz =  (mpfr_cmpabs (x, u) >= 0) ? MPFR_EXP(x) - MPFR_EXP(u)
                      : MPFR_EXP(u) - MPFR_EXP(x);
                /* x + u is exactly representable with precision
                   abs(EXP(x)-EXP(u)) + max(prec(x), prec(u)) + 1 */
                pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u)) + 1;
                mpfr_set_prec (z, pz);
                rnd = RND_RAND ();
                if (test_add (z, x, u, rnd))
                {
                    printf ("z <- x + u should be exact\n");
                    printf ("x=");
                    mpfr_print_binary (x);
                    puts ("");
                    printf ("u=");
                    mpfr_print_binary (u);
                    puts ("");
                    printf ("z=");
                    mpfr_print_binary (z);
                    puts ("");
                    exit (1);
                }
                {
                    rnd = RND_RAND ();
                    inexact = test_add (y, x, u, rnd);
                    cmp = mpfr_cmp (y, z);
                    if (((inexact == 0) && (cmp != 0)) ||
                            ((inexact > 0) && (cmp <= 0)) ||
                            ((inexact < 0) && (cmp >= 0)))
                    {
                        printf ("Wrong inexact flag for rnd=%s\n",
                                mpfr_print_rnd_mode(rnd));
                        printf ("expected %d, got %d\n", cmp, inexact);
                        printf ("x=");
                        mpfr_print_binary (x);
                        puts ("");
                        printf ("u=");
                        mpfr_print_binary (u);
                        puts ("");
                        printf ("y=  ");
                        mpfr_print_binary (y);
                        puts ("");
                        printf ("x+u=");
                        mpfr_print_binary (z);
                        puts ("");
                        exit (1);
                    }
                }
            }
        }
    }

    mpfr_clear (x);
    mpfr_clear (y);
    mpfr_clear (z);
    mpfr_clear (u);
}
Пример #23
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y;
  unsigned long k, bd, nc, i;
  char *str, *str2;
  mp_exp_t e;
  int base, logbase, prec, baseprec, ret;

  tests_start_mpfr ();

  if (argc >= 2) /* tset_str <string> [<prec>] [<base>] */
    {
      prec = (argc >= 3) ? atoi (argv[2]) : 53;
      base = (argc >= 4) ? atoi (argv[3]) : 2;
      mpfr_init2 (x, prec);
      mpfr_set_str (x, argv[1], base, GMP_RNDN);
      mpfr_out_str (stdout, 10, 0, x, GMP_RNDN);
      puts ("");
      mpfr_clear (x);
      return 0;
    }

  mpfr_init2 (x, 2);

  nc = (argc > 1) ? atoi(argv[1]) : 53;
  if (nc < 100)
    nc = 100;

  bd = randlimb () & 8;

  str2 = str = (char*) (*__gmp_allocate_func) (nc * sizeof(char));

  if (bd)
    {
      for(k = 1; k <= bd; k++)
        *(str2++) = (randlimb () & 1) + '0';
    }
  else
    *(str2++) = '0';

  *(str2++) = '.';

  for (k = 1; k < nc - 17 - bd; k++)
    *(str2++) = '0' + (char) (randlimb () & 1);

  *(str2++) = 'e';
  sprintf (str2, "%d", (int) (randlimb () & INT_MAX) + INT_MIN/2);

  mpfr_set_prec (x, nc + 10);
  mpfr_set_str_binary (x, str);

  mpfr_set_prec (x, 54);
  mpfr_set_str_binary (x, "0.100100100110110101001010010101111000001011100100101010E-529");
  mpfr_init2 (y, 54);
  mpfr_set_str (y, "4.936a52bc17254@-133", 16, GMP_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (1a):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str_binary (x, "0.111111101101110010111010100110000111011001010100001101E-529");
  mpfr_set_str (y, "0.fedcba98765434P-529", 16, GMP_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (1b):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  (*__gmp_free_func) (str, nc * sizeof(char));

  mpfr_set_prec (x, 53);
  mpfr_set_str_binary (x, "+110101100.01010000101101000000100111001000101011101110E00");

  mpfr_set_str_binary (x, "1.0");
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error in mpfr_set_str_binary for s=1.0\n");
      mpfr_clear(x);
      mpfr_clear(y);
      exit(1);
    }

  mpfr_set_str_binary (x, "+0000");
  mpfr_set_str_binary (x, "+0000E0");
  mpfr_set_str_binary (x, "0000E0");
  if (mpfr_cmp_ui (x, 0))
    {
      printf ("Error in mpfr_set_str_binary for s=0.0\n");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (x, "+243495834958.53452345E1", 10, GMP_RNDN);
  mpfr_set_str (x, "9007199254740993", 10, GMP_RNDN);
  mpfr_set_str (x, "9007199254740992", 10, GMP_RNDU);
  mpfr_set_str (x, "9007199254740992", 10, GMP_RNDD);
  mpfr_set_str (x, "9007199254740992", 10, GMP_RNDZ);

  /* check a random number printed and read is not modified */
  prec = 53;
  mpfr_set_prec (x, prec);
  mpfr_set_prec (y, prec);
  for (i=0;i<N;i++)
    {
      mpfr_random (x);
      k = RND_RAND ();
      logbase = (randlimb () % 5) + 1;
      base = 1 << logbase;
      /* Warning: the number of bits needed to print exactly a number of
         'prec' bits in base 2^logbase may be greater than ceil(prec/logbase),
         for example 0.11E-1 in base 2 cannot be written exactly with only
         one digit in base 4 */
      if (base == 2)
        baseprec = prec;
      else
        baseprec = 1 + (prec - 2 + logbase) / logbase;
      str = mpfr_get_str (NULL, &e, base, baseprec, x, (mp_rnd_t) k);
      mpfr_set_str (y, str, base, (mp_rnd_t) k);
      MPFR_EXP(y) += logbase * (e - strlen (str));
      if (mpfr_cmp (x, y))
        {
          printf ("mpfr_set_str o mpfr_get_str <> id for rnd_mode=%s\n",
                  mpfr_print_rnd_mode ((mp_rnd_t) k));
          printf ("x=");
          mpfr_print_binary (x);
          puts ("");
          printf ("s=%s, exp=%d, base=%d\n", str, (int) e, base);
          printf ("y=");
          mpfr_print_binary (y);
          puts ("");
          mpfr_clear (x);
          mpfr_clear (y);
          exit (1);
        }
      (*__gmp_free_func) (str, strlen (str) + 1);
    }

  for (i = 2; i <= 36; i++)
    {
      if (mpfr_set_str (x, "@NaN@(garbage)", i, GMP_RNDN) != 0 ||
          !mpfr_nan_p(x))
        {
          printf ("mpfr_set_str failed on @NaN@(garbage)\n");
          exit (1);
        }

      /*
      if (mpfr_set_str (x, "@Inf@garbage", i, GMP_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
        {
          printf ("mpfr_set_str failed on @Inf@garbage\n");
          exit (1);
        }

      if (mpfr_set_str (x, "-@Inf@garbage", i, GMP_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) > 0)
        {
          printf ("mpfr_set_str failed on -@Inf@garbage\n");
          exit (1);
        }

      if (mpfr_set_str (x, "+@Inf@garbage", i, GMP_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
        {
          printf ("mpfr_set_str failed on +@Inf@garbage\n");
          exit (1);
        }
      */

      if (i > 16)
        continue;

      if (mpfr_set_str (x, "NaN", i, GMP_RNDN) != 0 ||
          !mpfr_nan_p(x))
        {
          printf ("mpfr_set_str failed on NaN\n");
          exit (1);
        }

      if (mpfr_set_str (x, "Inf", i, GMP_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
        {
          printf ("mpfr_set_str failed on Inf\n");
          exit (1);
        }

      if (mpfr_set_str (x, "-Inf", i, GMP_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) > 0)
        {
          printf ("mpfr_set_str failed on -Inf\n");
          exit (1);
        }

      if (mpfr_set_str (x, "+Inf", i, GMP_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
        {
          printf ("mpfr_set_str failed on +Inf\n");
          exit (1);
        }
    }

  /* check that mpfr_set_str works for uppercase letters too */
  mpfr_set_prec (x, 10);
  mpfr_set_str (x, "B", 16, GMP_RNDN);
  if (mpfr_cmp_ui (x, 11) != 0)
    {
      printf ("mpfr_set_str does not work for uppercase letters\n");
      exit (1);
    }

  /* start of tests added by Alain Delplanque */

  /* in this example an overflow can occur */
  mpfr_set_prec (x, 64);
  mpfr_set_prec (y, 64);
  mpfr_set_str_binary (x, "1.0E-532");
  mpfr_set_str (y, "0.71128279983522479470@-160", 10, GMP_RNDU);
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (2):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  /* in this example, I think there was a pb in the old function :
     result of mpfr_set_str_old for the same number , but with more
     precision is: 1.111111111110000000000000000111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100111000100001100000010101100111010e184
     this result is the same as mpfr_set_str */
  mpfr_set_prec (x, 64);
  mpfr_set_prec (y, 64);
  mpfr_set_str_binary (x, "1.111111111110000000000000000111111111111111111111111110000000001E184");
  mpfr_set_str (y, "0.jo08hg31hc5mmpj5mjjmgn55p2h35g@39", 27, GMP_RNDU);
  /* y = 49027884868983130654865109690613178467841148597221480052 */
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (3):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  /* not exact rounding in mpfr_set_str
     same number with more precision is : 1.111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011011111101000001101110110010101101000010100110011101110010001110e195
     this result is the same as mpfr_set_str */
  /* problem was : can_round was call with GMP_RNDN round mode,
     so can_round use an error : 1/2 * 2^err * ulp(y)
     instead of 2^err * ulp(y)
     I have increase err by 1 */
  mpfr_set_prec (x, 64);  /* it was round down instead of up */
  mpfr_set_prec (y, 64);
  mpfr_set_str_binary (x, "1.111111111111111111111111111000000000000000000000000000000000001e195");
  mpfr_set_str (y, "0.6e23ekb6acgh96abk10b6c9f2ka16i@45", 21, GMP_RNDU);
  /* y = 100433627392042473064661483711179345482301462325708736552078 */
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (4):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  /* may be an error in mpfr_set_str_old
     with more precision : 1.111111100000001111110000000000011111011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110111101010001110111011000010111001011100110110e180 */
  mpfr_set_prec (x, 64);  /* it was round down instead of up */
  mpfr_set_prec (y, 64);
  mpfr_set_str_binary (x, "1.111111100000001111110000000000011111011111111111111111111111111e180");
  mpfr_set_str (y, "0.10j8j2k82ehahha56390df0a1de030@41", 23, GMP_RNDZ);
  /* y = 3053110535624388280648330929253842828159081875986159414 */
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (5):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_prec (x, 64);
  mpfr_set_prec (y, 64);
  mpfr_set_str (y, "0.jrchfhpp9en7hidqm9bmcofid9q3jg@39", 28, GMP_RNDU);
  /* y = 196159429139499688661464718784226062699788036696626429952 */
  mpfr_set_str_binary (x, "0.1111111111111111111111111111111000000000000011100000001111100001E187");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (6):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_prec (x, 64);
  mpfr_set_prec (y, 64);
  mpfr_set_str (y, "0.h148m5ld5cf8gk1kd70b6ege92g6ba@47", 24, GMP_RNDZ);
  /* y = 52652933527468502324759448399183654588831274530295083078827114496 */
  mpfr_set_str_binary (x, "0.1111111111111100000000001000000000000000000011111111111111101111E215");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (7):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  /* worst cases for rounding to nearest in double precision */
  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);

  mpfr_set_str (y, "5e125", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.10111101000101110110011000100000101001010000000111111E418");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (8):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "69e267", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.10000101101111100101101100000110010011001010011011010E894");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (9):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "623e100", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.10110010000001010011000101111001110101000001111011111E342");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (10):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "3571e263", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.10110001001100100010011000110000111010100000110101010E886");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (11):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "75569e-254", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.10101101001000110001011011001000111000110101010110011E-827");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (12):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "920657e-23", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.10101001110101001100110000101110110111101111001101100E-56");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (13):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "9210917e80", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.11101101000100011001000110100011111100110000000110010E289");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (14):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "87575437e-309", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.11110000001110011001000000110000000100000010101101100E-1000");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (15):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "245540327e122", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.10001101101100010001100011110000110001100010111001011E434");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (16):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "491080654e122", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.10001101101100010001100011110000110001100010111001011E435");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (17):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "83356057653e193", 10, GMP_RNDN);
  mpfr_set_str_binary (x, "0.10101010001001110011011011010111011100010101000011000E678");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (18):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  CHECK53(y, "83356057653e193", GMP_RNDN, x,
          "0.10101010001001110011011011010111011100010101000011000E678",
          18);

  CHECK53(y, "619534293513e124", GMP_RNDN, x,
          "0.10001000011000010000000110000001111111110000011110001e452",
          19);

  CHECK53(y, "3142213164987e-294", GMP_RNDN, x,
          "0.11101001101000000100111011111101111001010001001101111e-935",
          20);

  CHECK53(y, "36167929443327e-159", GMP_RNDN, x,
          "0.11100111001110111110000101011001100110010100011111100e-483",
          21);

  CHECK53(y, "904198236083175e-161", GMP_RNDN, x,
          "0.11100111001110111110000101011001100110010100011111100e-485",
          22);

  CHECK53(y, "3743626360493413e-165", GMP_RNDN, x,
          "0.11000100000100011101001010111101011011011111011111001e-496",
          23);

  CHECK53(y, "94080055902682397e-242", GMP_RNDN, x,
          "0.10110010010011000000111100011100111100110011011001010e-747",
          24);

  CHECK53(y, "7e-303", GMP_RNDD, x,
          "0.10011001100111001000100110001110001000110111110001011e-1003",
          25);
  CHECK53(y, "7e-303", GMP_RNDU, x,
          "0.10011001100111001000100110001110001000110111110001100e-1003",
          26);

  CHECK53(y, "93e-234", GMP_RNDD, x,
          "0.10010011110110010111001001111001000010000000001110101E-770",
          27);
  CHECK53(y, "93e-234", GMP_RNDU, x,
          "0.10010011110110010111001001111001000010000000001110110E-770",
          28);

  CHECK53(y, "755e174", GMP_RNDD, x,
          "0.10111110110010011000110010011111101111000111111000101E588",
          29);
  CHECK53(y, "755e174", GMP_RNDU, x,
          "0.10111110110010011000110010011111101111000111111000110E588",
          30);

  CHECK53(y, "8699e-276", GMP_RNDD, x,
          "0.10010110100101101111100100100011011101100110100101100E-903",
          31);
  CHECK53(y, "8699e-276", GMP_RNDU, x,
          "0.10010110100101101111100100100011011101100110100101101E-903",
          32);

  CHECK53(y, "82081e41", GMP_RNDD, x,
          "0.10111000000010000010111011111001111010100011111001011E153",
          33);
  CHECK53(y, "82081e41", GMP_RNDU, x,
          "0.10111000000010000010111011111001111010100011111001100E153",
          34);

  CHECK53(y, "584169e229", GMP_RNDD, x,
          "0.11101011001010111000001011001110111000111100110101010E780",
          35);
  CHECK53(y, "584169e229", GMP_RNDU, x,
          "0.11101011001010111000001011001110111000111100110101011E780",
          36);

  CHECK53(y, "5783893e-128", GMP_RNDD, x,
          "0.10011000111100000110011110000101100111110011101110100E-402",
          37);
  CHECK53(y, "5783893e-128", GMP_RNDU, x,
          "0.10011000111100000110011110000101100111110011101110101E-402",
          38);

  CHECK53(y, "87575437e-310", GMP_RNDD, x,
          "0.11000000001011100000110011110011010000000010001010110E-1003",
          39);
  CHECK53(y, "87575437e-310", GMP_RNDU, x,
          "0.11000000001011100000110011110011010000000010001010111E-1003",
          40);

  CHECK53(y, "245540327e121", GMP_RNDD, x,
          "0.11100010101101001111010010110100011100000100101000100E430",
          41);
  CHECK53(y, "245540327e121", GMP_RNDU, x,
          "0.11100010101101001111010010110100011100000100101000101E430",
          42);

  CHECK53(y, "9078555839e-109", GMP_RNDD, x,
          "0.11111110001010111010110000110011100110001010011101101E-329",
          43);
  CHECK53(y, "9078555839e-109", GMP_RNDU, x,
          "0.11111110001010111010110000110011100110001010011101110E-329",
          44);

  CHECK53(y, "42333842451e201", GMP_RNDD, x,
          "0.10000000110001001101000100110110111110101011101011111E704",
          45);
  CHECK53(y, "42333842451e201", GMP_RNDU, x,
          "0.10000000110001001101000100110110111110101011101100000E704",
          46);

  CHECK53(y, "778380362293e218", GMP_RNDD, x,
          "0.11001101010111000001001100001100110010000001010010010E764",
          47);
  CHECK53(y, "778380362293e218", GMP_RNDU, x,
          "0.11001101010111000001001100001100110010000001010010011E764",
          48);

  CHECK53(y, "7812878489261e-179", GMP_RNDD, x,
          "0.10010011011011010111001111011101111101101101001110100E-551",
          49);
  CHECK53(y, "7812878489261e-179", GMP_RNDU, x,
          "0.10010011011011010111001111011101111101101101001110101E-551",
          50);

  CHECK53(y, "77003665618895e-73", GMP_RNDD, x,
          "0.11000101111110111111001111111101001101111000000101001E-196",
          51);
  CHECK53(y, "77003665618895e-73", GMP_RNDU, x,
          "0.11000101111110111111001111111101001101111000000101010E-196",
          52);

  CHECK53(y, "834735494917063e-300", GMP_RNDD, x,
          "0.11111110001101100001001101111100010011001110111010001E-947",
          53);
  CHECK53(y, "834735494917063e-300", GMP_RNDU, x,
          "0.11111110001101100001001101111100010011001110111010010E-947",
          54);

  CHECK53(y, "6182410494241627e-119", GMP_RNDD, x,
          "0.10001101110010110010001011000010001000101110100000111E-342",
          55);
  CHECK53(y, "6182410494241627e-119", GMP_RNDU, x,
          "0.10001101110010110010001011000010001000101110100001000E-342",
          56);

  CHECK53(y, "26153245263757307e49", GMP_RNDD, x,
          "0.10011110111100000000001011011110101100010000011011110E218",
          57);
  CHECK53(y, "26153245263757307e49", GMP_RNDU, x,
          "0.10011110111100000000001011011110101100010000011011111E218",
          58);

  /* to check this problem : I convert limb (10--0 or 101--1) into base b
     with more than mp_bits_per_limb digits,
     so when convert into base 2 I should have
     the limb that I have choose */
  /* this use mpfr_get_str */
  {
    size_t nb_digit = mp_bits_per_limb;
    mp_limb_t check_limb[2] = {MPFR_LIMB_HIGHBIT, ~(MPFR_LIMB_HIGHBIT >> 1)};
    int base[3] = {10, 16, 19};
    mp_rnd_t rnd[3] = {GMP_RNDU, GMP_RNDN, GMP_RNDD};
    int cbase, climb, crnd;
    char *str;

    mpfr_set_prec (x, mp_bits_per_limb); /* x and y have only one limb */
    mpfr_set_prec (y, mp_bits_per_limb);

    str = (char*) (*__gmp_allocate_func) (N + 20);

    mpfr_set_ui (x, 1, GMP_RNDN); /* ensures that x is not NaN or Inf */
    for (; nb_digit < N; nb_digit *= 10)
      for (cbase = 0; cbase < 3; cbase++)
        for (climb = 0; climb < 2; climb++)
          for (crnd = 0; crnd < 3; crnd++)
            {
              char *str1;
              mp_exp_t exp;

              *(MPFR_MANT(x)) = check_limb[climb];
              MPFR_EXP(x) = 0;

              mpfr_get_str (str + 2, &exp, base[cbase],
                            nb_digit, x, rnd[crnd]);
              str[0] = '-';
              str[(str[2] == '-')] =  '0';
              str[(str[2] == '-') + 1] =  '.';

              for (str1 = str; *str1 != 0; str1++)
                ;
              sprintf (str1, "@%i", (int) exp);

              mpfr_set_str (y, str, base[cbase], rnd[2 - crnd]);

              if (mpfr_cmp (x, y) != 0)
                {
                  printf ("Error in mpfr_set_str for nb_digit=%u, base=%d, "
                          "rnd=%s:\n", (unsigned int) nb_digit, base[cbase],
                          mpfr_print_rnd_mode (rnd[crnd]));
                  printf ("instead of: ");
                  mpfr_print_binary (x);
                  puts ("");
                  printf ("return    : ");
                  mpfr_print_binary (y);
                  puts ("");
                  exit (1);
                }
            }

    (*__gmp_free_func) (str, N + 20);
  }

  /* end of tests added by Alain Delplanque */

  /* check that flags are correctly cleared */
  mpfr_set_nan (x);
  mpfr_set_str (x, "+0.0", 10, GMP_RNDN);
  if (!mpfr_number_p(x) || mpfr_cmp_ui (x, 0) != 0 || mpfr_sgn (x) < 0)
    {
      printf ("x <- +0.0 failed after x=NaN\n");
      exit (1);
    }
  mpfr_set_str (x, "-0.0", 10, GMP_RNDN);
  if (!mpfr_number_p(x) || mpfr_cmp_ui (x, 0) != 0 || mpfr_sgn (x) > 0)
    {
      printf ("x <- -0.0 failed after x=NaN\n");
      exit (1);
    }

  /* check invalid input */
  ret = mpfr_set_str (x, "1E10toto", 10, GMP_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "1p10toto", 16, GMP_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "", 16, GMP_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "+", 16, GMP_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "-", 16, GMP_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "this_is_an_invalid_number_in_base_36", 36, GMP_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "1.2.3", 10, GMP_RNDN);
  MPFR_ASSERTN (ret == -1);
  mpfr_set_prec (x, 135);
  ret = mpfr_set_str (x, "thisisavalidnumberinbase36", 36, GMP_RNDN);
  mpfr_set_prec (y, 135);
  mpfr_set_str (y, "23833565676460972739462619524519814462546", 10, GMP_RNDN);
  MPFR_ASSERTN (mpfr_cmp (x, y) == 0 && ret == 0);

  /* coverage test for set_str_binary */
  mpfr_set_str_binary (x, "NaN");
  MPFR_ASSERTN(mpfr_nan_p (x));
  mpfr_set_str_binary (x, "Inf");
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
  mpfr_set_str_binary (x, "+Inf");
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
  mpfr_set_str_binary (x, "-Inf");
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);
  mpfr_set_prec (x, 3);
  mpfr_set_str_binary (x, "0.01E2");
  MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);
  mpfr_set_str_binary (x, "-0.01E2");
  MPFR_ASSERTN(mpfr_cmp_si (x, -1) == 0);

  mpfr_clear (x);
  mpfr_clear (y);

  check_underflow ();

  tests_end_mpfr ();
  return 0;
}
Пример #24
0
int
main (void)
{
  mpfr_t x, u;
  mpf_t y, z;
  mpfr_exp_t emax;
  unsigned long k, pr;
  int r, inexact;

  tests_start_mpfr ();

  mpf_init (y);
  mpf_init (z);

  mpf_set_d (y, 0.0);

  /* check prototype of mpfr_init_set_f */
  mpfr_init_set_f (x, y, MPFR_RNDN);
  mpfr_set_prec (x, 100);
  mpfr_set_f (x, y, MPFR_RNDN);

  mpf_urandomb (y, RANDS, 10 * GMP_NUMB_BITS);
  mpfr_set_f (x, y, RND_RAND ());

  /* bug found by Jean-Pierre Merlet */
  mpfr_set_prec (x, 256);
  mpf_set_prec (y, 256);
  mpfr_init2 (u, 256);
  mpfr_set_str (u,
                "7.f10872b020c49ba5e353f7ced916872b020c49ba5e353f7ced916872b020c498@2",
                16, MPFR_RNDN);
  mpf_set_str (y, "2033033E-3", 10); /* avoid 2033.033 which is
                                        locale-sensitive */
  mpfr_set_f (x, y, MPFR_RNDN);
  if (mpfr_cmp (x, u))
    {
      printf ("mpfr_set_f failed for y=2033033E-3\n");
      exit (1);
    }
  mpf_set_str (y, "-2033033E-3", 10); /* avoid -2033.033 which is
                                         locale-sensitive */
  mpfr_set_f (x, y, MPFR_RNDN);
  mpfr_neg (u, u, MPFR_RNDN);
  if (mpfr_cmp (x, u))
    {
      printf ("mpfr_set_f failed for y=-2033033E-3\n");
      exit (1);
    }

  mpf_set_prec (y, 300);
  mpf_set_str (y, "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", -2);
  mpf_mul_2exp (y, y, 600);
  mpfr_set_prec (x, 300);
  mpfr_set_f (x, y, MPFR_RNDN);
  if (mpfr_check (x) == 0)
    {
      printf ("Error in mpfr_set_f: corrupted result\n");
      mpfr_dump (x);
      exit (1);
    }
  MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, 901) == 0);

  /* random values */
  for (k = 1; k <= 1000; k++)
    {
      pr = 2 + (randlimb () & 255);
      mpf_set_prec (z, pr);
      mpf_urandomb (z, RANDS, z->_mp_prec);
      mpfr_set_prec (u, ((pr / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS));
      mpfr_set_f (u, z, MPFR_RNDN);
      if (mpfr_cmp_f (u , z) != 0)
        {
          printf ("Error in mpfr_set_f:\n");
          printf ("mpf (precision=%lu)=", pr);
          mpf_out_str (stdout, 16, 0, z);
          printf ("\nmpfr(precision=%lu)=",
                  ((pr / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS));
          mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
          putchar ('\n');
          exit (1);
        }
      mpfr_set_prec (x, pr);
      mpfr_set_f (x, z, MPFR_RNDN);
      mpfr_sub (u, u, x, MPFR_RNDN);
      mpfr_abs (u, u, MPFR_RNDN);
      if (mpfr_cmp_ui_2exp (u, 1, -pr - 1) > 0)
        {
          printf ("Error in mpfr_set_f: precision=%lu\n", pr);
          printf ("mpf =");
          mpf_out_str (stdout, 16, 0, z);
          printf ("\nmpfr=");
          mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
          putchar ('\n');
          exit (1);
        }
    }

  /* Check for +0 */
  mpfr_set_prec (x, 53);
  mpf_set_prec (y, 53);
  mpf_set_ui (y, 0);
  for (r = 0 ; r < MPFR_RND_MAX ; r++)
    {
      int i;
      for (i = -1; i <= 1; i++)
        {
          if (i)
            mpfr_set_si (x, i, MPFR_RNDN);
          inexact = mpfr_set_f (x, y, (mpfr_rnd_t) r);
          if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact)
            {
              printf ("mpfr_set_f(x,0) failed for %s, i = %d\n",
                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
              exit (1);
            }
        }
    }

  /* coverage test */
  mpf_set_prec (y, 2);
  mpfr_set_prec (x, 3 * mp_bits_per_limb);
  mpf_set_ui (y, 1);
  for (r = 0; r < mp_bits_per_limb; r++)
    {
      mpfr_urandomb (x, RANDS); /* to fill low limbs with random data */
      inexact = mpfr_set_f (x, y, MPFR_RNDN);
      MPFR_ASSERTN(inexact == 0 && mpfr_cmp_ui_2exp (x, 1, r) == 0);
      mpf_mul_2exp (y, y, 1);
    }

  mpf_set_ui (y, 1);
  mpf_mul_2exp (y, y, ULONG_MAX);
  mpfr_set_f (x, y, MPFR_RNDN);
  mpfr_set_ui (u, 1, MPFR_RNDN);
  mpfr_mul_2ui (u, u, ULONG_MAX, MPFR_RNDN);
  if (!mpfr_equal_p (x, u))
    {
      printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^ULONG_MAX\n");
      exit (1);
    }

  emax = mpfr_get_emax ();

  /* For mpf_mul_2exp, emax must fit in an unsigned long! */
  if (emax >= 0 && emax <= ULONG_MAX)
    {
      mpf_set_ui (y, 1);
      mpf_mul_2exp (y, y, emax);
      mpfr_set_f (x, y, MPFR_RNDN);
      mpfr_set_ui_2exp (u, 1, emax, MPFR_RNDN);
      if (!mpfr_equal_p (x, u))
        {
          printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^emax\n");
          exit (1);
        }
    }

  /* For mpf_mul_2exp, emax - 1 must fit in an unsigned long! */
  if (emax >= 1 && emax - 1 <= ULONG_MAX)
    {
      mpf_set_ui (y, 1);
      mpf_mul_2exp (y, y, emax - 1);
      mpfr_set_f (x, y, MPFR_RNDN);
      mpfr_set_ui_2exp (u, 1, emax - 1, MPFR_RNDN);
      if (!mpfr_equal_p (x, u))
        {
          printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^(emax-1)\n");
          exit (1);
        }
    }

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

  tests_end_mpfr ();
  return 0;
}
Пример #25
0
static void
check_cmp (int argc, char *argv[])
{
  mpfr_t x, y;
  int n, k;

  mpfr_inits2 (53, x, y, (mpfr_ptr) 0);

  mpfr_set_ui(x, 1, MPFR_RNDN);
  (mpfr_abs) (x, x, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error in mpfr_abs(1.0)\n");
      exit (1);
    }

  mpfr_set_si(x, -1, MPFR_RNDN);
  mpfr_abs(x, x, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error in mpfr_abs(1.0)\n");
      exit (1);
    }

  mpfr_set_si(x, -1, MPFR_RNDN);
  mpfr_abs(x, x, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error in mpfr_abs(-1.0)\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_abs (x, x, MPFR_RNDN);
  if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0))
    {
      printf ("Error in mpfr_abs(Inf).\n");
      exit (1);
    }
  mpfr_set_inf (x, -1);
  mpfr_abs (x, x, MPFR_RNDN);
  if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0))
    {
      printf ("Error in mpfr_abs(-Inf).\n");
      exit (1);
    }

  MPFR_SET_NAN(x);
  mpfr_abs (x, x, MPFR_RNDN);
  if (!MPFR_IS_NAN(x))
    {
      printf ("Error in mpfr_abs(NAN).\n");
      exit (1);
    }

  n = (argc==1) ? 25000 : atoi(argv[1]);
  for (k = 1; k <= n; k++)
    {
      mpfr_rnd_t rnd;
      int sign = SIGN_RAND ();

      mpfr_urandomb (x, RANDS);
      MPFR_SET_SIGN (x, sign);
      rnd = RND_RAND ();
      mpfr_abs (y, x, rnd);
      MPFR_SET_POS (x);
      if (mpfr_cmp (x, y))
        {
          printf ("Mismatch for sign=%d and x=", sign);
          mpfr_print_binary (x);
          printf ("\nResults=");
          mpfr_print_binary (y);
          putchar ('\n');
          exit (1);
        }
    }

  mpfr_clears (x, y, (mpfr_ptr) 0);
}
Пример #26
0
static void
check_random (FILE *fout, int nb_tests)
{
  int i;
  mpfr_t x;
  mp_rnd_t rnd;
  char flag[] =
    {
      '-',
      '+',
      ' ',
      '#',
      '0', /* no ambiguity: first zeros are flag zero*/
      '\''
    };
  char specifier[] =
    {
      'a',
      'b',
      'e',
      'f',
      'g'
    };
  mp_exp_t old_emin, old_emax;

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

  mpfr_init (x);

  for (i = 0; i < nb_tests; ++i)
    {
      int ret;
      int j, jmax;
      int spec, prec;
#define FMT_SIZE 13
      char fmt[FMT_SIZE]; /* at most something like "%-+ #0'.*R*f" */
      char *ptr = fmt;

      tests_default_random (x, 256, MPFR_EMIN_MIN, MPFR_EMAX_MAX);
      rnd = RND_RAND ();

      spec = (int) (randlimb () % 5);
      jmax = (spec == 3 || spec == 4) ? 6 : 5; /* ' flag only with %f or %g */
      /* advantage small precision */
      prec = (int) (randlimb () % ((randlimb () % 2) ? 10 : prec_max_printf));
      if (spec == 3
          && (mpfr_get_exp (x) > prec_max_printf
              || mpfr_get_exp (x) < -prec_max_printf))
        /*  change style 'f' to style 'e' when number x is large */
        --spec;

      *ptr++ = '%';
      for (j = 0; j < jmax; j++)
        {
          if (randlimb () % 3 == 0)
            *ptr++ = flag[j];
        }
      *ptr++ = '.';
      *ptr++ = '*';
      *ptr++ = 'R';
      *ptr++ = '*';
      *ptr++ = specifier[spec];
      *ptr = '\0';
      MPFR_ASSERTD (ptr - fmt < FMT_SIZE);

      mpfr_fprintf (fout, "mpfr_fprintf(fout, \"%s\", %d, %s, %Re)\n",
                    fmt, prec, mpfr_print_rnd_mode (rnd), x);
      ret = mpfr_fprintf (fout, fmt, prec, rnd, x);
      if (ret == -1)
        {
          if (spec == 3
              && (MPFR_GET_EXP (x) > INT_MAX || MPFR_GET_EXP (x) < -INT_MAX))
            /* normal failure: x is too large to be output with full precision */
            {
              mpfr_fprintf (fout, "too large !");
            }
          else
            {
              mpfr_printf ("Error in mpfr_fprintf(fout, \"%s\", %d, %s, %Re)\n",
                           fmt, prec, mpfr_print_rnd_mode (rnd), x);
              exit (1);
            }
        }
      mpfr_fprintf (fout, "\n");
    }

  mpfr_set_emin (old_emin);
  mpfr_set_emax (old_emax);

  mpfr_clear (x);
}
int
main (int argc, char *argv[])
{
  int i, N=10000, p;
  mpfr_rnd_t rnd;
  double d;

  tests_start_mpfr ();

  /* with no argument: prints to /dev/null,
     tout_str N: prints N tests to stdout */
  if (argc == 1)
    {
      fout = fopen ("/dev/null", "w");
      /* If we failed to open this device, try with a dummy file */
      if (fout == NULL)
        fout = fopen ("mpfrtest.txt", "w");
    }
  else
    {
      fout = stdout;
      N = atoi (argv[1]);
    }

  if (fout == NULL)
    {
      printf ("Can't open /dev/null or stdout\n");
      exit (1);
    }

  special ();

  check (-1.37247529013405550000e+15, MPFR_RNDN, 7);
  check (-1.5674376729569697500e+15, MPFR_RNDN, 19);
  check (-5.71262771772792640000e-79, MPFR_RNDU, 16);
  check (DBL_NEG_ZERO, MPFR_RNDU, 7);
  check (-4.5306392613572974756e-308, MPFR_RNDN, 8);
  check (-6.7265890111403371523e-165, MPFR_RNDN, 4);
  check (-1.3242553591261807653e+156, MPFR_RNDN, 16);
  check (-6.606499965302424244461355e233, MPFR_RNDN, 10);
  check4 (1.0, MPFR_RNDN, 10, 120);
  check (1.0, MPFR_RNDU, 10);
  check (4.059650008e-83, MPFR_RNDN, 10);
  check (-7.4, MPFR_RNDN, 10);
  check (0.997, MPFR_RNDN, 10);
  check (-4.53063926135729747564e-308, MPFR_RNDN, 10);
  check (2.14478198760196000000e+16, MPFR_RNDN, 10);
  check (7.02293374921793516813e-84, MPFR_RNDN, 10);

  /* random tests */
  for (i=0;i<N;i++)
    {
      do
        {
          d = DBL_RAND ();
        }
#ifdef HAVE_DENORMS
      while (0);
#else
      while (ABS(d) < DBL_MIN);
#endif
      rnd = RND_RAND ();
      p = 2 + randlimb () % 61;
      check (d, rnd, p);
    }

  fclose (fout);

  tests_end_mpfr ();
  return 0;
}
int
main (int argc, char *argv[])
{
  mpfr_t x, y, z;

  mpfr_prec_t prec, yprec;
  mpfr_t t, s;
  mpfr_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n, err;

  mpfr_prec_t p0=2, p1=100;
  unsigned int N=25;

  tests_start_mpfr ();

  mpfr_init (x);
  mpfr_init2 (y,sizeof(unsigned long int)*CHAR_BIT);
  mpfr_init (z);

  mpfr_init (s);
  mpfr_init (t);

  /* generic test */
  for (prec = p0; prec <= p1; prec++)
    {
      mpfr_set_prec (x, prec);
      mpfr_set_prec (s, sizeof(unsigned long int)*CHAR_BIT);
      mpfr_set_prec (z, prec);
      mpfr_set_prec (t, prec);
      yprec = prec + 10;

      for (n=0; n<N; n++)
        {
          mpfr_urandomb (x, RANDS);
          mpfr_urandomb (s, RANDS);
          if (randlimb () % 2)
            mpfr_neg (s, s, MPFR_RNDN);
          rnd = RND_RAND ();
          mpfr_set_prec (y, yprec);
          compare = mpfr_pow (y, x, s, rnd);
          err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec;
          if (mpfr_can_round (y, err, rnd, rnd, prec))
            {
              mpfr_set (t, y, rnd);
              inexact = mpfr_pow (z, x, s, rnd);
              if (mpfr_cmp (t, z))
                {
                  printf ("results differ for x^y with x=");
                  mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
                  printf (" y=");
                  mpfr_out_str (stdout, 2, 0, s, 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, z, MPFR_RNDN);
                  puts ("");
                  printf ("expected ");
                  mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
                  puts ("");
                  printf ("approx  ");
                  mpfr_print_binary (y);
                  puts ("");
                  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 ((rnd != MPFR_RNDN) && (compare * compare2 >= 0))
                compare = compare + compare2;
              else
                compare = inexact; /* cannot determine sign(t-f(x)) */
              if (((inexact == 0) && (compare != 0)) ||
                  ((inexact > 0) && (compare <= 0)) ||
                  ((inexact < 0) && (compare >= 0)))
                {
                  printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
                          "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
                  printf ("x="); mpfr_print_binary (x); puts ("");
                  printf ("y="); mpfr_print_binary (y); puts ("");
                  printf ("t="); mpfr_print_binary (t); puts ("");
                  exit (1);
                }
            }
        }
    }

  mpfr_clear (s);
  mpfr_clear (t);

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

  tests_end_mpfr ();
  return 0;
}