Esempio n. 1
0
static void
test_underflow1 (void)
{
  mpfr_t x, y, z, r;
  int inex, signy, signz, rnd, err = 0;

  mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);

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

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

  if (err)
    exit (1);
  mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
}
Esempio n. 2
0
static void
overflowed_fac0 (void)
{
  mpfr_t x, y;
  int inex, rnd, err = 0;
  mpfr_exp_t old_emax;

  old_emax = mpfr_get_emax ();

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

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

  if (err)
    exit (1);
  mpfr_clear (x);
  mpfr_clear (y);
}
Esempio n. 3
0
static void
test_overflow2 (void)
{
  mpfr_t x, y, z, r;
  int i, inex, rnd, err = 0;

  mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);

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

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

        inf = rnd == MPFR_RNDN || rnd == MPFR_RNDD || rnd == MPFR_RNDA;
        overflow = inf || i <= 0;

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

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

      }

  if (err)
    exit (1);
  mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
}
Esempio n. 4
0
int
main (void)
{
  mpfr_t x, y;
  float f, g, infp;
  int i;

  infp = (float) DBL_POS_INF;
  if (infp * 0.5 != infp)
    {
      fprintf (stderr, "Error, FLT_MAX + FLT_MAX does not yield INFP\n");
      fprintf (stderr, "(this is probably a compiler bug, please report)\n");
      exit (1);
    }

  tests_start_mpfr ();

  mpfr_init2 (x, 24);
  mpfr_init2 (y, 24);

#if !defined(MPFR_ERRDIVZERO)
  mpfr_set_nan (x);
  f = mpfr_get_flt (x, MPFR_RNDN);
  if (f == f)
    {
      printf ("Error for mpfr_get_flt(NaN)\n");
      exit (1);
    }
  mpfr_set_flt (x, f, MPFR_RNDN);
  if (mpfr_nan_p (x) == 0)
    {
      printf ("Error for mpfr_set_flt(NaN)\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  f = mpfr_get_flt (x, MPFR_RNDN);
  mpfr_set_flt (x, f, MPFR_RNDN);
  if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) < 0)
    {
      printf ("Error for mpfr_set_flt(mpfr_get_flt(+Inf)):\n");
      printf ("f=%f, expected -Inf\n", f);
      printf ("got "); mpfr_dump (x);
      exit (1);
    }

  mpfr_set_inf (x, -1);
  f = mpfr_get_flt (x, MPFR_RNDN);
  mpfr_set_flt (x, f, MPFR_RNDN);
  if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) > 0)
    {
      printf ("Error for mpfr_set_flt(mpfr_get_flt(-Inf)):\n");
      printf ("f=%f, expected -Inf\n", f);
      printf ("got "); mpfr_dump (x);
      exit (1);
    }
#endif

  mpfr_set_ui (x, 0, MPFR_RNDN);
  f = mpfr_get_flt (x, MPFR_RNDN);
  mpfr_set_flt (x, f, MPFR_RNDN);
  if (mpfr_zero_p (x) == 0 || MPFR_SIGN (x) < 0)
    {
      printf ("Error for mpfr_set_flt(mpfr_get_flt(+0))\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_neg (x, x, MPFR_RNDN);
  f = mpfr_get_flt (x, MPFR_RNDN);
  mpfr_set_flt (x, f, MPFR_RNDN);
  if (mpfr_zero_p (x) == 0 || MPFR_SIGN (x) > 0)
    {
      printf ("Error for mpfr_set_flt(mpfr_get_flt(-0))\n");
      exit (1);
    }

  mpfr_set_ui (x, 17, MPFR_RNDN);
  f = mpfr_get_flt (x, MPFR_RNDN);
  mpfr_set_flt (x, f, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 17) != 0)
    {
      printf ("Error for mpfr_set_flt(mpfr_get_flt(17))\n");
      printf ("expected 17\n");
      printf ("got      ");
      mpfr_dump (x);
      exit (1);
    }

  mpfr_set_si (x, -42, MPFR_RNDN);
  f = mpfr_get_flt (x, MPFR_RNDN);
  mpfr_set_flt (x, f, MPFR_RNDN);
  if (mpfr_cmp_si (x, -42) != 0)
    {
      printf ("Error for mpfr_set_flt(mpfr_get_flt(-42))\n");
      printf ("expected -42\n");
      printf ("got      ");
      mpfr_dump (x);
      exit (1);
    }

  mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
  for (i = -126; i < 128; i++)
    {
      f = mpfr_get_flt (x, MPFR_RNDN);
      mpfr_set_flt (y, f, MPFR_RNDN);
      if (mpfr_cmp (x, y) != 0)
        {
          printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
          printf ("expected "); mpfr_dump (x);
          printf ("got      "); mpfr_dump (y);
          exit (1);
        }
      mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
    }

  mpfr_set_prec (x, 53);
  mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
  for (i = -126; i < 128; i++)
    {
      mpfr_nextbelow (x);
      f = mpfr_get_flt (x, MPFR_RNDN);
      mpfr_nextabove (x);
      mpfr_set_flt (y, f, MPFR_RNDN);
      if (mpfr_cmp (x, y) != 0)
        {
          printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
          printf ("expected "); mpfr_dump (x);
          printf ("got      "); mpfr_dump (y);
          exit (1);
        }
      mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
    }

  mpfr_set_prec (x, 53);
  mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
  for (i = -126; i < 128; i++)
    {
      mpfr_nextabove (x);
      f = mpfr_get_flt (x, MPFR_RNDN);
      mpfr_nextbelow (x);
      mpfr_set_flt (y, f, MPFR_RNDN);
      if (mpfr_cmp (x, y) != 0)
        {
          printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
          printf ("expected "); mpfr_dump (x);
          printf ("got      "); mpfr_dump (y);
          exit (1);
        }
      mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
    }

  mpfr_set_si_2exp (x, 1, -150, MPFR_RNDN);
  g = 0.0;
  f = mpfr_get_flt (x, MPFR_RNDN);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-150),RNDN)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDZ);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-150),RNDZ)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDD);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-150),RNDD)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  g = FLT_MIN * FLT_EPSILON;
  f = mpfr_get_flt (x, MPFR_RNDU);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-150),RNDU)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDA);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-150),RNDA)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }

  mpfr_set_si_2exp (x, 1, -151, MPFR_RNDN);
  g = 0.0;
  f = mpfr_get_flt (x, MPFR_RNDN);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-151),RNDN)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDZ);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-151),RNDZ)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDD);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-151),RNDD)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  g = FLT_MIN * FLT_EPSILON;
  f = mpfr_get_flt (x, MPFR_RNDU);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-151),RNDU)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDA);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-151),RNDA)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }

  mpfr_set_si_2exp (x, 1, -149, MPFR_RNDN);
  g = FLT_MIN * FLT_EPSILON;
  f = mpfr_get_flt (x, MPFR_RNDN);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-149),RNDN)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDZ);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-149),RNDZ)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDD);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-149),RNDD)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDU);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-149),RNDU)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDA);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^(-149),RNDA)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }

  mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
  g = FLT_MAX;
  f = mpfr_get_flt (x, MPFR_RNDZ);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128,RNDZ)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDD);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128,RNDD)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
