示例#1
0
文件: texp.c 项目: BrianGladman/mpfr
static void
compare_exp2_exp3 (mpfr_prec_t p0, mpfr_prec_t p1)
{
  mpfr_t x, y, z;
  mpfr_prec_t prec;
  mpfr_rnd_t rnd;

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

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
int
mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  mpfr_exp_t expx;
  mpfr_prec_t precy;
  int inexact;
  MPFR_SAVE_EXPO_DECL (expo);

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

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

  /* First, let's detect most overflow and underflow cases. */
  {
    mpfr_t e, bound;

    /* We must extended the exponent range and save the flags now. */
    MPFR_SAVE_EXPO_MARK (expo);

    mpfr_init2 (e, sizeof (mpfr_exp_t) * CHAR_BIT);
    mpfr_init2 (bound, 32);

    inexact = mpfr_set_exp_t (e, expo.saved_emax, MPFR_RNDN);
    MPFR_ASSERTD (inexact == 0);
    mpfr_const_log2 (bound, expo.saved_emax < 0 ? MPFR_RNDD : MPFR_RNDU);
    mpfr_mul (bound, bound, e, MPFR_RNDU);
    if (MPFR_UNLIKELY (mpfr_cmp (x, bound) >= 0))
      {
        /* x > log(2^emax), thus exp(x) > 2^emax */
        mpfr_clears (e, bound, (mpfr_ptr) 0);
        MPFR_SAVE_EXPO_FREE (expo);
        return mpfr_overflow (y, rnd_mode, 1);
      }

    inexact = mpfr_set_exp_t (e, expo.saved_emin, MPFR_RNDN);
    MPFR_ASSERTD (inexact == 0);
    inexact = mpfr_sub_ui (e, e, 2, MPFR_RNDN);
    MPFR_ASSERTD (inexact == 0);
    mpfr_const_log2 (bound, expo.saved_emin < 0 ? MPFR_RNDU : MPFR_RNDD);
    mpfr_mul (bound, bound, e, MPFR_RNDD);
    if (MPFR_UNLIKELY (mpfr_cmp (x, bound) <= 0))
      {
        /* x < log(2^(emin - 2)), thus exp(x) < 2^(emin - 2) */
        mpfr_clears (e, bound, (mpfr_ptr) 0);
        MPFR_SAVE_EXPO_FREE (expo);
        return mpfr_underflow (y, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
                               1);
      }

    /* Other overflow/underflow cases must be detected
       by the generic routines. */
    mpfr_clears (e, bound, (mpfr_ptr) 0);
    MPFR_SAVE_EXPO_FREE (expo);
  }

  expx  = MPFR_GET_EXP (x);
  precy = MPFR_PREC (y);

  /* if x < 2^(-precy), then exp(x) i.e. gives 1 +/- 1 ulp(1) */
  if (MPFR_UNLIKELY (expx < 0 && (mpfr_uexp_t) (-expx) > precy))
    {
      mpfr_exp_t emin = __gmpfr_emin;
      mpfr_exp_t emax = __gmpfr_emax;
      int signx = MPFR_SIGN (x);

      MPFR_SET_POS (y);
      if (MPFR_IS_NEG_SIGN (signx) && (rnd_mode == MPFR_RNDD ||
                                       rnd_mode == MPFR_RNDZ))
        {
          __gmpfr_emin = 0;
          __gmpfr_emax = 0;
          mpfr_setmax (y, 0);  /* y = 1 - epsilon */
          inexact = -1;
        }
      else
        {
          __gmpfr_emin = 1;
          __gmpfr_emax = 1;
          mpfr_setmin (y, 1);  /* y = 1 */
          if (MPFR_IS_POS_SIGN (signx) && (rnd_mode == MPFR_RNDU ||
                                           rnd_mode == MPFR_RNDA))
            {
              mp_size_t yn;
              int sh;

              yn = 1 + (MPFR_PREC(y) - 1) / GMP_NUMB_BITS;
              sh = (mpfr_prec_t) yn * GMP_NUMB_BITS - MPFR_PREC(y);
              MPFR_MANT(y)[0] += MPFR_LIMB_ONE << sh;
              inexact = 1;
            }
          else
            inexact = -MPFR_FROM_SIGN_TO_INT(signx);
        }

      __gmpfr_emin = emin;
      __gmpfr_emax = emax;
    }
  else  /* General case */
    {
      if (MPFR_UNLIKELY (precy >= MPFR_EXP_THRESHOLD))
        /* mpfr_exp_3 saves the exponent range and flags itself, otherwise
           the flag changes in mpfr_exp_3 are lost */
        inexact = mpfr_exp_3 (y, x, rnd_mode); /* O(M(n) log(n)^2) */
      else
        {
          MPFR_SAVE_EXPO_MARK (expo);
          inexact = mpfr_exp_2 (y, x, rnd_mode); /* O(n^(1/3) M(n)) */
          MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
          MPFR_SAVE_EXPO_FREE (expo);
        }
    }

  return mpfr_check_range (y, inexact, rnd_mode);
}
示例#3
0
文件: texp.c 项目: jozip/xcl
static void
check_special (void)
{
    mpfr_t x, y, z;
    mpfr_exp_t emin, emax;

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

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

    /* check exp(NaN) = NaN */
    mpfr_set_nan (x);
    test_exp (y, x, MPFR_RNDN);
    if (!mpfr_nan_p (y))
    {
        printf ("Error for exp(NaN)\n");
        exit (1);
    }

    /* check exp(+inf) = +inf */
    mpfr_set_inf (x, 1);
    test_exp (y, x, MPFR_RNDN);
    if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
        printf ("Error for exp(+inf)\n");
        exit (1);
    }

    /* check exp(-inf) = +0 */
    mpfr_set_inf (x, -1);
    test_exp (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
        printf ("Error for exp(-inf)\n");
        exit (1);
    }

    /* Check overflow. Corner case of mpfr_exp_2 */
    mpfr_set_prec (x, 64);
    mpfr_set_emax (MPFR_EMAX_DEFAULT);
    mpfr_set_emin (MPFR_EMIN_DEFAULT);
    mpfr_set_str (x,
                  "0.1011000101110010000101111111010100001100000001110001100111001101E30",
                  2, MPFR_RNDN);
    mpfr_exp (x, x, MPFR_RNDD);
    if (mpfr_cmp_str (x,
                      ".1111111111111111111111111111111111111111111111111111111111111111E1073741823",
                      2, MPFR_RNDN) != 0)
    {
        printf ("Wrong overflow detection in mpfr_exp\n");
        mpfr_dump (x);
        exit (1);
    }
    /* Check underflow. Corner case of mpfr_exp_2 */
    mpfr_set_str (x,
                  "-0.1011000101110010000101111111011111010001110011110111100110101100E30",
                  2, MPFR_RNDN);
    mpfr_exp (x, x, MPFR_RNDN);
    if (mpfr_cmp_str (x, "0.1E-1073741823", 2, MPFR_RNDN) != 0)
    {
        printf ("Wrong underflow (1) detection in mpfr_exp\n");
        mpfr_dump (x);
        exit (1);
    }
    mpfr_set_str (x,
                  "-0.1011001101110010000101111111011111010001110011110111100110111101E30",
                  2, MPFR_RNDN);
    mpfr_exp (x, x, MPFR_RNDN);
    if (mpfr_cmp_ui (x, 0) != 0)
    {
        printf ("Wrong underflow (2) detection in mpfr_exp\n");
        mpfr_dump (x);
        exit (1);
    }
    /* Check overflow. Corner case of mpfr_exp_3 */
    if (MPFR_PREC_MAX >= MPFR_EXP_THRESHOLD + 10 && MPFR_PREC_MAX >= 64)
    {
        /* this ensures that for small MPFR_EXP_THRESHOLD, the following
           mpfr_set_str conversion is exact */
        mpfr_set_prec (x, (MPFR_EXP_THRESHOLD + 10 > 64)
                       ? MPFR_EXP_THRESHOLD + 10 : 64);
        mpfr_set_str (x,
                      "0.1011000101110010000101111111010100001100000001110001100111001101E30",
                      2, MPFR_RNDN);
        mpfr_clear_overflow ();
        mpfr_exp (x, x, MPFR_RNDD);
        if (!mpfr_overflow_p ())
        {
            printf ("Wrong overflow detection in mpfr_exp_3\n");
            mpfr_dump (x);
            exit (1);
        }
        /* Check underflow. Corner case of mpfr_exp_3 */
        mpfr_set_str (x,
                      "-0.1011000101110010000101111111011111010001110011110111100110101100E30",
                      2, MPFR_RNDN);
        mpfr_clear_underflow ();
        mpfr_exp (x, x, MPFR_RNDN);
        if (!mpfr_underflow_p ())
        {
            printf ("Wrong underflow detection in mpfr_exp_3\n");
            mpfr_dump (x);
            exit (1);
        }
        mpfr_set_prec (x, 53);
    }

    /* check overflow */
    set_emax (10);
    mpfr_set_ui (x, 7, MPFR_RNDN);
    test_exp (y, x, MPFR_RNDN);
    if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
        printf ("Error for exp(7) for emax=10\n");
        exit (1);
    }
    set_emax (emax);

    /* check underflow */
    set_emin (-10);
    mpfr_set_si (x, -9, MPFR_RNDN);
    test_exp (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
        printf ("Error for exp(-9) for emin=-10\n");
        printf ("Expected +0\n");
        printf ("Got      ");
        mpfr_print_binary (y);
        puts ("");
        exit (1);
    }
    set_emin (emin);

    /* check case EXP(x) < -precy */
    mpfr_set_prec (y, 2);
    mpfr_set_str_binary (x, "-0.1E-3");
    test_exp (y, x, MPFR_RNDD);
    if (mpfr_cmp_ui_2exp (y, 3, -2))
    {
        printf ("Error for exp(-1/16), prec=2, RNDD\n");
        printf ("expected 0.11, got ");
        mpfr_dump (y);
        exit (1);
    }
    test_exp (y, x, MPFR_RNDZ);
    if (mpfr_cmp_ui_2exp (y, 3, -2))
    {
        printf ("Error for exp(-1/16), prec=2, RNDZ\n");
        printf ("expected 0.11, got ");
        mpfr_dump (y);
        exit (1);
    }
    mpfr_set_str_binary (x, "0.1E-3");
    test_exp (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 1))
    {
        printf ("Error for exp(1/16), prec=2, RNDN\n");
        exit (1);
    }
    test_exp (y, x, MPFR_RNDU);
    if (mpfr_cmp_ui_2exp (y, 3, -1))
    {
        printf ("Error for exp(1/16), prec=2, RNDU\n");
        exit (1);
    }

    /* bug reported by Franky Backeljauw, 28 Mar 2003 */
    mpfr_set_prec (x, 53);
    mpfr_set_prec (y, 53);
    mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
    test_exp (y, x, MPFR_RNDN);

    mpfr_set_prec (x, 153);
    mpfr_set_prec (z, 153);
    mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
    test_exp (z, x, MPFR_RNDN);
    mpfr_prec_round (z, 53, MPFR_RNDN);

    if (mpfr_cmp (y, z))
    {
        printf ("Error in mpfr_exp for large argument\n");
        exit (1);
    }

    /* corner cases in mpfr_exp_3 */
    mpfr_set_prec (x, 2);
    mpfr_set_ui (x, 1, MPFR_RNDN);
    mpfr_set_prec (y, 2);
    mpfr_exp_3 (y, x, MPFR_RNDN);

    /* Check some little things about overflow detection */
    set_emin (-125);
    set_emax (128);
    mpfr_set_prec (x, 107);
    mpfr_set_prec (y, 107);
    mpfr_set_str_binary (x, "0.11110000000000000000000000000000000000000000000"
                         "0000000000000000000000000000000000000000000000000000"
                         "00000000E4");
    test_exp (y, x, MPFR_RNDN);
    if (mpfr_cmp_str (y, "0.11000111100001100110010101111101011010010101010000"
                      "1101110111100010111001011111111000110111001011001101010"
                      "01E22", 2, MPFR_RNDN))
    {
        printf ("Special overflow error (1)\n");
        mpfr_dump (y);
        exit (1);
    }

    set_emin (emin);
    set_emax (emax);

    /* Check for overflow producing a segfault with HUGE exponent */
    mpfr_set_ui  (x, 3, MPFR_RNDN);
    mpfr_mul_2ui (x, x, 32, MPFR_RNDN);
    test_exp (y, x, MPFR_RNDN); /* Can't test return value: May overflow or not*/

    /* Bug due to wrong approximation of (x)/log2 */
    mpfr_set_prec (x, 163);

    mpfr_set_str (x, "-4.28ac8fceeadcda06bb56359017b1c81b85b392e7", 16,
                  MPFR_RNDN);
    mpfr_exp (x, x, MPFR_RNDN);
    if (mpfr_cmp_str (x, "3.fffffffffffffffffffffffffffffffffffffffe8@-2",
                      16, MPFR_RNDN))
    {
        printf ("Error for x= -4.28ac8fceeadcda06bb56359017b1c81b85b392e7");
        printf ("expected  3.fffffffffffffffffffffffffffffffffffffffe8@-2");
        printf ("Got       ");
        mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
        putchar ('\n');
    }

    /* bug found by Guillaume Melquiond, 13 Sep 2005 */
    mpfr_set_prec (x, 53);
    mpfr_set_str_binary (x, "-1E-400");
    mpfr_exp (x, x, MPFR_RNDZ);
    if (mpfr_cmp_ui (x, 1) == 0)
    {
        printf ("Error for exp(-2^(-400))\n");
        exit (1);
    }

    mpfr_clear (x);
    mpfr_clear (y);
    mpfr_clear (z);
}
示例#4
0
static void
check_special ()
{
  mpfr_t x, y, z;
  mp_exp_t emin, emax;

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

  /* check exp(NaN) = NaN */
  mpfr_set_nan (x);
  mpfr_exp (y, x, GMP_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for exp(NaN)\n");
      exit (1);
    }

  /* check exp(+inf) = +inf */
  mpfr_set_inf (x, 1);
  mpfr_exp (y, x, GMP_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for exp(+inf)\n");
      exit (1);
    }

  /* check exp(-inf) = +0 */
  mpfr_set_inf (x, -1);
  mpfr_exp (y, x, GMP_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
      printf ("Error for exp(-inf)\n");
      exit (1);
    }

  /* check overflow */
  emax = mpfr_get_emax ();
  set_emax (10);
  mpfr_set_ui (x, 7, GMP_RNDN);
  mpfr_exp (y, x, GMP_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for exp(7) for emax=10\n");
      exit (1);
    }
  set_emax (emax);

  /* check underflow */
  emin = mpfr_get_emin ();
  set_emin (-10);
  mpfr_set_si (x, -9, GMP_RNDN);
  mpfr_exp (y, x, GMP_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
      printf ("Error for exp(-9) for emin=-10\n");
      printf ("Expected +0\n");
      printf ("Got      "); mpfr_print_binary (y); puts ("");
      exit (1);
    }
  set_emin (emin);

  /* check case EXP(x) < -precy */
  mpfr_set_prec (y, 2);
  mpfr_set_str_binary (x, "-0.1E-3");
  mpfr_exp (y, x, GMP_RNDD);
  if (mpfr_cmp_ui_2exp (y, 3, -2))
    {
      printf ("Error for exp(-1/16), prec=2, RNDD\n");
      exit (1);
    }
  mpfr_exp (y, x, GMP_RNDZ);
  if (mpfr_cmp_ui (y, 1))
    {
      printf ("Error for exp(-1/16), prec=2, RNDZ\n");
      exit (1);
    }
  mpfr_set_str_binary (x, "0.1E-3");
  mpfr_exp (y, x, GMP_RNDN);
  if (mpfr_cmp_ui (y, 1))
    {
      printf ("Error for exp(1/16), prec=2, RNDN\n");
      exit (1);
    }
  mpfr_exp (y, x, GMP_RNDU);
  if (mpfr_cmp_ui_2exp (y, 3, -1))
    {
      printf ("Error for exp(1/16), prec=2, RNDU\n");
      exit (1);
    }

  /* bug reported by Franky Backeljauw, 28 Mar 2003 */
  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);
  mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
  mpfr_exp (y, x, GMP_RNDN);

  mpfr_set_prec (x, 153);
  mpfr_set_prec (z, 153);
  mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
  mpfr_exp (z, x, GMP_RNDN);
  mpfr_prec_round (z, 53, GMP_RNDN);

  if (mpfr_cmp (y, z))
    {
      printf ("Error in mpfr_exp for large argument\n");
      exit (1);
    }

  /* corner cases in mpfr_exp_3 */
  mpfr_set_prec (x, 2);
  mpfr_set_ui (x, 1, GMP_RNDN);
  mpfr_set_prec (y, 2);
  mpfr_exp_3 (y, x, GMP_RNDN);

  /* Check some little things about overflow detection */
  set_emin (-125);
  set_emax (128);
  mpfr_set_prec (x, 107);
  mpfr_set_prec (y, 107);
  mpfr_set_str_binary (x, "0.11110000000000000000000000000000000000000000000"
		       "0000000000000000000000000000000000000000000000000000"
		       "00000000E4");
  mpfr_exp (y, x, GMP_RNDN);
  if (mpfr_cmp_str (y, "0.11000111100001100110010101111101011010010101010000"
		    "1101110111100010111001011111111000110111001011001101010"
		    "01E22", 2, GMP_RNDN))
    {
      printf ("Special overflow error (1)\n");
      mpfr_dump (y);
      exit (1);
    }
  
  set_emin (MPFR_EMIN_MIN);
  set_emax (MPFR_EMAX_MAX);

  /* Check for overflow producing a segfault with HUGE exponent */
  mpfr_set_ui  (x, 3, GMP_RNDN);
  mpfr_mul_2ui (x, x, 32, GMP_RNDN);
  mpfr_exp (y, x, GMP_RNDN); /* Can't test return value: May overflow or not*/
  
  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
示例#5
0
文件: texp.c 项目: BrianGladman/mpfr
/* worst cases communicated by Jean-Michel Muller and Vincent Lefevre */
static int
check_worst_cases (void)
{
  mpfr_t x; mpfr_t y;

  mpfr_init(x);
  mpfr_set_prec (x, 53);

  check_worst_case("4.44089209850062517562e-16", "1.00000000000000022204");
  check_worst_case("6.39488462184069720009e-14", "1.00000000000006372680");
  check_worst_case("1.84741111297455401935e-12", "1.00000000000184718907");
  check_worst_case("1.76177628026265550074e-10", "1.00000000017617751702");
  check3("1.76177628026265550074e-10", MPFR_RNDN, "1.00000000017617773906");
  check_worst_case("7.54175277499595900852e-10", "1.00000000075417516676");
  check3("7.54175277499595900852e-10", MPFR_RNDN, "1.00000000075417538881");
  /* bug found by Vincent Lefe`vre on December 8, 1999 */
  check3("-5.42410311287441459172e+02", MPFR_RNDN, "2.7176584868845723e-236");
  /* further cases communicated by Vincent Lefe`vre on January 27, 2000 */
  check3("-1.32920285897904911589e-10", MPFR_RNDN, "0.999999999867079769622");
  check3("-1.44037948245738330735e-10", MPFR_RNDN, "0.9999999998559621072757");
  check3("-1.66795910430705305937e-10", MPFR_RNDZ, "0.9999999998332040895832");
  check3("-1.64310953745426656203e-10", MPFR_RNDN, "0.9999999998356891017792");
  check3("-1.38323574826034659172e-10", MPFR_RNDZ, "0.9999999998616764251835");
  check3("-1.23621668465115401498e-10", MPFR_RNDZ, "0.9999999998763783315425");

  mpfr_set_prec (x, 601);
  mpfr_set_str (x, "0.88b6ba510e10450edc258748bc9dfdd466f21b47ed264cdf24aa8f64af1f3fad9ec2301d43c0743f534b5aa20091ff6d352df458ef1ba519811ef6f5b11853534fd8fa32764a0a6d2d0dd20@0", 16, MPFR_RNDZ);
  mpfr_init2 (y, 601);
  mpfr_exp_2 (y, x, MPFR_RNDD);
  mpfr_exp_3 (x, x, MPFR_RNDD);
  if (mpfr_cmp (x, y))
    {
      printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=601\n");
      printf ("mpfr_exp_2 gives ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\nmpfr_exp_3 gives ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_prec (x, 13001);
  mpfr_set_prec (y, 13001);
  mpfr_urandomb (x, RANDS);
  mpfr_exp_3 (y, x, MPFR_RNDN);
  mpfr_exp_2 (x, x, MPFR_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=13001\n");
      exit (1);
    }

  mpfr_set_prec (x, 118);
  mpfr_set_str_binary (x, "0.1110010100011101010000111110011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E-86");
  mpfr_set_prec (y, 118);
  mpfr_exp_2 (y, x, MPFR_RNDU);
  mpfr_exp_3 (x, x, MPFR_RNDU);
  if (mpfr_cmp (x, y))
    {
      printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=118\n");
      printf ("mpfr_exp_2 gives ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\nmpfr_exp_3 gives ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
  return 0;
}