#if !defined(MPFR_ERRDIVZERO)
  f = mpfr_get_flt (x, MPFR_RNDN); /* 2^128 rounds to itself with extended
                                      exponent range, we should get +Inf */
  g = infp;
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128,RNDN)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDU);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128,RNDU)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDA);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128,RNDA)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
#endif

  /* corner case: take x with 25 bits just below 2^128 */
  mpfr_set_prec (x, 25);
  mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
  mpfr_nextbelow (x);
  g = FLT_MAX;
  f = mpfr_get_flt (x, MPFR_RNDZ);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDZ)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDD);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDD)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDN); /* first round to 2^128 (even rule),
                                      thus we should get +Inf */
  g = infp;
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDN)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDU);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDU)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }
  f = mpfr_get_flt (x, MPFR_RNDA);
  if (f != g)
    {
      printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDA)\n");
      printf ("expected %.8e, got %.8e\n", g, f);
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);

  tests_end_mpfr ();
  return 0;
}
Esempio n. 5
0
static void
special ()
{
    mpfr_t x, y, z, t;

    mpfr_init2 (x, 53);
    mpfr_init2 (y, 53);
    mpfr_init2 (z, 53);
    mpfr_init2 (t, 2);

    mpfr_set_ui (x, 2, GMP_RNDN);
    mpfr_pow_si (x, x, -2, GMP_RNDN);
    if (mpfr_cmp_ui_2exp (x, 1, -2))
    {
        printf ("Error in pow_si(x,x,-2) for x=2\n");
        exit (1);
    }
    mpfr_set_ui (x, 2, GMP_RNDN);
    mpfr_set_si (y, -2, GMP_RNDN);
    test_pow (x, x, y, GMP_RNDN);
    if (mpfr_cmp_ui_2exp (x, 1, -2))
    {
        printf ("Error in pow(x,x,y) for x=2, y=-2\n");
        exit (1);
    }

    mpfr_set_prec (x, 2);
    mpfr_set_str_binary (x, "1.0e-1");
    mpfr_set_prec (y, 53);
    mpfr_set_str_binary (y, "0.11010110011100101010110011001010100111000001000101110E-1");
    mpfr_set_prec (z, 2);
    test_pow (z, x, y, GMP_RNDZ);
    mpfr_set_str_binary (x, "1.0e-1");
    if (mpfr_cmp (x, z))
    {
        printf ("Error in mpfr_pow (1)\n");
        exit (1);
    }

    mpfr_set_prec (x, 64);
    mpfr_set_prec (y, 64);
    mpfr_set_prec (z, 64);
    mpfr_set_prec (t, 64);
    mpfr_set_str_binary (x, "0.111011000111100000111010000101010100110011010000011");
    mpfr_set_str_binary (y, "0.111110010100110000011101100011010111000010000100101");
    mpfr_set_str_binary (t, "0.1110110011110110001000110100100001001111010011111000010000011001");

    test_pow (z, x, y, GMP_RNDN);
    if (mpfr_cmp (z, t))
    {
        printf ("Error in mpfr_pow for prec=64, rnd=GMP_RNDN\n");
        exit (1);
    }

    mpfr_set_prec (x, 53);
    mpfr_set_prec (y, 53);
    mpfr_set_prec (z, 53);
    mpfr_set_str (x, "5.68824667828621954868e-01", 10, GMP_RNDN);
    mpfr_set_str (y, "9.03327850535952658895e-01", 10, GMP_RNDN);
    test_pow (z, x, y, GMP_RNDZ);
    if (mpfr_cmp_str1 (z, "0.60071044650456473235"))
    {
        printf ("Error in mpfr_pow for prec=53, rnd=GMP_RNDZ\n");
        exit (1);
    }

    mpfr_set_prec (t, 2);
    mpfr_set_prec (x, 30);
    mpfr_set_prec (y, 30);
    mpfr_set_prec (z, 30);
    mpfr_set_str (x, "1.00000000001010111110001111011e1", 2, GMP_RNDN);
    mpfr_set_str (t, "-0.5", 10, GMP_RNDN);
    test_pow (z, x, t, GMP_RNDN);
    mpfr_set_str (y, "1.01101001111010101110000101111e-1", 2, GMP_RNDN);
    if (mpfr_cmp (z, y))
    {
        printf ("Error in mpfr_pow for prec=30, rnd=GMP_RNDN\n");
        exit (1);
    }

    mpfr_set_prec (x, 21);
    mpfr_set_prec (y, 21);
    mpfr_set_prec (z, 21);
    mpfr_set_str (x, "1.11111100100001100101", 2, GMP_RNDN);
    test_pow (z, x, t, GMP_RNDZ);
    mpfr_set_str (y, "1.01101011010001100000e-1", 2, GMP_RNDN);
    if (mpfr_cmp (z, y))
    {
        printf ("Error in mpfr_pow for prec=21, rnd=GMP_RNDZ\n");
        printf ("Expected ");
        mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
        printf ("\nGot      ");
        mpfr_out_str (stdout, 2, 0, z, GMP_RNDN);
        printf ("\n");
        exit (1);
    }

    /* From http://www.terra.es/personal9/ismaeljc/hall.htm */
    mpfr_set_prec (x, 113);
    mpfr_set_prec (y, 2);
    mpfr_set_prec (z, 169);
    mpfr_set_str1 (x, "6078673043126084065007902175846955");
    mpfr_set_ui_2exp (y, 3, -1, GMP_RNDN);
    test_pow (z, x, y, GMP_RNDZ);
    if (mpfr_cmp_str1 (z, "473928882491000966028828671876527456070714790264144"))
    {
        printf ("Error in mpfr_pow for 6078673043126084065007902175846955");
        printf ("^(3/2), GMP_RNDZ\nExpected ");
        printf ("4.73928882491000966028828671876527456070714790264144e50");
        printf ("\nGot      ");
        mpfr_out_str (stdout, 10, 0, z, GMP_RNDN);
        printf ("\n");
        exit (1);
    }
    test_pow (z, x, y, GMP_RNDU);
    if (mpfr_cmp_str1 (z, "473928882491000966028828671876527456070714790264145"))
    {
        printf ("Error in mpfr_pow for 6078673043126084065007902175846955");
        printf ("^(3/2), GMP_RNDU\nExpected ");
        printf ("4.73928882491000966028828671876527456070714790264145e50");
        printf ("\nGot      ");
        mpfr_out_str (stdout, 10, 0, z, GMP_RNDN);
        printf ("\n");
        exit (1);
    }

    mpfr_set_inf (x, 1);
    mpfr_set_prec (y, 2);
    mpfr_set_str_binary (y, "1E10");
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
    mpfr_set_inf (x, -1);
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
    mpfr_set_prec (y, 10);
    mpfr_set_str_binary (y, "1.000000001E9");
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_NEG(z));
    mpfr_set_str_binary (y, "1.000000001E8");
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));

    mpfr_set_inf (x, -1);
    mpfr_set_prec (y, 2 * mp_bits_per_limb);
    mpfr_set_ui (y, 1, GMP_RNDN);
    mpfr_mul_2exp (y, y, mp_bits_per_limb - 1, GMP_RNDN);
    /* y = 2^(mp_bits_per_limb - 1) */
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
    mpfr_nextabove (y);
    test_pow (z, x, y, GMP_RNDN);
    /* y = 2^(mp_bits_per_limb - 1) + epsilon */
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
    mpfr_nextbelow (y);
    mpfr_div_2exp (y, y, 1, GMP_RNDN);
    mpfr_nextabove (y);
    test_pow (z, x, y, GMP_RNDN);
    /* y = 2^(mp_bits_per_limb - 2) + epsilon */
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));

    mpfr_set_si (x, -1, GMP_RNDN);
    mpfr_set_prec (y, 2);
    mpfr_set_str_binary (y, "1E10");
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_cmp_ui (z, 1) == 0);

    /* Check (-0)^(17.0001) */
    mpfr_set_prec (x, 6);
    mpfr_set_prec (y, 640);
    MPFR_SET_ZERO (x);
    MPFR_SET_NEG (x);
    mpfr_set_ui (y, 17, GMP_RNDN);
    mpfr_nextabove (y);
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));

    mpfr_clear (x);
    mpfr_clear (y);
    mpfr_clear (z);
    mpfr_clear (t);
}
Esempio n. 6
0
static void
check_special_exprange (void)
{
  int inexact, ov;
  unsigned int eflags, gflags;
  mpfr_t xi, xf, x;
  mpfr_exp_t emax;

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

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

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

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

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

  mpfr_clears (xi, xf, x, (mpfr_ptr) 0);
}
Esempio n. 7
0
static void
check_hard (void)
{
  mpfr_t u, v, q, q2;
  mpfr_prec_t precu, precv, precq;
  int rnd;
  int inex, inex2, i, j;

  mpfr_init (q);
  mpfr_init (q2);
  mpfr_init (u);
  mpfr_init (v);

  for (precq = MPFR_PREC_MIN; precq <= 64; precq ++)
    {
      mpfr_set_prec (q, precq);
      mpfr_set_prec (q2, precq + 1);
      for (j = 0; j < 2; j++)
        {
          if (j == 0)
            {
              do
                {
                  mpfr_urandomb (q2, RANDS);
                }
              while (mpfr_cmp_ui (q2, 0) == 0);
            }
          else /* use q2=1 */
            mpfr_set_ui (q2, 1, MPFR_RNDN);
      for (precv = precq; precv <= 10 * precq; precv += precq)
        {
          mpfr_set_prec (v, precv);
          do
            {
              mpfr_urandomb (v, RANDS);
            }
          while (mpfr_cmp_ui (v, 0) == 0);
          for (precu = precq; precu <= 10 * precq; precu += precq)
            {
              mpfr_set_prec (u, precu);
              mpfr_mul (u, v, q2, MPFR_RNDN);
              mpfr_nextbelow (u);
              for (i = 0; i <= 2; i++)
                {
                  RND_LOOP(rnd)
                    {
                      inex = test_div (q, u, v, (mpfr_rnd_t) rnd);
                      inex2 = get_inexact (q, u, v);
                      if (inex_cmp (inex, inex2))
                        {
                          printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n",
                                  mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex2, inex);
                          printf ("u=  "); mpfr_dump (u);
                          printf ("v=  "); mpfr_dump (v);
                          printf ("q=  "); mpfr_dump (q);
                          mpfr_set_prec (q2, precq + precv);
                          mpfr_mul (q2, q, v, MPFR_RNDN);
                          printf ("q*v="); mpfr_dump (q2);
                          exit (1);
                        }
                    }
                  mpfr_nextabove (u);
                }
            }
        }
        }
    }

  mpfr_clear (q);
  mpfr_clear (q2);
  mpfr_clear (u);
  mpfr_clear (v);
}
Esempio n. 8
0
static void
overflowed_sin_cos0 (void)
{
  mpfr_t x, y, z;
  int emax, inex, rnd, err = 0;
  mpfr_exp_t old_emax;

  old_emax = mpfr_get_emax ();

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

  for (emax = -1; emax <= 0; emax++)
    {
      mpfr_set_ui_2exp (z, 1, emax, MPFR_RNDN);
      mpfr_nextbelow (z);
      set_emax (emax);  /* 1 is not representable. */
      /* and if emax < 0, 1 - eps is not representable either. */
      RND_LOOP (rnd)
        {
          mpfr_set_si (x, 0, MPFR_RNDN);
          mpfr_neg (x, x, MPFR_RNDN);
          mpfr_clear_flags ();
          inex = mpfr_sin_cos (x, y, x, (mpfr_rnd_t) rnd);
          if (! mpfr_overflow_p ())
            {
              printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
                      "  The overflow flag is not set.\n",
                      mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
              err = 1;
            }
          if (! (mpfr_zero_p (x) && MPFR_SIGN (x) < 0))
            {
              printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
                      "  Got sin = ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
              mpfr_print_binary (x);
              printf (" instead of -0.\n");
              err = 1;
            }
          if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
            {
              if (inex == 0)
                {
                  printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
                          "  The inexact value must be non-zero.\n",
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  err = 1;
                }
              if (! mpfr_equal_p (y, z))
                {
                  printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
                          "  Got cos = ",
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  mpfr_print_binary (y);
                  printf (" instead of 0.11111111E%d.\n", emax);
                  err = 1;
                }
            }
          else
            {
              if (inex == 0)
                {
                  printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
                          "  The inexact value must be non-zero.\n",
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  err = 1;
                }
              if (! (mpfr_inf_p (y) && MPFR_SIGN (y) > 0))
                {
                  printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
                          "  Got cos = ",
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  mpfr_print_binary (y);
                  printf (" instead of +Inf.\n");
                  err = 1;
                }
            }
        }
      set_emax (old_emax);
    }

  if (err)
    exit (1);
  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Esempio n. 9
0
static void
addsubq_overflow_aux (mpfr_exp_t e)
{
  mpfr_t x, y;
  mpq_t q;
  mpfr_exp_t emax;
  int inex;
  int rnd;
  int sign, sub;

  MPFR_ASSERTN (e <= LONG_MAX);
  emax = mpfr_get_emax ();
  set_emax (e);
  mpfr_inits2 (16, x, y, (mpfr_ptr) 0);
  mpq_init (q);

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

  for (sign = 0; sign <= 1; sign++)
    {
      for (sub = 0; sub <= 1; sub++)
        {
          RND_LOOP(rnd)
            {
              unsigned int flags, ex_flags;
              int inf;

              inf = rnd == MPFR_RNDA ||
                    rnd == (sign ? MPFR_RNDD : MPFR_RNDU);
              ex_flags = MPFR_FLAGS_INEXACT | (inf ? MPFR_FLAGS_OVERFLOW : 0);
              mpfr_clear_flags ();
              inex = sub ?
                mpfr_sub_q (y, x, q, (mpfr_rnd_t) rnd) :
                mpfr_add_q (y, x, q, (mpfr_rnd_t) rnd);
              flags = __gmpfr_flags;
              if (inex == 0 || flags != ex_flags ||
                  (inf ? ! mpfr_inf_p (y) : ! mpfr_equal_p (x, y)))
                {
                  printf ("Error in addsubq_overflow_aux(%ld),"
                          " sign = %d, %s\n", (long) e, sign,
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  printf ("Got inex = %d, y = ", inex);
                  mpfr_dump (y);
                  printf ("Expected flags:");
                  flags_out (ex_flags);
                  printf ("Got flags:     ");
                  flags_out (flags);
                  exit (1);
                }
            }
          mpq_neg (q, q);
        }
      mpfr_neg (x, x, MPFR_RNDN);
      mpq_neg (q, q);
    }

  mpq_clear (q);
  mpfr_clears (x, y, (mpfr_ptr) 0);
  set_emax (emax);
}
Esempio n. 10
0
File: zeta.c Progetto: MiKTeX/miktex
int
mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
{
  mpfr_t z_pre, s1, y, p;
  long add;
  mpfr_prec_t precz, prec1, precs, precs1;
  int inex;
  MPFR_GROUP_DECL (group);
  MPFR_ZIV_DECL (loop);
  MPFR_SAVE_EXPO_DECL (expo);

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

  /* Zero, Nan or Inf ? */
  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (s)))
    {
      if (MPFR_IS_NAN (s))
        {
          MPFR_SET_NAN (z);
          MPFR_RET_NAN;
        }
      else if (MPFR_IS_INF (s))
        {
          if (MPFR_IS_POS (s))
            return mpfr_set_ui (z, 1, MPFR_RNDN); /* Zeta(+Inf) = 1 */
          MPFR_SET_NAN (z); /* Zeta(-Inf) = NaN */
          MPFR_RET_NAN;
        }
      else /* s iz zero */
        {
          MPFR_ASSERTD (MPFR_IS_ZERO (s));
          return mpfr_set_si_2exp (z, -1, -1, rnd_mode);
        }
    }

  /* s is neither Nan, nor Inf, nor Zero */

  /* check tiny s: we have zeta(s) = -1/2 - 1/2 log(2 Pi) s + ... around s=0,
     and for |s| <= 2^(-4), we have |zeta(s) + 1/2| <= |s|.
     EXP(s) + 1 < -PREC(z) is a sufficient condition to be able to round
     correctly, for any PREC(z) >= 1 (see algorithms.tex for details). */
  if (MPFR_GET_EXP (s) + 1 < - (mpfr_exp_t) MPFR_PREC(z))
    {
      int signs = MPFR_SIGN(s);

      MPFR_SAVE_EXPO_MARK (expo);
      mpfr_set_si_2exp (z, -1, -1, rnd_mode); /* -1/2 */
      if (rnd_mode == MPFR_RNDA)
        rnd_mode = MPFR_RNDD; /* the result is around -1/2, thus negative */
      if ((rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDZ) && signs < 0)
        {
          mpfr_nextabove (z); /* z = -1/2 + epsilon */
          inex = 1;
        }
      else if (rnd_mode == MPFR_RNDD && signs > 0)
        {
          mpfr_nextbelow (z); /* z = -1/2 - epsilon */
          inex = -1;
        }
      else
        {
          if (rnd_mode == MPFR_RNDU) /* s > 0: z = -1/2 */
            inex = 1;
          else if (rnd_mode == MPFR_RNDD)
            inex = -1;              /* s < 0: z = -1/2 */
          else /* (MPFR_RNDZ and s > 0) or MPFR_RNDN: z = -1/2 */
            inex = (signs > 0) ? 1 : -1;
        }
      MPFR_SAVE_EXPO_FREE (expo);
      return mpfr_check_range (z, inex, rnd_mode);
    }

  /* Check for case s= -2n */
  if (MPFR_IS_NEG (s))
    {
      mpfr_t tmp;
      tmp[0] = *s;
      MPFR_EXP (tmp) = MPFR_GET_EXP (s) - 1;
      if (mpfr_integer_p (tmp))
        {
          MPFR_SET_ZERO (z);
          MPFR_SET_POS (z);
          MPFR_RET (0);
        }
    }

  /* Check for case s=1 before changing the exponent range */
  if (mpfr_cmp (s, __gmpfr_one) == 0)
    {
      MPFR_SET_INF (z);
      MPFR_SET_POS (z);
      MPFR_SET_DIVBY0 ();
      MPFR_RET (0);
    }

  MPFR_SAVE_EXPO_MARK (expo);

  /* Compute Zeta */
  if (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0) /* Case s >= 1/2 */
    inex = mpfr_zeta_pos (z, s, rnd_mode);
  else /* use reflection formula
          zeta(s) = 2^s*Pi^(s-1)*sin(Pi*s/2)*gamma(1-s)*zeta(1-s) */
    {
      int overflow = 0;

      precz = MPFR_PREC (z);
      precs = MPFR_PREC (s);

      /* Precision precs1 needed to represent 1 - s, and s + 2,
         without any truncation */
      precs1 = precs + 2 + MAX (0, - MPFR_GET_EXP (s));
      /* Precision prec1 is the precision on elementary computations;
         it ensures a final precision prec1 - add for zeta(s) */
      add = compute_add (s, precz);
      prec1 = precz + add;
      /* FIXME: To avoid that the working precision (prec1) depends on the
         input precision, one would need to take into account the error made
         when s1 is not exactly 1-s when computing zeta(s1) and gamma(s1)
         below, and also in the case y=Inf (i.e. when gamma(s1) overflows).
         Make sure that underflows do not occur in intermediate computations.
         Due to the limited precision, they are probably not possible
         in practice; add some MPFR_ASSERTN's to be sure that problems
         do not remain undetected? */
      prec1 = MAX (prec1, precs1) + 10;

      MPFR_GROUP_INIT_4 (group, prec1, z_pre, s1, y, p);
      MPFR_ZIV_INIT (loop, prec1);
      for (;;)
        {
          mpfr_exp_t ey;
          mpfr_t z_up;

          mpfr_const_pi (p, MPFR_RNDD); /* p is Pi */

          mpfr_sub (s1, __gmpfr_one, s, MPFR_RNDN); /* s1 = 1-s */
          mpfr_gamma (y, s1, MPFR_RNDN);          /* gamma(1-s) */
          if (MPFR_IS_INF (y)) /* zeta(s) < 0 for -4k-2 < s < -4k,
                                  zeta(s) > 0 for -4k < s < -4k+2 */
            {
              /* FIXME: An overflow in gamma(s1) does not imply that
                 zeta(s) will overflow. A solution:
                 1. Compute
                   log(|zeta(s)|/2) = (s-1)*log(2*pi) + lngamma(1-s)
                     + log(abs(sin(Pi*s/2)) * zeta(1-s))
                 (possibly sharing computations with the normal case)
                 with a rather good accuracy (see (2)).
                 Memorize the sign of sin(...) for the final sign.
                 2. Take the exponential, ~= |zeta(s)|/2. If there is an
                 overflow, then this means an overflow on the final result
                 (due to the multiplication by 2, which has not been done
                 yet).
                 3. Ziv test.
                 4. Correct the sign from the sign of sin(...).
                 5. Round then multiply by 2. Here, an overflow in either
                 operation means a real overflow. */
              mpfr_reflection_overflow (z_pre, s1, s, y, p, MPFR_RNDD);
              /* z_pre is a lower bound of |zeta(s)|/2, thus if it overflows,
                 or has exponent emax, then |zeta(s)| overflows too. */
              if (MPFR_IS_INF (z_pre) || MPFR_GET_EXP(z_pre) == __gmpfr_emax)
                { /* determine the sign of overflow */
                  mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
                  mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
                  overflow = (mpfr_cmp_si_2exp (s1, -1, -1) > 0) ? -1 : 1;
                  break;
                }
              else /* EXP(z_pre) < __gmpfr_emax */
                {
                  int ok = 0;
                  mpfr_t z_down;
                  mpfr_init2 (z_up, mpfr_get_prec (z_pre));
                  mpfr_reflection_overflow (z_up, s1, s, y, p, MPFR_RNDU);
                  /* if the lower approximation z_pre does not overflow, but
                     z_up does, we need more precision */
                  if (MPFR_IS_INF (z_up) || MPFR_GET_EXP(z_up) == __gmpfr_emax)
                    goto next_loop;
                  /* check if z_pre and z_up round to the same number */
                  mpfr_init2 (z_down, precz);
                  mpfr_set (z_down, z_pre, rnd_mode);
                  /* Note: it might be that EXP(z_down) = emax here, in that
                     case we will have overflow below when we multiply by 2 */
                  mpfr_prec_round (z_up, precz, rnd_mode);
                  ok = mpfr_cmp (z_down, z_up) == 0;
                  mpfr_clear (z_up);
                  mpfr_clear (z_down);
                  if (ok)
                    {
                      /* get correct sign and multiply by 2 */
                      mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
                      mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
                      if (mpfr_cmp_si_2exp (s1, -1, -1) > 0)
                        mpfr_neg (z_pre, z_pre, rnd_mode);
                      mpfr_mul_2ui (z_pre, z_pre, 1, rnd_mode);
                      break;
                    }
                  else
                    goto next_loop;
                }
            }
          mpfr_zeta_pos (z_pre, s1, MPFR_RNDN);   /* zeta(1-s)  */
          mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);  /* gamma(1-s)*zeta(1-s) */

          /* multiply z_pre by 2^s*Pi^(s-1) where p=Pi, s1=1-s */
          mpfr_mul_2ui (y, p, 1, MPFR_RNDN);      /* 2*Pi */
          mpfr_neg (s1, s1, MPFR_RNDN);           /* s-1 */
          mpfr_pow (y, y, s1, MPFR_RNDN);         /* (2*Pi)^(s-1) */
          mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
          mpfr_mul_2ui (z_pre, z_pre, 1, MPFR_RNDN);

          /* multiply z_pre by sin(Pi*s/2) */
          mpfr_mul (y, s, p, MPFR_RNDN);
          mpfr_div_2ui (p, y, 1, MPFR_RNDN);      /* p = s*Pi/2 */
          /* FIXME: sinpi will be available, we should replace the mpfr_sin
             call below by mpfr_sinpi(s/2), where s/2 will be exact.
             Can mpfr_sin underflow? Moreover, the code below should be
             improved so that the "if" condition becomes unlikely, e.g.
             by taking a slightly larger working precision. */
          mpfr_sin (y, p, MPFR_RNDN);             /* y = sin(Pi*s/2) */
          ey = MPFR_GET_EXP (y);
          if (ey < 0) /* take account of cancellation in sin(p) */
            {
              mpfr_t t;

              MPFR_ASSERTN (- ey < MPFR_PREC_MAX - prec1);
              mpfr_init2 (t, prec1 - ey);
              mpfr_const_pi (t, MPFR_RNDD);
              mpfr_mul (t, s, t, MPFR_RNDN);
              mpfr_div_2ui (t, t, 1, MPFR_RNDN);
              mpfr_sin (y, t, MPFR_RNDN);
              mpfr_clear (t);
            }
          mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);

          if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, prec1 - add, precz,
                                           rnd_mode)))
            break;

        next_loop:
          MPFR_ZIV_NEXT (loop, prec1);
          MPFR_GROUP_REPREC_4 (group, prec1, z_pre, s1, y, p);
        }
      MPFR_ZIV_FREE (loop);
      if (overflow != 0)
        {
          inex = mpfr_overflow (z, rnd_mode, overflow);
          MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
        }
      else
        inex = mpfr_set (z, z_pre, rnd_mode);
      MPFR_GROUP_CLEAR (group);
    }

  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (z, inex, rnd_mode);
}
Esempio n. 11
0
static void
check_underflow (void)
{
  mpfr_t sum1, sum2, t[NUNFL];
  mpfr_ptr p[NUNFL];
  mpfr_prec_t precmax = 444;
  mpfr_exp_t emin, emax;
  unsigned int ex_flags, flags;
  int c, i;

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

  ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;

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

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

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

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

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

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

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

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

      RND_LOOP(r)
        {
          int inex1, inex2;

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

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

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

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

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

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

  set_emin (emin);
  set_emax (emax);
}
Esempio n. 12
0
File: zeta.c Progetto: MiKTeX/miktex
/* return in z a lower bound (for rnd = RNDD) or upper bound (for rnd = RNDU)
   of |zeta(s)|/2, using:
   log(|zeta(s)|/2) = (s-1)*log(2*Pi) + lngamma(1-s)
   + log(|sin(Pi*s/2)| * zeta(1-s)).
   Assumes s < 1/2 and s1 = 1-s exactly, thus s1 > 1/2.
   y and p are temporary variables.
   At input, p is Pi rounded down.
   The comments in the code are for rnd = RNDD. */
static void
mpfr_reflection_overflow (mpfr_t z, mpfr_t s1, const mpfr_t s, mpfr_t y,
                          mpfr_t p, mpfr_rnd_t rnd)
{
  mpz_t sint;

  MPFR_ASSERTD (rnd == MPFR_RNDD || rnd == MPFR_RNDU);

  /* Since log is increasing, we want lower bounds on |sin(Pi*s/2)| and
     zeta(1-s). */
  mpz_init (sint);
  mpfr_get_z (sint, s, MPFR_RNDD); /* sint = floor(s) */
  /* We first compute a lower bound of |sin(Pi*s/2)|, which is a periodic
     function of period 2. Thus:
     if 2k < s < 2k+1, then |sin(Pi*s/2)| is increasing;
     if 2k-1 < s < 2k, then |sin(Pi*s/2)| is decreasing.
     These cases are distinguished by testing bit 0 of floor(s) as if
     represented in two's complement (or equivalently, as an unsigned
     integer mod 2):
     0: sint = 0 mod 2, thus 2k < s < 2k+1 and |sin(Pi*s/2)| is increasing;
     1: sint = 1 mod 2, thus 2k-1 < s < 2k and |sin(Pi*s/2)| is decreasing.
     Let's recall that the comments are for rnd = RNDD. */
  if (mpz_tstbit (sint, 0) == 0) /* |sin(Pi*s/2)| is increasing: round down
                                    Pi*s to get a lower bound. */
    {
      mpfr_mul (y, p, s, rnd);
      if (rnd == MPFR_RNDD)
        mpfr_nextabove (p); /* we will need p rounded above afterwards */
    }
  else /* |sin(Pi*s/2)| is decreasing: round up Pi*s to get a lower bound. */
    {
      if (rnd == MPFR_RNDD)
        mpfr_nextabove (p);
      mpfr_mul (y, p, s, MPFR_INVERT_RND(rnd));
    }
  mpfr_div_2ui (y, y, 1, MPFR_RNDN); /* exact, rounding mode doesn't matter */
  /* The rounding direction of sin depends on its sign. We have:
     if -4k-2 < s < -4k, then -2k-1 < s/2 < -2k, thus sin(Pi*s/2) < 0;
     if -4k < s < -4k+2, then -2k < s/2 < -2k+1, thus sin(Pi*s/2) > 0.
     These cases are distinguished by testing bit 1 of floor(s) as if
     represented in two's complement (or equivalently, as an unsigned
     integer mod 4):
     0: sint = {0,1} mod 4, thus -2k < s/2 < -2k+1 and sin(Pi*s/2) > 0;
     1: sint = {2,3} mod 4, thus -2k-1 < s/2 < -2k and sin(Pi*s/2) < 0.
     Let's recall that the comments are for rnd = RNDD. */
  if (mpz_tstbit (sint, 1) == 0) /* -2k < s/2 < -2k+1; sin(Pi*s/2) > 0 */
    {
      /* Round sin down to get a lower bound of |sin(Pi*s/2)|. */
      mpfr_sin (y, y, rnd);
    }
  else /* -2k-1 < s/2 < -2k; sin(Pi*s/2) < 0 */
    {
      /* Round sin up to get a lower bound of |sin(Pi*s/2)|. */
      mpfr_sin (y, y, MPFR_INVERT_RND(rnd));
      mpfr_abs (y, y, MPFR_RNDN); /* exact, rounding mode doesn't matter */
    }
  mpz_clear (sint);
  /* now y <= |sin(Pi*s/2)| when rnd=RNDD, y >= |sin(Pi*s/2)| when rnd=RNDU */
  mpfr_zeta_pos (z, s1, rnd); /* zeta(1-s) */
  mpfr_mul (z, z, y, rnd);
  /* now z <= |sin(Pi*s/2)|*zeta(1-s) */
  mpfr_log (z, z, rnd);
  /* now z <= log(|sin(Pi*s/2)|*zeta(1-s)) */
  mpfr_lngamma (y, s1, rnd);
  mpfr_add (z, z, y, rnd);
  /* z <= lngamma(1-s) + log(|sin(Pi*s/2)|*zeta(1-s)) */
  /* since s-1 < 0, we want to round log(2*pi) upwards */
  mpfr_mul_2ui (y, p, 1, MPFR_INVERT_RND(rnd));
  mpfr_log (y, y, MPFR_INVERT_RND(rnd));
  mpfr_mul (y, y, s1, MPFR_INVERT_RND(rnd));
  mpfr_sub (z, z, y, rnd);
  mpfr_exp (z, z, rnd);
  if (rnd == MPFR_RNDD)
    mpfr_nextbelow (p); /* restore original p */
}
Esempio n. 13
0
int
mpfr_digamma (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  int inex;
  MPFR_SAVE_EXPO_DECL (expo);

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

  if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
    {
      if (MPFR_IS_NAN(x))
        {
          MPFR_SET_NAN(y);
          MPFR_RET_NAN;
        }
      else if (MPFR_IS_INF(x))
        {
          if (MPFR_IS_POS(x)) /* Digamma(+Inf) = +Inf */
            {
              MPFR_SET_SAME_SIGN(y, x);
              MPFR_SET_INF(y);
              MPFR_RET(0);
            }
          else                /* Digamma(-Inf) = NaN */
            {
              MPFR_SET_NAN(y);
              MPFR_RET_NAN;
            }
        }
      else /* Zero case */
        {
          /* the following works also in case of overlap */
          MPFR_SET_INF(y);
          MPFR_SET_OPPOSITE_SIGN(y, x);
          MPFR_SET_DIVBY0 ();
          MPFR_RET(0);
        }
    }

  /* Digamma is undefined for negative integers */
  if (MPFR_IS_NEG(x) && mpfr_integer_p (x))
    {
      MPFR_SET_NAN(y);
      MPFR_RET_NAN;
    }

  /* now x is a normal number */

  MPFR_SAVE_EXPO_MARK (expo);
  /* for x very small, we have Digamma(x) = -1/x - gamma + O(x), more precisely
     -1 < Digamma(x) + 1/x < 0 for -0.2 < x < 0.2, thus:
     (i) either x is a power of two, then 1/x is exactly representable, and
         as long as 1/2*ulp(1/x) > 1, we can conclude;
     (ii) otherwise assume x has <= n bits, and y has <= n+1 bits, then
   |y + 1/x| >= 2^(-2n) ufp(y), where ufp means unit in first place.
   Since |Digamma(x) + 1/x| <= 1, if 2^(-2n) ufp(y) >= 2, then
   |y - Digamma(x)| >= 2^(-2n-1)ufp(y), and rounding -1/x gives the correct result.
   If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
   A sufficient condition is thus EXP(x) <= -2 MAX(PREC(x),PREC(Y)). */
  if (MPFR_EXP(x) < -2)
    {
      if (MPFR_EXP(x) <= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(y)))
        {
          int signx = MPFR_SIGN(x);
          inex = mpfr_si_div (y, -1, x, rnd_mode);
          if (inex == 0) /* x is a power of two */
            { /* result always -1/x, except when rounding down */
              if (rnd_mode == MPFR_RNDA)
                rnd_mode = (signx > 0) ? MPFR_RNDD : MPFR_RNDU;
              if (rnd_mode == MPFR_RNDZ)
                rnd_mode = (signx > 0) ? MPFR_RNDU : MPFR_RNDD;
              if (rnd_mode == MPFR_RNDU)
                inex = 1;
              else if (rnd_mode == MPFR_RNDD)
                {
                  mpfr_nextbelow (y);
                  inex = -1;
                }
              else /* nearest */
                inex = 1;
            }
          MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
          goto end;
        }
    }

  if (MPFR_IS_NEG(x))
    inex = mpfr_digamma_reflection (y, x, rnd_mode);
  /* if x < 1/2 we use the reflection formula */
  else if (MPFR_EXP(x) < 0)
    inex = mpfr_digamma_reflection (y, x, rnd_mode);
  else
    inex = mpfr_digamma_positive (y, x, rnd_mode);

 end:
  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (y, inex, rnd_mode);
}
Esempio n. 14
0
static void
special (void)
{
  mpfr_t x, y;
  unsigned xprec, yprec;

  mpfr_init (x);
  mpfr_init (y);

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 32);
  mpfr_set_ui (x, 1, GMP_RNDN);
  mpfr_div_ui (y, x, 3, GMP_RNDN);

  mpfr_set_prec (x, 100);
  mpfr_set_prec (y, 100);
  mpfr_random (x);
  mpfr_div_ui (y, x, 123456, GMP_RNDN);
  mpfr_set_ui (x, 0, GMP_RNDN);
  mpfr_div_ui (y, x, 123456789, GMP_RNDN);
  if (mpfr_cmp_ui (y, 0))
    {
      printf ("mpfr_div_ui gives non-zero for 0/ui\n");
      exit (1);
    }

  /* bug found by Norbert Mueller, 21 Aug 2001 */
  mpfr_set_prec (x, 110);
  mpfr_set_prec (y, 60);
  mpfr_set_str_binary (x, "0.110101110011111110011111001110011001110111000000111110001000111011000011E-44");
  mpfr_div_ui (y, x, 17, GMP_RNDN);
  mpfr_set_str_binary (x, "0.11001010100101100011101110000001100001010110101001010011011E-48");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in x/17 for x=1/16!\n");
      printf ("Expected ");
      mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
      printf ("\nGot      ");
      mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
      printf ("\n");
      exit (1);
    }

  /* corner case */
  mpfr_set_prec (x, 2 * mp_bits_per_limb);
  mpfr_set_prec (y, 2);
  mpfr_set_ui (x, 4, GMP_RNDN);
  mpfr_nextabove (x);
  mpfr_div_ui (y, x, 2, GMP_RNDN); /* exactly in the middle */
  MPFR_ASSERTN(mpfr_cmp_ui (y, 2) == 0);

  mpfr_set_prec (x, 3 * mp_bits_per_limb);
  mpfr_set_prec (y, 2);
  mpfr_set_ui (x, 2, GMP_RNDN);
  mpfr_nextabove (x);
  mpfr_div_ui (y, x, 2, GMP_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);

  mpfr_set_prec (x, 3 * mp_bits_per_limb);
  mpfr_set_prec (y, 2);
  mpfr_set_si (x, -4, GMP_RNDN);
  mpfr_nextbelow (x);
  mpfr_div_ui (y, x, 2, GMP_RNDD);
  MPFR_ASSERTN(mpfr_cmp_si (y, -3) == 0);

  for (xprec = 53; xprec <= 128; xprec++)
    {
      mpfr_set_prec (x, xprec);
      mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2");
      for (yprec = 53; yprec <= 128; yprec++)
        {
          mpfr_set_prec (y, yprec);
          mpfr_div_ui (y, x, 1, GMP_RNDN);
          if (mpfr_cmp(x,y))
            {
              printf ("division by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec);
              printf ("expected "); mpfr_print_binary (x); puts ("");
              printf ("got      "); mpfr_print_binary (y); puts ("");
              exit (1);
            }
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
Esempio n. 15
0
int
mpfr_zeta (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
{
  mpfr_t z_pre, s1, y, p;
  double sd, eps, m1, c;
  long add;
  mp_prec_t precz, prec1, precs, precs1;
  int inex;
  MPFR_GROUP_DECL (group);
  MPFR_ZIV_DECL (loop);
  MPFR_SAVE_EXPO_DECL (expo);

  MPFR_LOG_FUNC (("s[%#R]=%R rnd=%d", s, s, rnd_mode),
                 ("z[%#R]=%R inexact=%d", z, z, inex));

  /* Zero, Nan or Inf ? */
  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (s)))
    {
      if (MPFR_IS_NAN (s))
        {
          MPFR_SET_NAN (z);
          MPFR_RET_NAN;
        }
      else if (MPFR_IS_INF (s))
        {
          if (MPFR_IS_POS (s))
            return mpfr_set_ui (z, 1, GMP_RNDN); /* Zeta(+Inf) = 1 */
          MPFR_SET_NAN (z); /* Zeta(-Inf) = NaN */
          MPFR_RET_NAN;
        }
      else /* s iz zero */
        {
          MPFR_ASSERTD (MPFR_IS_ZERO (s));
          mpfr_set_ui (z, 1, rnd_mode);
          mpfr_div_2ui (z, z, 1, rnd_mode);
          MPFR_CHANGE_SIGN (z);
          MPFR_RET (0);
        }
    }

  /* s is neither Nan, nor Inf, nor Zero */

  /* check tiny s: we have zeta(s) = -1/2 - 1/2 log(2 Pi) s + ... around s=0,
     and for |s| <= 0.074, we have |zeta(s) + 1/2| <= |s|.
     Thus if |s| <= 1/4*ulp(1/2), we can deduce the correct rounding
     (the 1/4 covers the case where |zeta(s)| < 1/2 and rounding to nearest).
     A sufficient condition is that EXP(s) + 1 < -PREC(z). */
  if (MPFR_EXP(s) + 1 < - (mp_exp_t) MPFR_PREC(z))
    {
      int signs = MPFR_SIGN(s);
      mpfr_set_si_2exp (z, -1, -1, rnd_mode); /* -1/2 */
      if ((rnd_mode == GMP_RNDU || rnd_mode == GMP_RNDZ) && signs < 0)
        {
          mpfr_nextabove (z); /* z = -1/2 + epsilon */
          inex = 1;
        }
      else if (rnd_mode == GMP_RNDD && signs > 0)
        {
          mpfr_nextbelow (z); /* z = -1/2 - epsilon */
          inex = -1;
        }
      else
        {
          if (rnd_mode == GMP_RNDU) /* s > 0: z = -1/2 */
            inex = 1;
          else if (rnd_mode == GMP_RNDD)
            inex = -1;              /* s < 0: z = -1/2 */
          else /* (GMP_RNDZ and s > 0) or GMP_RNDN: z = -1/2 */
            inex = (signs > 0) ? 1 : -1;
        }
      return mpfr_check_range (z, inex, rnd_mode);
    }

  /* Check for case s= -2n */
  if (MPFR_IS_NEG (s))
    {
      mpfr_t tmp;
      tmp[0] = *s;
      MPFR_EXP (tmp) = MPFR_EXP (s) - 1;
      if (mpfr_integer_p (tmp))
        {
          MPFR_SET_ZERO (z);
          MPFR_SET_POS (z);
          MPFR_RET (0);
        }
    }

  MPFR_SAVE_EXPO_MARK (expo);

  /* Compute Zeta */
  if (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0) /* Case s >= 1/2 */
    inex = mpfr_zeta_pos (z, s, rnd_mode);
  else /* use reflection formula
          zeta(s) = 2^s*Pi^(s-1)*sin(Pi*s/2)*gamma(1-s)*zeta(1-s) */
    {
      precz = MPFR_PREC (z);
      precs = MPFR_PREC (s);

      /* Precision precs1 needed to represent 1 - s, and s + 2,
         without any truncation */
      precs1 = precs + 2 + MAX (0, - MPFR_GET_EXP (s));
      sd = mpfr_get_d (s, GMP_RNDN) - 1.0;
      if (sd < 0.0)
        sd = -sd; /* now sd = abs(s-1.0) */
      /* Precision prec1 is the precision on elementary computations;
         it ensures a final precision prec1 - add for zeta(s) */
      /* eps = pow (2.0, - (double) precz - 14.0); */
      eps = __gmpfr_ceil_exp2 (- (double) precz - 14.0);
      m1 = 1.0 + MAX(1.0 / eps,  2.0 * sd) * (1.0 + eps);
      c = (1.0 + eps) * (1.0 + eps * MAX(8.0, m1));
      /* add = 1 + floor(log(c*c*c*(13 + m1))/log(2)); */
      add = __gmpfr_ceil_log2 (c * c * c * (13.0 + m1));
      prec1 = precz + add;
      prec1 = MAX (prec1, precs1) + 10;

      MPFR_GROUP_INIT_4 (group, prec1, z_pre, s1, y, p);
      MPFR_ZIV_INIT (loop, prec1);
      for (;;)
        {
          mpfr_sub (s1, __gmpfr_one, s, GMP_RNDN);/* s1 = 1-s */
          mpfr_zeta_pos (z_pre, s1, GMP_RNDN);   /* zeta(1-s)  */
          mpfr_gamma (y, s1, GMP_RNDN);          /* gamma(1-s) */
          if (MPFR_IS_INF (y)) /* Zeta(s) < 0 for -4k-2 < s < -4k,
                                  Zeta(s) > 0 for -4k < s < -4k+2 */
            {
              MPFR_SET_INF (z_pre);
              mpfr_div_2ui (s1, s, 2, GMP_RNDN); /* s/4, exact */
              mpfr_frac (s1, s1, GMP_RNDN); /* exact, -1 < s1 < 0 */
              if (mpfr_cmp_si_2exp (s1, -1, -1) > 0)
                MPFR_SET_NEG (z_pre);
              else
                MPFR_SET_POS (z_pre);
              break;
            }
          mpfr_mul (z_pre, z_pre, y, GMP_RNDN);  /* gamma(1-s)*zeta(1-s) */
          mpfr_const_pi (p, GMP_RNDD);
          mpfr_mul (y, s, p, GMP_RNDN);
          mpfr_div_2ui (y, y, 1, GMP_RNDN);      /* s*Pi/2 */
          mpfr_sin (y, y, GMP_RNDN);             /* sin(Pi*s/2) */
          mpfr_mul (z_pre, z_pre, y, GMP_RNDN);
          mpfr_mul_2ui (y, p, 1, GMP_RNDN);      /* 2*Pi */
          mpfr_neg (s1, s1, GMP_RNDN);           /* s-1 */
          mpfr_pow (y, y, s1, GMP_RNDN);         /* (2*Pi)^(s-1) */
          mpfr_mul (z_pre, z_pre, y, GMP_RNDN);
          mpfr_mul_2ui (z_pre, z_pre, 1, GMP_RNDN);

          if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, prec1 - add, precz,
                                           rnd_mode)))
            break;

          MPFR_ZIV_NEXT (loop, prec1);
          MPFR_GROUP_REPREC_4 (group, prec1, z_pre, s1, y, p);
        }
      MPFR_ZIV_FREE (loop);
      inex = mpfr_set (z, z_pre, rnd_mode);
      MPFR_GROUP_CLEAR (group);
    }

  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (z, inex, rnd_mode);
}
Esempio n. 16
0
File: yn.c Progetto: Kirija/XPIR
int
mpfr_yn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
{
  int inex;
  unsigned long absn;
  MPFR_SAVE_EXPO_DECL (expo);

  MPFR_LOG_FUNC
    (("n=%ld x[%Pu]=%.*Rg rnd=%d", n, mpfr_get_prec (z), mpfr_log_prec, z, r),
     ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (res), mpfr_log_prec, res, inex));

  absn = SAFE_ABS (unsigned long, n);

  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (z)))
    {
      if (MPFR_IS_NAN (z))
        {
          MPFR_SET_NAN (res); /* y(n,NaN) = NaN */
          MPFR_RET_NAN;
        }
      /* y(n,z) tends to zero when z goes to +Inf, oscillating around
         0. We choose to return +0 in that case. */
      else if (MPFR_IS_INF (z))
        {
          if (MPFR_SIGN(z) > 0)
            return mpfr_set_ui (res, 0, r);
          else /* y(n,-Inf) = NaN */
            {
              MPFR_SET_NAN (res);
              MPFR_RET_NAN;
            }
        }
      else /* y(n,z) tends to -Inf for n >= 0 or n even, to +Inf otherwise,
              when z goes to zero */
        {
          MPFR_SET_INF(res);
          if (n >= 0 || ((unsigned long) n & 1) == 0)
            MPFR_SET_NEG(res);
          else
            MPFR_SET_POS(res);
          mpfr_set_divby0 ();
          MPFR_RET(0);
        }
    }

  /* for z < 0, y(n,z) is imaginary except when j(n,|z|) = 0, which we
     assume does not happen for a rational z. */
  if (MPFR_SIGN(z) < 0)
    {
      MPFR_SET_NAN (res);
      MPFR_RET_NAN;
    }

  /* now z is not singular, and z > 0 */

  MPFR_SAVE_EXPO_MARK (expo);

  /* Deal with tiny arguments. We have:
     y0(z) = 2 log(z)/Pi + 2 (euler - log(2))/Pi + O(log(z)*z^2), more
     precisely for 0 <= z <= 1/2, with g(z) = 2/Pi + 2(euler-log(2))/Pi/log(z),
                g(z) - 0.41*z^2 < y0(z)/log(z) < g(z)
     thus since log(z) is negative:
             g(z)*log(z) < y0(z) < (g(z) - z^2/2)*log(z)
     and since |g(z)| >= 0.63 for 0 <= z <= 1/2, the relative error on
     y0(z)/log(z) is bounded by 0.41*z^2/0.63 <= 0.66*z^2.
     Note: we use both the main term in log(z) and the constant term, because
     otherwise the relative error would be only in 1/log(|log(z)|).
  */
  if (n == 0 && MPFR_EXP(z) < - (mpfr_exp_t) (MPFR_PREC(res) / 2))
    {
      mpfr_t l, h, t, logz;
      mpfr_prec_t prec;
      int ok, inex2;

      prec = MPFR_PREC(res) + 10;
      mpfr_init2 (l, prec);
      mpfr_init2 (h, prec);
      mpfr_init2 (t, prec);
      mpfr_init2 (logz, prec);
      /* first enclose log(z) + euler - log(2) = log(z/2) + euler */
      mpfr_log (logz, z, MPFR_RNDD);    /* lower bound of log(z) */
      mpfr_set (h, logz, MPFR_RNDU);    /* exact */
      mpfr_nextabove (h);              /* upper bound of log(z) */
      mpfr_const_euler (t, MPFR_RNDD);  /* lower bound of euler */
      mpfr_add (l, logz, t, MPFR_RNDD); /* lower bound of log(z) + euler */
      mpfr_nextabove (t);              /* upper bound of euler */
      mpfr_add (h, h, t, MPFR_RNDU);    /* upper bound of log(z) + euler */
      mpfr_const_log2 (t, MPFR_RNDU);   /* upper bound of log(2) */
      mpfr_sub (l, l, t, MPFR_RNDD);    /* lower bound of log(z/2) + euler */
      mpfr_nextbelow (t);              /* lower bound of log(2) */
      mpfr_sub (h, h, t, MPFR_RNDU);    /* upper bound of log(z/2) + euler */
      mpfr_const_pi (t, MPFR_RNDU);     /* upper bound of Pi */
      mpfr_div (l, l, t, MPFR_RNDD);    /* lower bound of (log(z/2)+euler)/Pi */
      mpfr_nextbelow (t);              /* lower bound of Pi */
      mpfr_div (h, h, t, MPFR_RNDD);    /* upper bound of (log(z/2)+euler)/Pi */
      mpfr_mul_2ui (l, l, 1, MPFR_RNDD); /* lower bound on g(z)*log(z) */
      mpfr_mul_2ui (h, h, 1, MPFR_RNDU); /* upper bound on g(z)*log(z) */
      /* we now have l <= g(z)*log(z) <= h, and we need to add -z^2/2*log(z)
         to h */
      mpfr_mul (t, z, z, MPFR_RNDU);     /* upper bound on z^2 */
      /* since logz is negative, a lower bound corresponds to an upper bound
         for its absolute value */
      mpfr_neg (t, t, MPFR_RNDD);
      mpfr_div_2ui (t, t, 1, MPFR_RNDD);
      mpfr_mul (t, t, logz, MPFR_RNDU); /* upper bound on z^2/2*log(z) */
      mpfr_add (h, h, t, MPFR_RNDU);
      inex = mpfr_prec_round (l, MPFR_PREC(res), r);
      inex2 = mpfr_prec_round (h, MPFR_PREC(res), r);
      /* we need h=l and inex=inex2 */
      ok = (inex == inex2) && mpfr_equal_p (l, h);
      if (ok)
        mpfr_set (res, h, r); /* exact */
      mpfr_clear (l);
      mpfr_clear (h);
      mpfr_clear (t);
      mpfr_clear (logz);
      if (ok)
        goto end;
    }

  /* small argument check for y1(z) = -2/Pi/z + O(log(z)):
     for 0 <= z <= 1, |y1(z) + 2/Pi/z| <= 0.25 */
  if (n == 1 && MPFR_EXP(z) + 1 < - (mpfr_exp_t) MPFR_PREC(res))
    {
      mpfr_t y;
      mpfr_prec_t prec;
      mpfr_exp_t err1;
      int ok;
      MPFR_BLOCK_DECL (flags);

      /* since 2/Pi > 0.5, and |y1(z)| >= |2/Pi/z|, if z <= 2^(-emax-1),
         then |y1(z)| > 2^emax */
      prec = MPFR_PREC(res) + 10;
      mpfr_init2 (y, prec);
      mpfr_const_pi (y, MPFR_RNDU); /* Pi*(1+u)^2, where here and below u
                                      represents a quantity <= 1/2^prec */
      mpfr_mul (y, y, z, MPFR_RNDU); /* Pi*z * (1+u)^4, upper bound */
      MPFR_BLOCK (flags, mpfr_ui_div (y, 2, y, MPFR_RNDZ));
      /* 2/Pi/z * (1+u)^6, lower bound, with possible overflow */
      if (MPFR_OVERFLOW (flags))
        {
          mpfr_clear (y);
          MPFR_SAVE_EXPO_FREE (expo);
          return mpfr_overflow (res, r, -1);
        }
      mpfr_neg (y, y, MPFR_RNDN);
      /* (1+u)^6 can be written 1+7u [for another value of u], thus the
         error on 2/Pi/z is less than 7ulp(y). The truncation error is less
         than 1/4, thus if ulp(y)>=1/4, the total error is less than 8ulp(y),
         otherwise it is less than 1/4+7/8 <= 2. */
      if (MPFR_EXP(y) + 2 >= MPFR_PREC(y)) /* ulp(y) >= 1/4 */
        err1 = 3;
      else /* ulp(y) <= 1/8 */
        err1 = (mpfr_exp_t) MPFR_PREC(y) - MPFR_EXP(y) + 1;
      ok = MPFR_CAN_ROUND (y, prec - err1, MPFR_PREC(res), r);
      if (ok)
        inex = mpfr_set (res, y, r);
      mpfr_clear (y);
      if (ok)
        goto end;
    }

  /* we can use the asymptotic expansion as soon as z > p log(2)/2,
     but to get some margin we use it for z > p/2 */
  if (mpfr_cmp_ui (z, MPFR_PREC(res) / 2 + 3) > 0)
    {
      inex = mpfr_yn_asympt (res, n, z, r);
      if (inex != 0)
        goto end;
    }

  /* General case */
  {
    mpfr_prec_t prec;
    mpfr_exp_t err1, err2, err3;
    mpfr_t y, s1, s2, s3;
    MPFR_ZIV_DECL (loop);

    mpfr_init (y);
    mpfr_init (s1);
    mpfr_init (s2);
    mpfr_init (s3);

    prec = MPFR_PREC(res) + 2 * MPFR_INT_CEIL_LOG2 (MPFR_PREC (res)) + 13;
    MPFR_ZIV_INIT (loop, prec);
    for (;;)
      {
        mpfr_set_prec (y, prec);
        mpfr_set_prec (s1, prec);
        mpfr_set_prec (s2, prec);
        mpfr_set_prec (s3, prec);

        mpfr_mul (y, z, z, MPFR_RNDN);
        mpfr_div_2ui (y, y, 2, MPFR_RNDN); /* z^2/4 */

        /* store (z/2)^n temporarily in s2 */
        mpfr_pow_ui (s2, z, absn, MPFR_RNDN);
        mpfr_div_2si (s2, s2, absn, MPFR_RNDN);

        /* compute S1 * (z/2)^(-n) */
        if (n == 0)
          {
            mpfr_set_ui (s1, 0, MPFR_RNDN);
            err1 = 0;
          }
        else
          err1 = mpfr_yn_s1 (s1, y, absn - 1);
        mpfr_div (s1, s1, s2, MPFR_RNDN); /* (z/2)^(-n) * S1 */
        /* See algorithms.tex: the relative error on s1 is bounded by
           (3n+3)*2^(e+1-prec). */
        err1 = MPFR_INT_CEIL_LOG2 (3 * absn + 3) + err1 + 1;
        /* rel_err(s1) <= 2^(err1-prec), thus err(s1) <= 2^err1 ulps */

        /* compute (z/2)^n * S3 */
        mpfr_neg (y, y, MPFR_RNDN); /* -z^2/4 */
        err3 = mpfr_yn_s3 (s3, y, s2, absn); /* (z/2)^n * S3 */
        /* the error on s3 is bounded by 2^err3 ulps */

        /* add s1+s3 */
        err1 += MPFR_EXP(s1);
        mpfr_add (s1, s1, s3, MPFR_RNDN);
        /* the error is bounded by 1/2 + 2^err1*2^(- EXP(s1))
           + 2^err3*2^(EXP(s3) - EXP(s1)) */
        err3 += MPFR_EXP(s3);
        err1 = (err3 > err1) ? err3 + 1 : err1 + 1;
        err1 -= MPFR_EXP(s1);
        err1 = (err1 >= 0) ? err1 + 1 : 1;
        /* now the error on s1 is bounded by 2^err1*ulp(s1) */

        /* compute S2 */
        mpfr_div_2ui (s2, z, 1, MPFR_RNDN); /* z/2 */
        mpfr_log (s2, s2, MPFR_RNDN); /* log(z/2) */
        mpfr_const_euler (s3, MPFR_RNDN);
        err2 = MPFR_EXP(s2) > MPFR_EXP(s3) ? MPFR_EXP(s2) : MPFR_EXP(s3);
        mpfr_add (s2, s2, s3, MPFR_RNDN); /* log(z/2) + gamma */
        err2 -= MPFR_EXP(s2);
        mpfr_mul_2ui (s2, s2, 1, MPFR_RNDN); /* 2*(log(z/2) + gamma) */
        mpfr_jn (s3, absn, z, MPFR_RNDN); /* Jn(z) */
        mpfr_mul (s2, s2, s3, MPFR_RNDN); /* 2*(log(z/2) + gamma)*Jn(z) */
        err2 += 4; /* the error on s2 is bounded by 2^err2 ulps, see
                      algorithms.tex */

        /* add all three sums */
        err1 += MPFR_EXP(s1); /* the error on s1 is bounded by 2^err1 */
        err2 += MPFR_EXP(s2); /* the error on s2 is bounded by 2^err2 */
        mpfr_sub (s2, s2, s1, MPFR_RNDN); /* s2 - (s1+s3) */
        err2 = (err1 > err2) ? err1 + 1 : err2 + 1;
        err2 -= MPFR_EXP(s2);
        err2 = (err2 >= 0) ? err2 + 1 : 1;
        /* now the error on s2 is bounded by 2^err2*ulp(s2) */
        mpfr_const_pi (y, MPFR_RNDN); /* error bounded by 1 ulp */
        mpfr_div (s2, s2, y, MPFR_RNDN); /* error bounded by
                                           2^(err2+1)*ulp(s2) */
        err2 ++;

        if (MPFR_LIKELY (MPFR_CAN_ROUND (s2, prec - err2, MPFR_PREC(res), r)))
          break;
        MPFR_ZIV_NEXT (loop, prec);
      }
    MPFR_ZIV_FREE (loop);

    /* Assume two's complement for the test n & 1 */
    inex = mpfr_set4 (res, s2, r, n >= 0 || (n & 1) == 0 ?
                      MPFR_SIGN (s2) : - MPFR_SIGN (s2));

    mpfr_clear (y);
    mpfr_clear (s1);
    mpfr_clear (s2);
    mpfr_clear (s3);
  }

 end:
  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (res, inex, r);
}
Esempio n. 17
0
File: tsqrt.c Progetto: epowers/mpfr
static void
special (void)
{
  mpfr_t x, y, z;
  int inexact;
  mpfr_prec_t p;

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

  mpfr_set_prec (x, 64);
  mpfr_set_str_binary (x, "1010000010100011011001010101010010001100001101011101110001011001E-1");
  mpfr_set_prec (y, 32);
  test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 2405743844UL))
    {
      printf ("Error for n^2+n+1/2 with n=2405743843\n");
      exit (1);
    }

  mpfr_set_prec (x, 65);
  mpfr_set_str_binary (x, "10100000101000110110010101010100100011000011010111011100010110001E-2");
  mpfr_set_prec (y, 32);
  test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 2405743844UL))
    {
      printf ("Error for n^2+n+1/4 with n=2405743843\n");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 66);
  mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100011E-3");
  mpfr_set_prec (y, 32);
  test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 2405743844UL))
    {
      printf ("Error for n^2+n+1/4+1/8 with n=2405743843\n");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 66);
  mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100001E-3");
  mpfr_set_prec (y, 32);
  test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 2405743843UL))
    {
      printf ("Error for n^2+n+1/8 with n=2405743843\n");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 27);
  mpfr_set_str_binary (x, "0.110100111010101000010001011");
  if ((inexact = test_sqrt (x, x, MPFR_RNDZ)) >= 0)
    {
      printf ("Wrong inexact flag: expected -1, got %d\n", inexact);
      exit (1);
    }

  mpfr_set_prec (x, 2);
  for (p=2; p<1000; p++)
    {
      mpfr_set_prec (z, p);
      mpfr_set_ui (z, 1, MPFR_RNDN);
      mpfr_nexttoinf (z);
      test_sqrt (x, z, MPFR_RNDU);
      if (mpfr_cmp_ui_2exp(x, 3, -1))
        {
          printf ("Error: sqrt(1+ulp(1), up) should give 1.5 (prec=%u)\n",
                  (unsigned int) p);
          printf ("got "); mpfr_print_binary (x); puts ("");
          exit (1);
        }
    }

  /* check inexact flag */
  mpfr_set_prec (x, 5);
  mpfr_set_str_binary (x, "1.1001E-2");
  if ((inexact = test_sqrt (x, x, MPFR_RNDN)))
    {
      printf ("Wrong inexact flag: expected 0, got %d\n", inexact);
      exit (1);
    }

  mpfr_set_prec (x, 2);
  mpfr_set_prec (z, 2);

  /* checks the sign is correctly set */
  mpfr_set_si (x, 1,  MPFR_RNDN);
  mpfr_set_si (z, -1, MPFR_RNDN);
  test_sqrt (z, x, MPFR_RNDN);
  if (mpfr_cmp_ui (z, 0) < 0)
    {
      printf ("Error: square root of 1 gives ");
      mpfr_print_binary(z);
      putchar('\n');
      exit (1);
    }

  mpfr_set_prec (x, 192);
  mpfr_set_prec (z, 160);
  mpfr_set_str_binary (z, "0.1011010100000100100100100110011001011100100100000011000111011001011101101101110000110100001000100001100001011000E1");
  mpfr_set_prec (x, 160);
  test_sqrt(x, z, MPFR_RNDN);
  test_sqrt(z, x, MPFR_RNDN);

  mpfr_set_prec (x, 53);
  mpfr_set_str (x, "8093416094703476.0", 10, MPFR_RNDN);
  mpfr_div_2exp (x, x, 1075, MPFR_RNDN);
  test_sqrt (x, x, MPFR_RNDN);
  mpfr_set_str (z, "1e55596835b5ef@-141", 16, MPFR_RNDN);
  if (mpfr_cmp (x, z))
    {
      printf ("Error: square root of 8093416094703476*2^(-1075)\n");
      printf ("expected "); mpfr_dump (z);
      printf ("got      "); mpfr_dump (x);
      exit (1);
    }

  mpfr_set_prec (x, 33);
  mpfr_set_str_binary (x, "0.111011011011110001100111111001000e-10");
  mpfr_set_prec (z, 157);
  inexact = test_sqrt (z, x, MPFR_RNDN);
  mpfr_set_prec (x, 157);
  mpfr_set_str_binary (x, "0.11110110101100101111001011100011100011100001101010111011010000100111011000111110100001001011110011111100101110010110010110011001011011010110010000011001101E-5");
  if (mpfr_cmp (x, z))
    {
      printf ("Error: square root (1)\n");
      exit (1);
    }
  if (inexact <= 0)
    {
      printf ("Error: wrong inexact flag (1)\n");
      exit (1);
    }

  /* case prec(result) << prec(input) */
  mpfr_set_prec (z, 2);
  for (p = 2; p < 1000; p++)
    {
      mpfr_set_prec (x, p);
      mpfr_set_ui (x, 1, MPFR_RNDN);
      mpfr_nextabove (x);
      /* 1.0 < x <= 1.5 thus 1 < sqrt(x) <= 1.23 */
      inexact = test_sqrt (z, x, MPFR_RNDN);
      MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
      inexact = test_sqrt (z, x, MPFR_RNDZ);
      MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
      inexact = test_sqrt (z, x, MPFR_RNDU);
      MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
      inexact = test_sqrt (z, x, MPFR_RNDD);
      MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
      inexact = test_sqrt (z, x, MPFR_RNDA);
      MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
    }

  /* corner case rw = 0 in rounding to nearest */
  mpfr_set_prec (z, GMP_NUMB_BITS - 1);
  mpfr_set_prec (y, GMP_NUMB_BITS - 1);
  mpfr_set_ui (y, 1, MPFR_RNDN);
  mpfr_mul_2exp (y, y, GMP_NUMB_BITS - 1, MPFR_RNDN);
  mpfr_nextabove (y);
  for (p = 2 * GMP_NUMB_BITS - 1; p <= 1000; p++)
    {
      mpfr_set_prec (x, p);
      mpfr_set_ui (x, 1, MPFR_RNDN);
      mpfr_set_exp (x, GMP_NUMB_BITS);
      mpfr_add_ui (x, x, 1, MPFR_RNDN);
      /* now x = 2^(GMP_NUMB_BITS - 1) + 1 (GMP_NUMB_BITS bits) */
      inexact = mpfr_mul (x, x, x, MPFR_RNDN);
      MPFR_ASSERTN (inexact == 0); /* exact */
      inexact = test_sqrt (z, x, MPFR_RNDN);
      /* even rule: z should be 2^(GMP_NUMB_BITS - 1) */
      MPFR_ASSERTN (inexact < 0);
      inexact = mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1);
      MPFR_ASSERTN (inexact == 0);
      mpfr_nextbelow (x);
      /* now x is just below [2^(GMP_NUMB_BITS - 1) + 1]^2 */
      inexact = test_sqrt (z, x, MPFR_RNDN);
      MPFR_ASSERTN(inexact < 0 &&
                   mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0);
      mpfr_nextabove (x);
      mpfr_nextabove (x);
      /* now x is just above [2^(GMP_NUMB_BITS - 1) + 1]^2 */
      inexact = test_sqrt (z, x, MPFR_RNDN);
      if (mpfr_cmp (z, y))
        {
          printf ("Error for sqrt(x) in rounding to nearest\n");
          printf ("x="); mpfr_dump (x);
          printf ("Expected "); mpfr_dump (y);
          printf ("Got      "); mpfr_dump (z);
          exit (1);
        }
      if (inexact <= 0)
        {
          printf ("Wrong inexact flag in corner case for p = %lu\n", (unsigned long) p);
          exit (1);
        }
    }

  mpfr_set_prec (x, 1000);
  mpfr_set_ui (x, 9, MPFR_RNDN);
  mpfr_set_prec (y, 10);
  inexact = test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 3) || inexact != 0)
    {
      printf ("Error in sqrt(9:1000) for prec=10\n");
      exit (1);
    }
  mpfr_set_prec (y, GMP_NUMB_BITS);
  mpfr_nextabove (x);
  inexact = test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 3) || inexact >= 0)
    {
      printf ("Error in sqrt(9:1000) for prec=%d\n", (int) GMP_NUMB_BITS);
      exit (1);
    }
  mpfr_set_prec (x, 2 * GMP_NUMB_BITS);
  mpfr_set_prec (y, GMP_NUMB_BITS);
  mpfr_set_ui (y, 1, MPFR_RNDN);
  mpfr_nextabove (y);
  mpfr_set (x, y, MPFR_RNDN);
  inexact = test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 1) || inexact >= 0)
    {
      printf ("Error in sqrt(1) for prec=%d\n", (int) GMP_NUMB_BITS);
      mpfr_dump (y);
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Esempio n. 18
0
File: terf.c Progetto: epowers/mpfr
static void
special_erf (void)
{
  mpfr_t x, y;
  int inex;

  mpfr_init2 (x, 53);
  mpfr_init2 (y, 53);

  /* erf(NaN) = NaN */
  mpfr_set_nan (x);
  mpfr_erf (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("mpfr_erf failed for x=NaN\n");
      exit (1);
    }

  /* erf(+Inf) = 1 */
  mpfr_set_inf (x, 1);
  mpfr_erf (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 1))
    {
      printf ("mpfr_erf failed for x=+Inf\n");
      printf ("expected 1.0, got ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  /* erf(-Inf) = -1 */
  mpfr_set_inf (x, -1);
  mpfr_erf (y, x, MPFR_RNDN);
  if (mpfr_cmp_si (y, -1))
    {
      printf ("mpfr_erf failed for x=-Inf\n");
      exit (1);
    }

  /* erf(+0) = +0 */
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_erf (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
      printf ("mpfr_erf failed for x=+0\n");
      exit (1);
    }

  /* erf(-0) = -0 */
  mpfr_neg (x, x, MPFR_RNDN);
  mpfr_erf (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
    {
      printf ("mpfr_erf failed for x=-0\n");
      exit (1);
    }

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_erf (x, x, MPFR_RNDN);
  mpfr_set_str_binary (y, "0.11010111101110110011110100111010000010000100010001011");
  if (mpfr_cmp (x, y))
    {
      printf ("mpfr_erf failed for x=1.0, rnd=MPFR_RNDN\n");
      printf ("expected ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\n");
      printf ("got      ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_str (x, "6.6", 10, MPFR_RNDN);
  mpfr_erf (x, x, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("mpfr_erf failed for x=6.6, rnd=MPFR_RNDN\n");
      printf ("expected 1\n");
      printf ("got      ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_str (x, "-6.6", 10, MPFR_RNDN);
  mpfr_erf (x, x, MPFR_RNDN);
  if (mpfr_cmp_si (x, -1))
    {
      printf ("mpfr_erf failed for x=-6.6, rnd=MPFR_RNDN\n");
      printf ("expected -1\n");
      printf ("got      ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_str (x, "6.6", 10, MPFR_RNDN);
  mpfr_erf (x, x, MPFR_RNDZ);
  mpfr_set_str_binary (y, "0.11111111111111111111111111111111111111111111111111111");
  if (mpfr_cmp (x, y))
    {
      printf ("mpfr_erf failed for x=6.6, rnd=MPFR_RNDZ\n");
      printf ("expected ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\n");
      printf ("got      ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_str (x, "4.5", 10, MPFR_RNDN);
  mpfr_erf (x, x, MPFR_RNDN);
  mpfr_set_str_binary (y, "0.1111111111111111111111111111111100100111110100011");
  if (mpfr_cmp (x, y))
    {
      printf ("mpfr_erf failed for x=4.5, rnd=MPFR_RNDN\n");
      printf ("expected ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\n");
      printf ("got      ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_prec (x, 120);
  mpfr_set_prec (y, 120);
  mpfr_set_str_binary (x, "0.110100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011E3");
  mpfr_erf (x, x, MPFR_RNDN);
  mpfr_set_str_binary (y, "0.11111111111111111111111111111111111111111111111111111111111111111100111111000100111011111011010000110101111100011001101");
  if (mpfr_cmp (x, y))
    {
      printf ("mpfr_erf failed for x=6.6, rnd=MPFR_RNDN\n");
      printf ("expected ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\n");
      printf ("got      ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_prec (x, 8);
  mpfr_set_prec (y, 8);
  mpfr_set_ui (x, 50, MPFR_RNDN);
  inex = mpfr_erf (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 1))
    {
      printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDN\n");
      printf ("expected 1, got ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }
  if (inex <= 0)
    {
      printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDN: wrong ternary value\n"
              "expected positive, got %d\n", inex);
      exit (1);
    }
  inex = mpfr_erf (x, x, MPFR_RNDZ);
  mpfr_nextbelow (y);
  if (mpfr_cmp (x, y))
    {
      printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDZ\n");
      printf ("expected ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\n");
      printf ("got      ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }
  if (inex >= 0)
    {
      printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDN: wrong ternary value\n"
              "expected negative, got %d\n", inex);
      exit (1);
    }

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 32);

  mpfr_set_str_binary (x, "0.1010100100111011001111100101E-1");
  mpfr_set_str_binary (y, "0.10111000001110011010110001101011E-1");
  mpfr_erf (x, x, MPFR_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for prec=32 (1)\n");
      exit (1);
    }

  mpfr_set_str_binary (x, "-0.10110011011010111110010001100001");
  mpfr_set_str_binary (y, "-0.1010110110101011100010111000111");
  mpfr_erf (x, x, MPFR_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for prec=32 (2)\n");
      mpfr_print_binary (x); printf ("\n");
      exit (1);
    }

  mpfr_set_str_binary (x, "100.10001110011110100000110000111");
  mpfr_set_str_binary (y, "0.11111111111111111111111111111111");
  mpfr_erf (x, x, MPFR_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for prec=32 (3)\n");
      exit (1);
    }
  mpfr_set_str_binary (x, "100.10001110011110100000110000111");
  mpfr_erf (x, x, MPFR_RNDZ);
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for prec=32 (4)\n");
      exit (1);
    }
  mpfr_set_str_binary (x, "100.10001110011110100000110000111");
  mpfr_erf (x, x, MPFR_RNDU);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error: erf for prec=32 (5)\n");
      exit (1);
    }

  mpfr_set_str_binary (x, "100.10001110011110100000110001000");
  mpfr_erf (x, x, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error: erf for prec=32 (6)\n");
      exit (1);
    }
  mpfr_set_str_binary (x, "100.10001110011110100000110001000");
  mpfr_set_str_binary (y, "0.11111111111111111111111111111111");
  mpfr_erf (x, x, MPFR_RNDZ);
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for prec=32 (7)\n");
      exit (1);
    }
  mpfr_set_str_binary (x, "100.10001110011110100000110001000");
  mpfr_erf (x, x, MPFR_RNDU);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error: erf for prec=32 (8)\n");
      exit (1);
    }

  mpfr_set_ui (x, 5, MPFR_RNDN);
  mpfr_erf (x, x, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error: erf for prec=32 (9)\n");
      exit (1);
    }
  mpfr_set_ui (x, 5, MPFR_RNDN);
  mpfr_erf (x, x, MPFR_RNDU);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error: erf for prec=32 (10)\n");
      exit (1);
    }
  mpfr_set_ui (x, 5, MPFR_RNDN);
  mpfr_erf (x, x, MPFR_RNDZ);
  mpfr_set_str_binary (y, "0.11111111111111111111111111111111");
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for prec=32 (11)\n");
      exit (1);
    }
  mpfr_set_ui (x, 5, MPFR_RNDN);
  mpfr_erf (x, x, MPFR_RNDD);
  mpfr_set_str_binary (y, "0.11111111111111111111111111111111");
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for prec=32 (12)\n");
      exit (1);
    }

  mpfr_set_prec (x, 43);
  mpfr_set_prec (y, 64);
  mpfr_set_str_binary (x, "-0.1101110110101111100101011101110101101001001e3");
  mpfr_erf (y, x, MPFR_RNDU);
  mpfr_set_prec (x, 64);
  mpfr_set_str_binary (x, "-0.1111111111111111111111111111111111111111111111111111111111111111");
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for prec=43,64 (13)\n");
      exit (1);
    }

  /* worst cases */
  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);
  mpfr_set_str_binary (x, "1.0000000000000000000000000000000000000110000000101101");
  mpfr_erf (y, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.110101111011101100111101001110100000101011000011001");
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for worst case (1)\n");
      exit (1);
    }

  mpfr_set_str_binary (x, "1.0000000000000000000000000000011000111010101101011010");
  mpfr_erf (y, x, MPFR_RNDU);
  mpfr_set_str_binary (x, "0.11010111101110110011110100111100100111100011111000110");
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for worst case (2a)\n");
      exit (1);
    }
  mpfr_set_str_binary (x, "1.0000000000000000000000000000011000111010101101011010");
  mpfr_erf (y, x, MPFR_RNDD);
  mpfr_set_str_binary (x, "0.11010111101110110011110100111100100111100011111000101");
  if (mpfr_cmp (x, y))
    {
      printf ("Error: erf for worst case (2b)\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
Esempio n. 19
0
static void
check_small (void)
{
  mpfr_t x;
  char *s;
  mpfr_exp_t e;
  mpfr_prec_t p;

  mpfr_init (x);

  mpfr_set_prec (x, 20);
  mpfr_set_ui (x, 2, MPFR_RNDN);
  mpfr_nexttozero (x);
  s = mpfr_get_str (NULL, &e, 4, 2, x, MPFR_RNDU);
  if (strcmp (s, "20") || (e != 1))
    {
      printf ("Error in mpfr_get_str: 2- rounded up with 2 digits"
              " in base 4\n");
      exit (1);
    }
  mpfr_free_str (s);

  /* check n_digits=0 */
  mpfr_set_prec (x, 5);
  mpfr_set_ui (x, 17, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 3, 0, x, MPFR_RNDN);
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 36, 0, x, MPFR_RNDN);
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 62, 0, x, MPFR_RNDN);
  mpfr_free_str (s);

  mpfr_set_prec (x, 64);
  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_div_2exp (x, x, 63, MPFR_RNDN); /* x = -2^(-63) */
  mpfr_add_ui (x, x, 1, MPFR_RNDN); /* x = 1 - 2^(-63) */
  mpfr_mul_2exp (x, x, 32, MPFR_RNDN); /* x = 2^32 - 2^(-31) */
  s = mpfr_get_str (NULL, &e, 3, 21, x, MPFR_RNDU);
  if (strcmp (s, "102002022201221111211") || (e != 21))
    {
      printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with"
              " 21 digits in base 3\n");
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 3, 20, x, MPFR_RNDU);
  if (strcmp (s, "10200202220122111122") || (e != 21))
    {
      printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with"
              " 20 digits in base 3\n");
      exit (1);
    }
  mpfr_free_str (s);

  /* check corner case ret!=0, j0!=0 in mpfr_get_str_aux */
  mpfr_set_prec (x, 100);
  mpfr_set_str_binary (x, "0.1001011111010001101110010101010101111001010111111101101101100110100011110110000101110110001011110000E-9");
  s = mpfr_get_str (NULL, &e, 3, 2, x, MPFR_RNDU);
  if (strcmp (s, "22") || (e != -6))
    {
      printf ("Error in mpfr_get_str: 100-bit number rounded up with"
              " 2 digits in base 3\n");
      exit (1);
    }
  mpfr_free_str (s);

  /* check corner case exact=0 in mpfr_get_str_aux */
  mpfr_set_prec (x, 100);
  mpfr_set_str_binary (x, "0.1001001111101101111000101000110111111010101100000110010001111111011001101011101100001100110000000000E8");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDZ);
  if (strcmp (s, "14") || (e != 3))
    {
      printf ("Error in mpfr_get_str: 100-bit number rounded to zero with"
              " 2 digits in base 10\n");
      exit (1);
    }
  mpfr_free_str (s);

  for (p=4; p<=200; p++)
    {
      mpfr_set_prec (x, p);
      mpfr_set_str (x, "6.5", 10, MPFR_RNDN);

      s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN);
      if (strcmp (s, "10") || (e != 2))
        {
          printf ("Error in mpfr_get_str: 6.5 rounded to nearest with"
                  " 2 digits in base 6\n");
          exit (1);
        }
      mpfr_free_str (s);

      mpfr_nexttoinf (x);
      s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN);
      if (strcmp (s, "11") || (e != 2))
        {
          printf ("Error in mpfr_get_str: 6.5+ rounded to nearest with"
                  " 2 digits in base 6\ngot %se%d instead of 11e2\n",
                  s, (int) e);
          exit (1);
        }
      mpfr_free_str (s);

      mpfr_set_str (x, "6.5", 10, MPFR_RNDN);
      mpfr_nexttozero (x);
      s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN);
      if (strcmp (s, "10") || (e != 2))
        {
          printf ("Error in mpfr_get_str: 6.5- rounded to nearest with"
                  " 2 digits in base 6\n");
          exit (1);
        }
      mpfr_free_str (s);
    }

  mpfr_set_prec (x, 3);
  mpfr_set_ui (x, 7, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 2, 2, x, MPFR_RNDU);
  if (strcmp (s, "10") || (e != 4))
    {
      printf ("Error in mpfr_get_str: 7 rounded up with 2 bits should"
              " give 0.10e3 instead of 0.%s*2^%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* problem found by Fabrice Rouillier */
  mpfr_set_prec (x, 63);
  mpfr_set_str (x, "5e14", 10, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU);
  mpfr_free_str (s);

  /* bug found by Johan Vervloet */
  mpfr_set_prec (x, 6);
  mpfr_set_str (x, "688.0", 10, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 2, 4, x, MPFR_RNDU);
  if (strcmp (s, "1011") || (e != 10))
    {
      printf ("Error in mpfr_get_str: 688 printed up to 4 bits should"
              " give 1.011e9\ninstead of ");
      mpfr_out_str (stdout, 2, 4, x, MPFR_RNDU);
      puts ("");
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 38);
  mpfr_set_str_binary (x, "1.0001110111110100011010100010010100110e-6");
  s = mpfr_get_str (NULL, &e, 8, 10, x, MPFR_RNDU);
  if (strcmp (s, "1073721522") || (e != -1))
    {
      printf ("Error in mpfr_get_str (3): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 53);
  mpfr_set_str_binary (x, "0.11010111011101100010000100010101110001000000010111001E454");
  s = mpfr_get_str (NULL, &e, 19, 12, x, MPFR_RNDU);
  if (strcmp (s, "b1cgfa4gha0h") || (e != 107))
    {
      printf ("Error in mpfr_get_str (4): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 145);
  mpfr_set_str_binary (x, "-0.1000110011000001011000010101101010110110101100101110100011111100011110011001001001010000100001000011000011000000010111011001000111101001110100110e6");
  s = mpfr_get_str (NULL, &e, 4, 53, x, MPFR_RNDU);
  if (strcmp (s, "-20303001120111222312230232203330132121021100201003003") || (e != 3))
    {
      printf ("Error in mpfr_get_str (5): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 45);
  mpfr_set_str_binary (x, "-0.00100111010110010001011001110111010001010010010");
  s = mpfr_get_str (NULL, &e, 32, 9, x, MPFR_RNDN);
  if (strcmp (s, "-4tchctq54") || (e != 0))
    {
      printf ("Error in mpfr_get_str (6): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* worst case found by Vincent Lefe`vre */
  mpfr_set_prec (x, 53);
  mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E164");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "13076622631878654") || (e != 66))
    {
      printf ("Error in mpfr_get_str (7): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10000001001001001100011101010011011011111000011000100E93");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
  if (strcmp (s, "46") || e != 44)
    {
       printf ("Error in mpfr_get_str (8): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10010001111100000111001111010101001010000010111010101E55");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN);
  if (strcmp (s, "19") || e != 33)
    {
       printf ("Error in mpfr_get_str (9): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11011001010010111110010101101100111110111000010110110E44");
  s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDN);
  if (strcmp (s, "135") || e != 30)
    {
       printf ("Error in mpfr_get_str (10): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11101111101000001011100001111000011111101111011001100E72");
  s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDN);
  if (strcmp (s, "3981") || e != 38)
    {
       printf ("Error in mpfr_get_str (11): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011001001100100010111100001101110101001001111110000E46");
  s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDN);
  if (strcmp (s, "37930") || e != 30)
    {
       printf ("Error in mpfr_get_str (12): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10001100110111001011011110011011011101100011010001011E-72");
  s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDN);
  if (strcmp (s, "104950") || e != -5)
    {
       printf ("Error in mpfr_get_str (13): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10100100001011001000011001101101000110100110000010111E89");
  s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDN);
  if (strcmp (s, "3575392") || e != 43)
    {
       printf ("Error in mpfr_get_str (14): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "11000011011110110010100110001010000001010011001011001E-73");
  s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDN);
  if (strcmp (s, "72822386") || e != -6)
    {
       printf ("Error in mpfr_get_str (15): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10101010001101000111001100001000100011100010010001010E78");
  s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDN);
  if (strcmp (s, "180992873") || e != 40)
    {
      printf ("Error in mpfr_get_str (16): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10110111001000100000001101111001100101101110011011101E91");
  s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDN);
  if (strcmp (s, "1595312255") || e != 44)
    {
      printf ("Error in mpfr_get_str (17): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E93");
  s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDN);
  if (strcmp (s, "54835744350") || e != 44)
    {
      printf ("Error in mpfr_get_str (18): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E92");
  s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDN);
  if (strcmp (s, "274178721752") || e != 44)
    {
      printf ("Error in mpfr_get_str (19): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E91");
  s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDN);
  if (strcmp (s, "1370893608762") || e != 44)
    {
      printf ("Error in mpfr_get_str (20): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10010011010110011100010010100101100011101000011111111E92");
  s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDN);
  if (strcmp (s, "25672105101864") || e != 44)
    {
      printf ("Error in mpfr_get_str (21): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "100110111110110001000101110100100101101000011111001E87");
  s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDN);
  if (strcmp (s, "212231308858721") || e != 42)
    {
      printf ("Error in mpfr_get_str (22): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10111010110000111000101100101111001011011100101001111E-128");
  s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDN);
  if (strcmp (s, "193109287087290") || e != -22)
    {
      printf ("Error in mpfr_get_str (22b): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10001101101011010001111110000111010111010000110101010E80");
  s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDN);
  if (strcmp (s, "6026241735727920") || e != 40)
    {
      printf ("Error in mpfr_get_str (23): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "100010001011101001110101000110011001001000110001001E-81");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "49741483709103481") || e != -9)
    {
      printf ("Error in mpfr_get_str (24): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11000100001001001110111010011001111001001010110101111E-101");
  s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDN);
  if (strcmp (s, "2722049") || e != -14)
    {
      printf ("Error in mpfr_get_str (25): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-135");
  s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDN);
  if (strcmp (s, "20138772") || e != -24)
    {
      printf ("Error in mpfr_get_str (26): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-136");
  s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDN);
  if (strcmp (s, "100693858") || e != -24)
    {
      printf ("Error in mpfr_get_str (27): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
    mpfr_free_str (s);
  mpfr_set_str_binary (x, "10001000001110010110001011111011111011011010000110001E-110");
  s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDN);
  if (strcmp (s, "36923634350619") || e != -17)
    {
      printf ("Error in mpfr_get_str (28): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11001100010111000111100010000110011101110001000101111E-87");
  s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDN);
  if (strcmp (s, "4646636036100804") || e != -10)
    {
      printf ("Error in mpfr_get_str (29): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011111001111110100001001010111111011010101111111000E-99");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "88399901882446712") || e != -14)
    {
      printf ("Error in mpfr_get_str (30): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 8116315218207718*2^(-293) ~ 0.5100000000000000000015*10^(-72) */
  mpfr_set_str_binary (x, "11100110101011011111011100101011101110110001111100110E-293");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
  if (strcmp (s, "52") || e != -72)
    {
      printf ("Error in mpfr_get_str (31u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDD);
  if (strcmp (s, "51") || e != -72)
    {
      printf ("Error in mpfr_get_str (31d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 6712731423444934*2^536 ~ .151000000000000000000067*10^178 */
  mpfr_set_str_binary (x, "10111110110010011000110010011111101111000111111000110E536");
  s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDU);
  if (strcmp (s, "152") || e != 178)
    {
      printf ("Error in mpfr_get_str (32u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDD);
  if (strcmp (s, "151") || e != 178)
    {
      printf ("Error in mpfr_get_str (32d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 3356365711722467*2^540 ~ .120800000000000000000054*10^179 */
  mpfr_set_str_binary (x, "1011111011001001100011001001111110111100011111100011E540");
  s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDU);
  if (strcmp (s, "1209") || e != 179)
    {
      printf ("Error in mpfr_get_str (33u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDD);
  if (strcmp (s, "1208") || e != 179)
    {
      printf ("Error in mpfr_get_str (33d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 6475049196144587*2^100 ~ .8208099999999999999999988*10^46 */
  mpfr_set_str_binary (x, "10111000000010000010111011111001111010100011111001011E100");
  s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDU);
  if (strcmp (s, "82081") || e != 46)
    {
      printf ("Error in mpfr_get_str (34u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDD);
  if (strcmp (s, "82080") || e != 46)
    {
      printf ("Error in mpfr_get_str (34d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 6722280709661868*2^364 ~ .25260100000000000000000012*10^126 */
  mpfr_set_str_binary (x, "10111111000011110000011110001110001111010010010101100E364");
  s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDU);
  if (strcmp (s, "252602") || e != 126)
    {
      printf ("Error in mpfr_get_str (35u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDD);
  if (strcmp (s, "252601") || e != 126)
    {
      printf ("Error in mpfr_get_str (35d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 5381065484265332*2^(-455) ~ .578389299999999999999999982*10^(-121) */
  mpfr_set_str_binary (x, "10011000111100000110011110000101100111110011101110100E-455");
  s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDU);
  if (strcmp (s, "5783893") || e != -121)
    {
      printf ("Error in mpfr_get_str (36u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDD);
  if (strcmp (s, "5783892") || e != -121)
    {
      printf ("Error in mpfr_get_str (36d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 8369123604277281*2^(-852) ~ .27869147000000000000000000056*10^(-240) */
  mpfr_set_str_binary (x, "11101101110111010110001101111100000111010100000100001E-852");
  s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDU);
  if (strcmp (s, "27869148") || e != -240)
    {
      printf ("Error in mpfr_get_str (37u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDD);
  if (strcmp (s, "27869147") || e != -240)
    {
      printf ("Error in mpfr_get_str (37d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 7976538478610756*2^377 ~ .245540326999999999999999999982*10^130 */
  mpfr_set_str_binary (x, "11100010101101001111010010110100011100000100101000100E377");
  s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDU);
  if (strcmp (s, "245540327") || e != 130)
    {
      printf ("Error in mpfr_get_str (38u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDD);
  if (strcmp (s, "245540326") || e != 130)
    {
      printf ("Error in mpfr_get_str (38d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 8942832835564782*2^(-382) ~ .9078555839000000000000000000038*10^(-99) */
  mpfr_set_str_binary (x, "11111110001010111010110000110011100110001010011101110E-382");
  s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDU);
  if (strcmp (s, "9078555840") || e != -99)
    {
      printf ("Error in mpfr_get_str (39u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDD);
  if (strcmp (s, "9078555839") || e != -99)
    {
      printf ("Error in mpfr_get_str (39d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 4471416417782391*2^(-380) ~ .18157111678000000000000000000077*10^(-98) */
  mpfr_set_str_binary (x, "1111111000101011101011000011001110011000101001110111E-380");
  s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDU);
  if (strcmp (s, "18157111679") || e != -98)
    {
      printf ("Error in mpfr_get_str (40u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDD);
  if (strcmp (s, "18157111678") || e != -98)
    {
      printf ("Error in mpfr_get_str (40d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 7225450889282194*2^711 ~ .778380362292999999999999999999971*10^230 */
  mpfr_set_str_binary (x, "11001101010111000001001100001100110010000001010010010E711");
  s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDU);
  if (strcmp (s, "778380362293") || e != 230)
    {
      printf ("Error in mpfr_get_str (41u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDD);
  if (strcmp (s, "778380362292") || e != 230)
    {
      printf ("Error in mpfr_get_str (41d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 3612725444641097*2^713 ~ .1556760724585999999999999999999942*10^231 */
  mpfr_set_str_binary (x, "1100110101011100000100110000110011001000000101001001E713");
  s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDU);
  if (strcmp (s, "1556760724586") || e != 231)
    {
      printf ("Error in mpfr_get_str (42u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDD);
  if (strcmp (s, "1556760724585") || e != 231)
    {
      printf ("Error in mpfr_get_str (42d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 6965949469487146*2^(-248) ~ .15400733123779000000000000000000016*10^(-58) */
  mpfr_set_str_binary (x, "11000101111110111111001111111101001101111000000101010E-248");
  s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDU);
  if (strcmp (s, "15400733123780") || e != -58)
    {
      printf ("Error in mpfr_get_str (43u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDD);
  if (strcmp (s, "15400733123779") || e != -58)
    {
      printf ("Error in mpfr_get_str (43d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 3482974734743573*2^(-244) ~ .12320586499023200000000000000000013*10^(-57) */
  mpfr_set_str_binary (x, "1100010111111011111100111111110100110111100000010101E-244");
  s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDU);
  if (strcmp (s, "123205864990233") || e != -57)
    {
      printf ("Error in mpfr_get_str (44u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDD);
  if (strcmp (s, "123205864990232") || e != -57)
    {
      printf ("Error in mpfr_get_str (44d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 7542952370752766*2^(-919) ~ .170206189963739699999999999999999974*10^(-260) */
  mpfr_set_str_binary (x, "11010110011000100011001110100100111011100110011111110E-919");
  s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDU);
  if (strcmp (s, "1702061899637397") || e != -260)
    {
      printf ("Error in mpfr_get_str (45u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDD);
  if (strcmp (s, "1702061899637396") || e != -260)
    {
      printf ("Error in mpfr_get_str (45d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 5592117679628511*2^165 ~ .26153245263757307000000000000000000074*10^66 */
  mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E165");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDU);
  if (strcmp (s, "26153245263757308") || e != 66)
    {
      printf ("Error in mpfr_get_str (46u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDD);
  if (strcmp (s, "26153245263757307") || e != 66)
    {
      printf ("Error in mpfr_get_str (46d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "11010010110111100001011010000110010000100001011011101E1223");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "10716284017294180") || e != 385)
    {
      printf ("Error in mpfr_get_str (47n): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU);
  if (strcmp (s, "107162840172941805") || e != 385)
    {
      printf ("Error in mpfr_get_str (47u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDD);
  if (strcmp (s, "107162840172941804") || e != 385)
    {
      printf ("Error in mpfr_get_str (47d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "11111101111011000001010100001101101000010010001111E122620");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "22183435284042374") || e != 36928)
    {
      printf ("Error in mpfr_get_str (48n): s=%s e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU);
  if (strcmp (s, "221834352840423736") || e != 36928)
    {
      printf ("Error in mpfr_get_str (48u): s=%s e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDD);
  if (strcmp (s, "221834352840423735") || e != 36928)
    {
      printf ("Error in mpfr_get_str (48d): s=%s e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 45);
  mpfr_set_str_binary (x, "1E45");
  s = mpfr_get_str (NULL, &e, 32, 9, x, MPFR_RNDN);
  mpfr_free_str (s);

  mpfr_set_prec (x, 7);
  mpfr_set_str_binary (x, "0.1010101E10");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
  mpfr_free_str (s);

  /* checks rounding of negative numbers */
  mpfr_set_prec (x, 7);
  mpfr_set_str (x, "-11.5", 10, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDD);
  if (strcmp (s, "-12"))
    {
      printf ("Error in mpfr_get_str for x=-11.5 and rnd=MPFR_RNDD\n"
              "got %s instead of -12\n", s);
      exit (1);
  }
  mpfr_free_str (s);

  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
  if (strcmp (s, "-11"))
    {
      printf ("Error in mpfr_get_str for x=-11.5 and rnd=MPFR_RNDU\n");
      exit (1);
    }
  mpfr_free_str (s);

  /* bug found by Jean-Pierre Merlet, produced error in mpfr_get_str */
  mpfr_set_prec (x, 128);
  mpfr_set_str_binary (x, "0.10111001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011010E3");
  s = mpfr_get_str (NULL, &e, 10, 0, x, MPFR_RNDU);
  mpfr_free_str (s);

  mpfr_set_prec (x, 381);
  mpfr_set_str_binary (x, "0.111111111111111111111111111111111111111111111111111111111111111111101110110000100110011101101101001010111000101111000100100011110101010110101110100000010100001000110100000100011111001000010010000010001010111001011110000001110010111101100001111000101101100000010110000101100100000101010110010110001010100111001111100011100101100000100100111001100010010011110011011010110000001000010");
  s = mpfr_get_str (NULL, &e, 10, 0, x, MPFR_RNDD);
  if (e != 0)
    {
      printf ("Error in mpfr_get_str for x=0.999999..., exponent is %d"
              " instead of 0\n", (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 5);
  mpfr_set_str_binary (x, "1101.1"); /* 13.5, or (16)_7 + 1/2 */
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  /* we are in the tie case: both surrounding numbers are (16)_7 and
     (20)_7: since (16)_7 = 13 is odd and (20)_7 = 14 is even,
     we should have s = "20" and e = 2 */
  if (e != 2 || strcmp (s, "20"))
    {
      printf ("Error in mpfr_get_str for x=13.5, base 7\n");
      printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  /* try the same example, with input just below or above 13.5 */
  mpfr_set_prec (x, 1000);
  mpfr_set_str_binary (x, "1101.1");
  mpfr_nextabove (x);
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  if (e != 2 || strcmp (s, "20"))
    {
      printf ("Error in mpfr_get_str for x=13.5+tiny, base 7\n");
      printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "1101.1");
  mpfr_nextbelow (x);
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  if (e != 2 || strcmp (s, "16"))
    {
      printf ("Error in mpfr_get_str for x=13.5-tiny, base 7\n");
      printf ("Expected s=16, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 7);
  mpfr_set_str_binary (x, "110000.1"); /* 48.5, or (66)_7 + 1/2 */
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  /* we are in the tie case: both surrounding numbers are (66)_7 and
     (100)_7: since (66)_7 = 48 is even and (100)_7 is odd,
     we should hase s = "66" and e = 2 */
  if (e != 2 || strcmp (s, "66"))
    {
      printf ("Error in mpfr_get_str for x=48.5, base 7\n");
      printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  /* try the same example, with input just below or above 48.5 */
  mpfr_set_prec (x, 1000);
  mpfr_set_str_binary (x, "110000.1");
  mpfr_nextabove (x);
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  if (e != 3 || strcmp (s, "10"))
    {
      printf ("Error in mpfr_get_str for x=48.5+tiny, base 7\n");
      printf ("Expected s=10, e=3, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "110000.1");
  mpfr_nextbelow (x);
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  if (e != 2 || strcmp (s, "66"))
    {
      printf ("Error in mpfr_get_str for x=48.5-tiny, base 7\n");
      printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_clear (x);
}
Esempio n. 20
0
int
mpc_atan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
{
    int s_re;
    int s_im;
    int inex_re;
    int inex_im;
    int inex;

    inex_re = 0;
    inex_im = 0;
    s_re = mpfr_signbit (mpc_realref (op));
    s_im = mpfr_signbit (mpc_imagref (op));

    /* special values */
    if (mpfr_nan_p (mpc_realref (op)) || mpfr_nan_p (mpc_imagref (op)))
    {
        if (mpfr_nan_p (mpc_realref (op)))
        {
            mpfr_set_nan (mpc_realref (rop));
            if (mpfr_zero_p (mpc_imagref (op)) || mpfr_inf_p (mpc_imagref (op)))
            {
                mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
                if (s_im)
                    mpc_conj (rop, rop, MPC_RNDNN);
            }
            else
                mpfr_set_nan (mpc_imagref (rop));
        }
        else
        {
            if (mpfr_inf_p (mpc_realref (op)))
            {
                inex_re = set_pi_over_2 (mpc_realref (rop), -s_re, MPC_RND_RE (rnd));
                mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
            }
            else
            {
                mpfr_set_nan (mpc_realref (rop));
                mpfr_set_nan (mpc_imagref (rop));
            }
        }
        return MPC_INEX (inex_re, 0);
    }

    if (mpfr_inf_p (mpc_realref (op)) || mpfr_inf_p (mpc_imagref (op)))
    {
        inex_re = set_pi_over_2 (mpc_realref (rop), -s_re, MPC_RND_RE (rnd));

        mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
        if (s_im)
            mpc_conj (rop, rop, GMP_RNDN);

        return MPC_INEX (inex_re, 0);
    }

    /* pure real argument */
    if (mpfr_zero_p (mpc_imagref (op)))
    {
        inex_re = mpfr_atan (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd));

        mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
        if (s_im)
            mpc_conj (rop, rop, GMP_RNDN);

        return MPC_INEX (inex_re, 0);
    }

    /* pure imaginary argument */
    if (mpfr_zero_p (mpc_realref (op)))
    {
        int cmp_1;

        if (s_im)
            cmp_1 = -mpfr_cmp_si (mpc_imagref (op), -1);
        else
            cmp_1 = mpfr_cmp_ui (mpc_imagref (op), +1);

        if (cmp_1 < 0)
        {
            /* atan(+0+iy) = +0 +i*atanh(y), if |y| < 1
               atan(-0+iy) = -0 +i*atanh(y), if |y| < 1 */

            mpfr_set_ui (mpc_realref (rop), 0, GMP_RNDN);
            if (s_re)
                mpfr_neg (mpc_realref (rop), mpc_realref (rop), GMP_RNDN);

            inex_im = mpfr_atanh (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd));
        }
        else if (cmp_1 == 0)
        {
            /* atan(+/-0+i) = NaN +i*inf
               atan(+/-0-i) = NaN -i*inf */
            mpfr_set_nan (mpc_realref (rop));
            mpfr_set_inf (mpc_imagref (rop), s_im ? -1 : +1);
        }
        else
        {
            /* atan(+0+iy) = +pi/2 +i*atanh(1/y), if |y| > 1
               atan(-0+iy) = -pi/2 +i*atanh(1/y), if |y| > 1 */
            mpfr_rnd_t rnd_im, rnd_away;
            mpfr_t y;
            mpfr_prec_t p, p_im;
            int ok;

            rnd_im = MPC_RND_IM (rnd);
            mpfr_init (y);
            p_im = mpfr_get_prec (mpc_imagref (rop));
            p = p_im;

            /* a = o(1/y)      with error(a) < 1 ulp(a)
               b = o(atanh(a)) with error(b) < (1+2^{1+Exp(a)-Exp(b)}) ulp(b)

               As |atanh (1/y)| > |1/y| we have Exp(a)-Exp(b) <=0 so, at most,
               2 bits of precision are lost.

               We round atanh(1/y) away from 0.
            */
            do
            {
                p += mpc_ceil_log2 (p) + 2;
                mpfr_set_prec (y, p);
                rnd_away = s_im == 0 ? GMP_RNDU : GMP_RNDD;
                inex_im = mpfr_ui_div (y, 1, mpc_imagref (op), rnd_away);
                /* FIXME: should we consider the case with unreasonably huge
                   precision prec(y)>3*exp_min, where atanh(1/Im(op)) could be
                   representable while 1/Im(op) underflows ?
                   This corresponds to |y| = 0.5*2^emin, in which case the
                   result may be wrong. */

                /* atanh cannot underflow: |atanh(x)| > |x| for |x| < 1 */
                inex_im |= mpfr_atanh (y, y, rnd_away);

                ok = inex_im == 0
                     || mpfr_can_round (y, p - 2, rnd_away, GMP_RNDZ,
                                        p_im + (rnd_im == GMP_RNDN));
            } while (ok == 0);

            inex_re = set_pi_over_2 (mpc_realref (rop), -s_re, MPC_RND_RE (rnd));
            inex_im = mpfr_set (mpc_imagref (rop), y, rnd_im);
            mpfr_clear (y);
        }
        return MPC_INEX (inex_re, inex_im);
    }

    /* regular number argument */
    {
        mpfr_t a, b, x, y;
        mpfr_prec_t prec, p;
        mpfr_exp_t err, expo;
        int ok = 0;
        mpfr_t minus_op_re;
        mpfr_exp_t op_re_exp, op_im_exp;
        mpfr_rnd_t rnd1, rnd2;

        mpfr_inits2 (MPFR_PREC_MIN, a, b, x, y, (mpfr_ptr) 0);

        /* real part: Re(arctan(x+i*y)) = [arctan2(x,1-y) - arctan2(-x,1+y)]/2 */
        minus_op_re[0] = mpc_realref (op)[0];
        MPFR_CHANGE_SIGN (minus_op_re);
        op_re_exp = mpfr_get_exp (mpc_realref (op));
        op_im_exp = mpfr_get_exp (mpc_imagref (op));

        prec = mpfr_get_prec (mpc_realref (rop)); /* result precision */

        /* a = o(1-y)         error(a) < 1 ulp(a)
           b = o(atan2(x,a))  error(b) < [1+2^{3+Exp(x)-Exp(a)-Exp(b)}] ulp(b)
                                         = kb ulp(b)
           c = o(1+y)         error(c) < 1 ulp(c)
           d = o(atan2(-x,c)) error(d) < [1+2^{3+Exp(x)-Exp(c)-Exp(d)}] ulp(d)
                                         = kd ulp(d)
           e = o(b - d)       error(e) < [1 + kb*2^{Exp(b}-Exp(e)}
                                            + kd*2^{Exp(d)-Exp(e)}] ulp(e)
                              error(e) < [1 + 2^{4+Exp(x)-Exp(a)-Exp(e)}
                                            + 2^{4+Exp(x)-Exp(c)-Exp(e)}] ulp(e)
                              because |atan(u)| < |u|
                                       < [1 + 2^{5+Exp(x)-min(Exp(a),Exp(c))
                                                 -Exp(e)}] ulp(e)
           f = e/2            exact
        */

        /* p: working precision */
        p = (op_im_exp > 0 || prec > SAFE_ABS (mpfr_prec_t, op_im_exp)) ? prec
            : (prec - op_im_exp);
        rnd1 = mpfr_sgn (mpc_realref (op)) > 0 ? GMP_RNDD : GMP_RNDU;
        rnd2 = mpfr_sgn (mpc_realref (op)) < 0 ? GMP_RNDU : GMP_RNDD;

        do
        {
            p += mpc_ceil_log2 (p) + 2;
            mpfr_set_prec (a, p);
            mpfr_set_prec (b, p);
            mpfr_set_prec (x, p);

            /* x = upper bound for atan (x/(1-y)). Since atan is increasing, we
               need an upper bound on x/(1-y), i.e., a lower bound on 1-y for
               x positive, and an upper bound on 1-y for x negative */
            mpfr_ui_sub (a, 1, mpc_imagref (op), rnd1);
            if (mpfr_sgn (a) == 0) /* y is near 1, thus 1+y is near 2, and
                                  expo will be 1 or 2 below */
            {
                MPC_ASSERT (mpfr_cmp_ui (mpc_imagref(op), 1) == 0);
                /* check for intermediate underflow */
                err = 2; /* ensures err will be expo below */
            }
            else
                err = mpfr_get_exp (a); /* err = Exp(a) with the notations above */
            mpfr_atan2 (x, mpc_realref (op), a, GMP_RNDU);

            /* b = lower bound for atan (-x/(1+y)): for x negative, we need a
               lower bound on -x/(1+y), i.e., an upper bound on 1+y */
            mpfr_add_ui (a, mpc_imagref(op), 1, rnd2);
            /* if a is exactly zero, i.e., Im(op) = -1, then the error on a is 0,
               and we can simply ignore the terms involving Exp(a) in the error */
            if (mpfr_sgn (a) == 0)
            {
                MPC_ASSERT (mpfr_cmp_si (mpc_imagref(op), -1) == 0);
                /* check for intermediate underflow */
                expo = err; /* will leave err unchanged below */
            }
            else
                expo = mpfr_get_exp (a); /* expo = Exp(c) with the notations above */
            mpfr_atan2 (b, minus_op_re, a, GMP_RNDD);

            err = err < expo ? err : expo; /* err = min(Exp(a),Exp(c)) */
            mpfr_sub (x, x, b, GMP_RNDU);

            err = 5 + op_re_exp - err - mpfr_get_exp (x);
            /* error is bounded by [1 + 2^err] ulp(e) */
            err = err < 0 ? 1 : err + 1;

            mpfr_div_2ui (x, x, 1, GMP_RNDU);

            /* Note: using RND2=RNDD guarantees that if x is exactly representable
               on prec + ... bits, mpfr_can_round will return 0 */
            ok = mpfr_can_round (x, p - err, GMP_RNDU, GMP_RNDD,
                                 prec + (MPC_RND_RE (rnd) == GMP_RNDN));
        } while (ok == 0);

        /* Imaginary part
           Im(atan(x+I*y)) = 1/4 * [log(x^2+(1+y)^2) - log (x^2 +(1-y)^2)] */
        prec = mpfr_get_prec (mpc_imagref (rop)); /* result precision */

        /* a = o(1+y)    error(a) < 1 ulp(a)
           b = o(a^2)    error(b) < 5 ulp(b)
           c = o(x^2)    error(c) < 1 ulp(c)
           d = o(b+c)    error(d) < 7 ulp(d)
           e = o(log(d)) error(e) < [1 + 7*2^{2-Exp(e)}] ulp(e) = ke ulp(e)
           f = o(1-y)    error(f) < 1 ulp(f)
           g = o(f^2)    error(g) < 5 ulp(g)
           h = o(c+f)    error(h) < 7 ulp(h)
           i = o(log(h)) error(i) < [1 + 7*2^{2-Exp(i)}] ulp(i) = ki ulp(i)
           j = o(e-i)    error(j) < [1 + ke*2^{Exp(e)-Exp(j)}
                                       + ki*2^{Exp(i)-Exp(j)}] ulp(j)
                         error(j) < [1 + 2^{Exp(e)-Exp(j)} + 2^{Exp(i)-Exp(j)}
                                       + 7*2^{3-Exp(j)}] ulp(j)
                                  < [1 + 2^{max(Exp(e),Exp(i))-Exp(j)+1}
                                       + 7*2^{3-Exp(j)}] ulp(j)
           k = j/4       exact
        */
        err = 2;
        p = prec; /* working precision */

        do
        {
            p += mpc_ceil_log2 (p) + err;
            mpfr_set_prec (a, p);
            mpfr_set_prec (b, p);
            mpfr_set_prec (y, p);

            /* a = upper bound for log(x^2 + (1+y)^2) */
            ROUND_AWAY (mpfr_add_ui (a, mpc_imagref (op), 1, MPFR_RNDA), a);
            mpfr_sqr (a, a, GMP_RNDU);
            mpfr_sqr (y, mpc_realref (op), GMP_RNDU);
            mpfr_add (a, a, y, GMP_RNDU);
            mpfr_log (a, a, GMP_RNDU);

            /* b = lower bound for log(x^2 + (1-y)^2) */
            mpfr_ui_sub (b, 1, mpc_imagref (op), GMP_RNDZ); /* round to zero */
            mpfr_sqr (b, b, GMP_RNDZ);
            /* we could write mpfr_sqr (y, mpc_realref (op), GMP_RNDZ) but it is
               more efficient to reuse the value of y (x^2) above and subtract
               one ulp */
            mpfr_nextbelow (y);
            mpfr_add (b, b, y, GMP_RNDZ);
            mpfr_log (b, b, GMP_RNDZ);

            mpfr_sub (y, a, b, GMP_RNDU);

            if (mpfr_zero_p (y))
                /* FIXME: happens when x and y have very different magnitudes;
                   could be handled more efficiently                           */
                ok = 0;
            else
            {
                expo = MPC_MAX (mpfr_get_exp (a), mpfr_get_exp (b));
                expo = expo - mpfr_get_exp (y) + 1;
                err = 3 - mpfr_get_exp (y);
                /* error(j) <= [1 + 2^expo + 7*2^err] ulp(j) */
                if (expo <= err) /* error(j) <= [1 + 2^{err+1}] ulp(j) */
                    err = (err < 0) ? 1 : err + 2;
                else
                    err = (expo < 0) ? 1 : expo + 2;

                mpfr_div_2ui (y, y, 2, GMP_RNDN);
                MPC_ASSERT (!mpfr_zero_p (y));
                /* FIXME: underflow. Since the main term of the Taylor series
                   in y=0 is 1/(x^2+1) * y, this means that y is very small
                   and/or x very large; but then the mpfr_zero_p (y) above
                   should be true. This needs a proof, or better yet,
                   special code.                                              */

                ok = mpfr_can_round (y, p - err, GMP_RNDU, GMP_RNDD,
                                     prec + (MPC_RND_IM (rnd) == GMP_RNDN));
            }
        } while (ok == 0);

        inex = mpc_set_fr_fr (rop, x, y, rnd);

        mpfr_clears (a, b, x, y, (mpfr_ptr) 0);
        return inex;
    }
}
Esempio n. 21
0
static void
check_nan (void)
{
  mpfr_t  a, d, q;
  mpfr_exp_t emax, emin;
  int i;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  mpfr_clear (a);
  mpfr_clear (d);
  mpfr_clear (q);
}
Esempio n. 22
0
int
main (void)
{
    mpfr_t x;
    mpfr_exp_t emax;

    tests_start_mpfr ();

    mpfr_init (x);

    mpfr_set_nan (x);
    mpfr_prec_round (x, 2, MPFR_RNDN);
    MPFR_ASSERTN(mpfr_nan_p (x));

    mpfr_set_inf (x, 1);
    mpfr_prec_round (x, 2, MPFR_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);

    mpfr_set_inf (x, -1);
    mpfr_prec_round (x, 2, MPFR_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);

    mpfr_set_ui (x, 0, MPFR_RNDN);
    mpfr_prec_round (x, 2, MPFR_RNDN);
    MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));

    mpfr_set_ui (x, 0, MPFR_RNDN);
    mpfr_neg (x, x, MPFR_RNDN);
    mpfr_prec_round (x, 2, MPFR_RNDN);
    MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG(x));

    emax = mpfr_get_emax ();
    set_emax (0);
    mpfr_set_prec (x, 3);
    mpfr_set_str_binary (x, "0.111");
    mpfr_prec_round (x, 2, MPFR_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
    set_emax (emax);

    mpfr_set_prec (x, mp_bits_per_limb + 2);
    mpfr_set_ui (x, 1, MPFR_RNDN);
    mpfr_nextbelow (x);
    mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN);
    MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);

    mpfr_set_prec (x, 3);
    mpfr_set_ui (x, 5, MPFR_RNDN);
    mpfr_prec_round (x, 2, MPFR_RNDN);
    if (mpfr_cmp_ui(x, 4))
    {
        printf ("Error in tround: got ");
        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
        printf (" instead of 4\n");
        exit (1);
    }

    /* check case when reallocation is needed */
    mpfr_set_prec (x, 3);
    mpfr_set_ui (x, 5, MPFR_RNDN); /* exact */
    mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN);
    if (mpfr_cmp_ui(x, 5))
    {
        printf ("Error in tround: got ");
        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
        printf (" instead of 5\n");
        exit (1);
    }

    mpfr_clear(x);
    mpfr_init2 (x, 3);
    mpfr_set_si (x, -5, MPFR_RNDN); /* exact */
    mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN);
    if (mpfr_cmp_si(x, -5))
    {
        printf ("Error in tround: got ");
        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
        printf (" instead of -5\n");
        exit (1);
    }

    /* check case when new precision needs less limbs */
    mpfr_set_prec (x, mp_bits_per_limb + 1);
    mpfr_set_ui (x, 5, MPFR_RNDN); /* exact */
    mpfr_prec_round (x, 3, MPFR_RNDN); /* exact */
    if (mpfr_cmp_ui(x, 5))
    {
        printf ("Error in tround: got ");
        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
        printf (" instead of 5\n");
        exit (1);
    }

    mpfr_clear(x);

    tests_end_mpfr ();
    return 0;
}
Esempio n. 23
0
static void
overflowed_exp2_0 (void)
{
  mpfr_t x, y;
  int emax, i, inex, rnd, err = 0;
  mpfr_exp_t old_emax;

  old_emax = mpfr_get_emax ();

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

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

  if (err)
    exit (1);
  mpfr_clear (x);
  mpfr_clear (y);
}
Esempio n. 24
0
int
main (int argc, char *argv[])
{
  mpfr_t w,z;
  unsigned long k;
  int i;

  tests_start_mpfr ();

  mpfr_inits2 (53, w, z, (mpfr_ptr) 0);

  for (i = 0; i < 3; i++)
    {
      mpfr_set_inf (w, 1);
      test_mul (i, 0, w, w, 10, GMP_RNDZ);
      if (!MPFR_IS_INF(w))
        {
          printf ("Result is not Inf (i = %d)\n", i);
          exit (1);
        }

      mpfr_set_nan (w);
      test_mul (i, 0, w, w, 10, GMP_RNDZ);
      if (!MPFR_IS_NAN(w))
        {
          printf ("Result is not NaN (i = %d)\n", i);
          exit (1);
        }

      for (k = 0 ; k < numberof(val) ; k+=3)
        {
          mpfr_set_str (w, val[k], 16, GMP_RNDN);
          test_mul (i, 0, z, w, 10, GMP_RNDZ);
          if (mpfr_cmp_str (z, val[k+1], 16, GMP_RNDN))
            {
              printf ("ERROR for x * 2^n (i = %d) for %s\n", i, val[k]);
              printf ("Expected: %s\n"
                      "Got     : ", val[k+1]);
              mpfr_out_str (stdout, 16, 0, z, GMP_RNDN);
              putchar ('\n');
              exit (1);
            }
          test_mul (i, 1, z, w, 10, GMP_RNDZ);
          if (mpfr_cmp_str (z, val[k+2], 16, GMP_RNDN))
            {
              printf ("ERROR for x / 2^n (i = %d) for %s\n", i, val[k]);
              printf ("Expected: %s\n"
                      "Got     : ", val[k+2]);
              mpfr_out_str (stdout, 16, 0, z, GMP_RNDN);
              putchar ('\n');
              exit (1);
            }
        }

      mpfr_set_inf (w, 1);
      mpfr_nextbelow (w);
      test_mul (i, 0, w, w, 1, GMP_RNDN);
      if (!mpfr_inf_p (w))
        {
          printf ("Overflow error (i = %d)!\n", i);
          exit (1);
        }
      mpfr_set_ui (w, 0, GMP_RNDN);
      mpfr_nextabove (w);
      test_mul (i, 1, w, w, 1, GMP_RNDN);
      if (mpfr_cmp_ui (w, 0))
        {
          printf ("Underflow error (i = %d)!\n", i);
          exit (1);
        }
    }

  if (MPFR_EXP_MAX >= LONG_MAX/2 && MPFR_EXP_MIN <= LONG_MAX/2-LONG_MAX-1)
    {
      unsigned long lmp1 = (unsigned long) LONG_MAX + 1;

      mpfr_set_ui (w, 1, GMP_RNDN);
      mpfr_mul_2ui (w, w, LONG_MAX/2, GMP_RNDZ);
      mpfr_div_2ui (w, w, lmp1, GMP_RNDZ);
      mpfr_mul_2ui (w, w, lmp1 - LONG_MAX/2, GMP_RNDZ);
      if (!mpfr_cmp_ui (w, 1))
        {
          printf ("Underflow LONG_MAX error!\n");
          exit (1);
        }
    }

  mpfr_clears (w, z, (mpfr_ptr) 0);

  underflow0 ();

  tests_end_mpfr ();
  return 0;
}
Esempio n. 25
0
static void
large (mpfr_exp_t e)
{
  mpfr_t x, y, z;
  mpfr_exp_t emax;
  int inex;
  unsigned int flags;

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

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

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

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

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

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

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

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

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

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
  set_emax (emax);
}
Esempio n. 26
0
int
main (int argc, char *argv[])
{
  unsigned int prec, yprec;
  int rnd;
  mpfr_t x, y, z, t;
  unsigned long n;
  int inex;
  mpfr_exp_t emin, emax;
  mpfr_flags_t flags, ex_flags;
  int i;

  tests_start_mpfr ();

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

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

  if (argc >= 3) /* tzeta_ui n prec [rnd] */
    {
      mpfr_set_prec (x, atoi (argv[2]));
      mpfr_zeta_ui (x, atoi (argv[1]),
                    argc > 3 ? (mpfr_rnd_t) atoi (argv[3]) : MPFR_RNDN);
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      printf ("\n");
      goto clear_and_exit;
    }

  mpfr_set_prec (x, 33);
  mpfr_set_prec (y, 33);
  mpfr_zeta_ui (x, 3, MPFR_RNDZ);
  mpfr_set_str_binary (y, "0.100110011101110100000000001001111E1");
  if (mpfr_cmp (x, y))
    {
      printf ("Error for zeta(3), prec=33, MPFR_RNDZ\n");
      printf ("expected "); mpfr_dump (y);
      printf ("got      "); mpfr_dump (x);
      exit (1);
    }

  mpfr_clear_flags ();
  inex = mpfr_zeta_ui (x, 0, MPFR_RNDN);
  flags = __gmpfr_flags;
  MPFR_ASSERTN (inex == 0 && mpfr_cmp_si_2exp (x, -1, -1) == 0 && flags == 0);

  for (i = -2; i <= 2; i += 2)
    RND_LOOP (rnd)
      {
        int ex_inex;

        set_emin (i);
        set_emax (i);
        mpfr_clear_flags ();
        inex = mpfr_zeta_ui (x, 0, (mpfr_rnd_t) rnd);
        flags = __gmpfr_flags;
        if (i < 0)
          {
            mpfr_set_inf (y, -1);
            if (rnd == MPFR_RNDU || rnd == MPFR_RNDZ)
              {
                mpfr_nextabove (y);
                ex_inex = 1;
              }
            else
              {
                ex_inex = -1;
              }
            ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
          }
        else if (i > 0)
          {
            mpfr_set_zero (y, -1);
            if (rnd == MPFR_RNDD || rnd == MPFR_RNDA)
              {
                mpfr_nextbelow (y);
                ex_inex = -1;
              }
            else
              {
                ex_inex = 1;
              }
            ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
          }
        else
          {
            mpfr_set_str_binary (y, "-1e-1");
            ex_inex = 0;
            ex_flags = 0;
          }
        set_emin (emin);
        set_emax (emax);
        if (! (mpfr_equal_p (x, y) && MPFR_IS_NEG (x) &&
               SAME_SIGN (inex, ex_inex) && flags == ex_flags))
          {
            printf ("Failure for zeta(0) in %s, exponent range [%d,%d]\n",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), i, i);
            printf ("Expected ");
            mpfr_dump (y);
            printf ("  with inex ~ %d, flags =", ex_inex);
            flags_out (ex_flags);
            printf ("Got      ");
            mpfr_dump (x);
            printf ("  with inex = %d, flags =", inex);
            flags_out (flags);
            exit (1);
          }
      }

  mpfr_clear_divby0 ();
  inex = mpfr_zeta_ui (x, 1, MPFR_RNDN);
  MPFR_ASSERTN (inex == 0 && MPFR_IS_INF (x) && MPFR_IS_POS (x)
                && mpfr_divby0_p ());

  for (prec = MPFR_PREC_MIN; prec <= 100; prec++)
    {
      mpfr_set_prec (x, prec);
      mpfr_set_prec (z, prec);
      mpfr_set_prec (t, prec);
      yprec = prec + 10;
      mpfr_set_prec (y, yprec);

      for (n = 0; n < 50; n++)
        RND_LOOP (rnd)
          {
            mpfr_zeta_ui (y, n, MPFR_RNDN);
            if (mpfr_can_round (y, yprec, MPFR_RNDN, MPFR_RNDZ, prec
                                + (rnd == MPFR_RNDN)))
              {
                mpfr_set (t, y, (mpfr_rnd_t) rnd);
                for (i = 0; i <= 1; i++)
                  {
                    if (i)
                      {
                        mpfr_exp_t e;

                        if (MPFR_IS_SINGULAR (t))
                          break;
                        e = mpfr_get_exp (t);
                        set_emin (e);
                        set_emax (e);
                      }
                    mpfr_zeta_ui (z, n, (mpfr_rnd_t) rnd);
                    if (i)
                      {
                        set_emin (emin);
                        set_emax (emax);
                      }
                    if (mpfr_cmp (t, z))
                      {
                        printf ("results differ for n = %lu, prec = %u,"
                                " %s%s\n", n, prec,
                                mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
                                i ? ", reduced exponent range" : "");
                        printf ("  got      ");
                        mpfr_dump (z);
                        printf ("  expected ");
                        mpfr_dump (t);
                        printf ("  approx   ");
                        mpfr_dump (y);
                        exit (1);
                      }
                  }
              }
          }
    }

 clear_and_exit:
  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (t);

  tests_end_mpfr ();
  return 0;
}