Пример #1
0
int
mpfr_urandom (mpfr_ptr rop, gmp_randstate_t rstate, mpfr_rnd_t rnd_mode)
{
  mpfr_limb_ptr rp;
  mpfr_prec_t nbits;
  mp_size_t nlimbs;
  mp_size_t n;
  mpfr_exp_t exp;
  mpfr_exp_t emin;
  int cnt;
  int inex;

  rp = MPFR_MANT (rop);
  nbits = MPFR_PREC (rop);
  nlimbs = MPFR_LIMB_SIZE (rop);
  MPFR_SET_POS (rop);
  exp = 0;
  emin = mpfr_get_emin ();
  if (MPFR_UNLIKELY (emin > 0))
    {
      if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
          || (emin == 1 && rnd_mode == MPFR_RNDN
              && random_rounding_bit (rstate)))
        {
          mpfr_set_ui_2exp (rop, 1, emin - 1, rnd_mode);
          return +1;
        }
      else
        {
          MPFR_SET_ZERO (rop);
          return -1;
        }
    }

  /* Exponent */
#define DRAW_BITS 8 /* we draw DRAW_BITS at a time */
  cnt = DRAW_BITS;
  MPFR_ASSERTN(DRAW_BITS <= GMP_NUMB_BITS);
  while (cnt == DRAW_BITS)
    {
      /* generate DRAW_BITS in rp[0] */
      mpfr_rand_raw (rp, rstate, DRAW_BITS);
      if (MPFR_UNLIKELY (rp[0] == 0))
        cnt = DRAW_BITS;
      else
        {
          count_leading_zeros (cnt, rp[0]);
          cnt -= GMP_NUMB_BITS - DRAW_BITS;
        }

      if (MPFR_UNLIKELY (exp < emin + cnt))
        {
          /* To get here, we have been drawing more than -emin zeros
             in a row, then return 0 or the smallest representable
             positive number.

             The rounding to nearest mode is subtle:
             If exp - cnt == emin - 1, the rounding bit is set, except
             if cnt == DRAW_BITS in which case the rounding bit is
             outside rp[0] and must be generated. */
          if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
              || (rnd_mode == MPFR_RNDN && cnt == exp - emin - 1
                  && (cnt != DRAW_BITS || random_rounding_bit (rstate))))
            {
              mpfr_set_ui_2exp (rop, 1, emin - 1, rnd_mode);
              return +1;
            }
          else
            {
              MPFR_SET_ZERO (rop);
              return -1;
            }
        }
      exp -= cnt;
    }
  MPFR_EXP (rop) = exp; /* Warning: may be outside the current
                           exponent range */


  /* Significand: we need generate only nbits-1 bits, since the most
     significant is 1 */
  mpfr_rand_raw (rp, rstate, nbits - 1);
  n = nlimbs * GMP_NUMB_BITS - nbits;
  if (MPFR_LIKELY (n != 0)) /* this will put the low bits to zero */
    mpn_lshift (rp, rp, nlimbs, n);

  /* Set the msb to 1 since it was fixed by the exponent choice */
  rp[nlimbs - 1] |= MPFR_LIMB_HIGHBIT;

  /* Rounding */
  if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
      || (rnd_mode == MPFR_RNDN && random_rounding_bit (rstate)))
    {
      /* Take care of the exponent range: it may have been reduced */
      if (exp < emin)
        mpfr_set_ui_2exp (rop, 1, emin - 1, rnd_mode);
      else if (exp > mpfr_get_emax ())
        mpfr_set_inf (rop, +1); /* overflow, flag set by mpfr_check_range */
      else
        mpfr_nextabove (rop);
      inex = +1;
    }
  else
    inex = -1;

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

  tests_start_mpfr ();

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

  mpfr_init (x);
  mpfr_init (y);

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

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

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

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

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

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

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

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

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

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

  test_generic (2, 100, 100);

  mpfr_clear (x);
  mpfr_clear (y);

  overflowed_exp2_0 ();

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

  tests_end_mpfr ();
  return 0;
}
Пример #3
0
static void
underflows (void)
{
    mpfr_t x, y, z;
    int err = 0;
    int inexact;
    int i;
    mp_exp_t emin;

    mpfr_init2 (x, 64);
    mpfr_init2 (y, 64);

    mpfr_set_ui (x, 1, GMP_RNDN);
    mpfr_set_exp (x, mpfr_get_emin());

    for (i = 3; i < 10; i++)
    {
        mpfr_set_ui (y, i, GMP_RNDN);
        mpfr_div_2ui (y, y, 1, GMP_RNDN);
        test_pow (y, x, y, GMP_RNDN);
        if (!MPFR_IS_FP(y) || mpfr_cmp_ui (y, 0))
        {
            printf ("Error in mpfr_pow for ");
            mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
            printf (" ^ (%d/2)\nGot ", i);
            mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
            printf (" instead of 0.\n");
            exit (1);
        }
    }

    mpfr_init2 (z, 55);
    mpfr_set_str (x, "0.110011010011101001110001110100010000110111101E0",
                  2, GMP_RNDN);
    mpfr_set_str (y, "0.101110010011111001011010100011011100111110011E40",
                  2, GMP_RNDN);
    mpfr_clear_flags ();
    inexact = mpfr_pow (z, x, y, GMP_RNDU);
    if (!mpfr_underflow_p ())
    {
        printf ("Underflow flag is not set for special underflow test.\n");
        err = 1;
    }
    if (inexact <= 0)
    {
        printf ("Ternary value is wrong for special underflow test.\n");
        err = 1;
    }
    mpfr_set_ui (x, 0, GMP_RNDN);
    mpfr_nextabove (x);
    if (mpfr_cmp (x, z) != 0)
    {
        printf ("Wrong value for special underflow test.\nGot ");
        mpfr_out_str (stdout, 2, 0, z, GMP_RNDN);
        printf ("\ninstead of ");
        mpfr_out_str (stdout, 2, 2, x, GMP_RNDN);
        printf ("\n");
        err = 1;
    }
    if (err)
        exit (1);

    /* MPFR currently (2006-08-19) segfaults on the following code (and
       possibly makes other programs crash due to the lack of memory),
       because y is converted into an mpz_t, and the required precision
       is too high. */
    mpfr_set_prec (x, 2);
    mpfr_set_prec (y, 2);
    mpfr_set_prec (z, 12);
    mpfr_set_ui_2exp (x, 3, -2, GMP_RNDN);
    mpfr_set_ui_2exp (y, 1, mpfr_get_emax () - 1, GMP_RNDN);
    mpfr_clear_flags ();
    mpfr_pow (z, x, y, GMP_RNDN);
    if (!mpfr_underflow_p () || MPFR_NOTZERO (z))
    {
        printf ("Underflow test with large y fails.\n");
        exit (1);
    }

    emin = mpfr_get_emin ();
    mpfr_set_emin (-256);
    mpfr_set_prec (x, 2);
    mpfr_set_prec (y, 2);
    mpfr_set_prec (z, 12);
    mpfr_set_ui_2exp (x, 3, -2, GMP_RNDN);
    mpfr_set_ui_2exp (y, 1, 38, GMP_RNDN);
    mpfr_clear_flags ();
    inexact = mpfr_pow (z, x, y, GMP_RNDN);
    if (!mpfr_underflow_p () || MPFR_NOTZERO (z) || inexact >= 0)
    {
        printf ("Bad underflow detection for 0.75^(2^38). Obtained:\n"
                "Underflow flag... %-3s (should be 'yes')\n"
                "Zero result...... %-3s (should be 'yes')\n"
                "Inexact value.... %-3d (should be negative)\n",
                mpfr_underflow_p () ? "yes" : "no",
                MPFR_IS_ZERO (z) ? "yes" : "no", inexact);
        exit (1);
    }
    mpfr_set_emin (emin);

    emin = mpfr_get_emin ();
    mpfr_set_emin (-256);
    mpfr_set_prec (x, 2);
    mpfr_set_prec (y, 40);
    mpfr_set_prec (z, 12);
    mpfr_set_ui_2exp (x, 3, -1, GMP_RNDN);
    mpfr_set_si_2exp (y, -1, 38, GMP_RNDN);
    for (i = 0; i < 4; i++)
    {
        if (i == 2)
            mpfr_neg (x, x, GMP_RNDN);
        mpfr_clear_flags ();
        inexact = mpfr_pow (z, x, y, GMP_RNDN);
        if (!mpfr_underflow_p () || MPFR_NOTZERO (z) ||
                (i == 3 ? (inexact <= 0) : (inexact >= 0)))
        {
            printf ("Bad underflow detection for (");
            mpfr_out_str (stdout, 10, 0, x, GMP_RNDN);
            printf (")^(-2^38-%d). Obtained:\n"
                    "Overflow flag.... %-3s (should be 'no')\n"
                    "Underflow flag... %-3s (should be 'yes')\n"
                    "Zero result...... %-3s (should be 'yes')\n"
                    "Inexact value.... %-3d (should be %s)\n", i,
                    mpfr_overflow_p () ? "yes" : "no",
                    mpfr_underflow_p () ? "yes" : "no",
                    MPFR_IS_ZERO (z) ? "yes" : "no", inexact,
                    i == 3 ? "positive" : "negative");
            exit (1);
        }
        inexact = mpfr_sub_ui (y, y, 1, GMP_RNDN);
        MPFR_ASSERTN (inexact == 0);
    }
    mpfr_set_emin (emin);

    mpfr_clears (x, y, z, (void *) 0);
}
Пример #4
0
static void
special (void)
{
  mpfr_t x, y;
  int inex;
  int sign;
  mpfr_exp_t emin, emax;

  mpfr_init (x);
  mpfr_init (y);

  mpfr_set_nan (x);
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for lgamma(NaN)\n");
      exit (1);
    }

  mpfr_set_inf (x, -1);
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for lgamma(-Inf)\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != 1)
    {
      printf ("Error for lgamma(+Inf)\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != 1)
    {
      printf ("Error for lgamma(+0)\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_neg (x, x, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != -1)
    {
      printf ("Error for lgamma(-0)\n");
      exit (1);
    }

  mpfr_set_ui (x, 1, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y) || sign != 1)
    {
      printf ("Error for lgamma(1)\n");
      exit (1);
    }

  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for lgamma(-1)\n");
      exit (1);
    }

  mpfr_set_ui (x, 2, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y) || sign != 1)
    {
      printf ("Error for lgamma(2)\n");
      exit (1);
    }

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

#define CHECK_X1 "1.0762904832837976166"
#define CHECK_Y1 "-0.039418362817587634939"

  mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN);
  if (mpfr_equal_p (y, x) == 0 || sign != 1)
    {
      printf ("mpfr_lgamma("CHECK_X1") is wrong:\n"
              "expected ");
      mpfr_dump (x);
      printf ("got      ");
      mpfr_dump (y);
      exit (1);
    }

#define CHECK_X2 "9.23709516716202383435e-01"
#define CHECK_Y2 "0.049010669407893718563"
  mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN);
  if (mpfr_equal_p (y, x) == 0 || sign != 1)
    {
      printf ("mpfr_lgamma("CHECK_X2") is wrong:\n"
              "expected ");
      mpfr_dump (x);
      printf ("got      ");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 8);
  mpfr_set_prec (y, 175);
  mpfr_set_ui (x, 33, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDU);
  mpfr_set_prec (x, 175);
  mpfr_set_str_binary (x, "0.1010001100011101101011001101110010100001000001000001110011000001101100001111001001000101011011100100010101011110100111110101010100010011010010000101010111001100011000101111E7");
  if (mpfr_equal_p (x, y) == 0 || sign != 1)
    {
      printf ("Error in mpfr_lgamma (1)\n");
      exit (1);
    }

  mpfr_set_prec (x, 21);
  mpfr_set_prec (y, 8);
  mpfr_set_ui (y, 120, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (x, &sign, y, MPFR_RNDZ);
  mpfr_set_prec (y, 21);
  mpfr_set_str_binary (y, "0.111000101000001100101E9");
  if (mpfr_equal_p (x, y) == 0 || sign != 1)
    {
      printf ("Error in mpfr_lgamma (120)\n");
      printf ("Expected "); mpfr_dump (y);
      printf ("Got      "); mpfr_dump (x);
      exit (1);
    }

  mpfr_set_prec (x, 3);
  mpfr_set_prec (y, 206);
  mpfr_set_str_binary (x, "0.110e10");
  sign = -17;
  inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_prec (x, 206);
  mpfr_set_str_binary (x, "0.10000111011000000011100010101001100110001110000111100011000100100110110010001011011110101001111011110110000001010100111011010000000011100110110101100111000111010011110010000100010111101010001101000110101001E13");
  if (mpfr_equal_p (x, y) == 0 || sign != 1)
    {
      printf ("Error in mpfr_lgamma (768)\n");
      exit (1);
    }
  if (inex >= 0)
    {
      printf ("Wrong flag for mpfr_lgamma (768)\n");
      exit (1);
    }

  mpfr_set_prec (x, 4);
  mpfr_set_prec (y, 4);
  mpfr_set_str_binary (x, "0.1100E-66");
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.1100E6");
  if (mpfr_equal_p (x, y) == 0 || sign != 1)
    {
      printf ("Error for lgamma(0.1100E-66)\n");
      printf ("Expected ");
      mpfr_dump (x);
      printf ("Got      ");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 256);
  mpfr_set_prec (y, 32);
  mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN);
  mpfr_add_ui (x, x, 1, MPFR_RNDN);
  mpfr_div_2ui (x, x, 1, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_prec (x, 32);
  mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207");
  if (mpfr_equal_p (x, y) == 0 || sign != 1)
    {
      printf ("Error for lgamma(-2^199+0.5)\n");
      printf ("Got        ");
      mpfr_dump (y);
      printf ("instead of ");
      mpfr_dump (x);
      exit (1);
    }

  mpfr_set_prec (x, 256);
  mpfr_set_prec (y, 32);
  mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN);
  mpfr_sub_ui (x, x, 1, MPFR_RNDN);
  mpfr_div_2ui (x, x, 1, MPFR_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_prec (x, 32);
  mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207");
  if (mpfr_equal_p (x, y) == 0 || sign != -1)
    {
      printf ("Error for lgamma(-2^199-0.5)\n");
      printf ("Got        ");
      mpfr_dump (y);
      printf ("with sign %d instead of ", sign);
      mpfr_dump (x);
      printf ("with sign -1.\n");
      exit (1);
    }

  mpfr_set_prec (x, 10);
  mpfr_set_prec (y, 10);
  mpfr_set_str_binary (x, "-0.1101111000E-3");
  inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "10.01001011");
  if (mpfr_equal_p (x, y) == 0 || sign != -1 || inex >= 0)
    {
      printf ("Error for lgamma(-0.1101111000E-3)\n");
      printf ("Got        ");
      mpfr_dump (y);
      printf ("instead of ");
      mpfr_dump (x);
      printf ("with sign %d instead of -1 (inex=%d).\n", sign, inex);
      exit (1);
    }

  mpfr_set_prec (x, 18);
  mpfr_set_prec (y, 28);
  mpfr_set_str_binary (x, "-1.10001101010001101e-196");
  inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_prec (x, 28);
  mpfr_set_str_binary (x, "0.100001110110101011011010011E8");
  MPFR_ASSERTN (mpfr_equal_p (x, y) && inex < 0);

  /* values reported by Kaveh Ghazi on 14 Jul 2007, where mpfr_lgamma()
     takes forever */
#define VAL1 "-0.11100001001010110111001010001001001011110100110000110E-55"
#define OUT1 "100110.01000000010111001110110101110101001001100110111"
#define VAL2 "-0.11100001001010110111001010001001001011110011111111100E-55"
#define OUT2 "100110.0100000001011100111011010111010100100110011111"
#define VAL3 "-0.11100001001010110111001010001001001001110101101010100E-55"
#define OUT3 "100110.01000000010111001110110101110101001011110111011"
#define VAL4 "-0.10001111110110110100100100000000001111110001001001011E-57"
#define OUT4 "101000.0001010111110011101101000101111111010001100011"
#define VAL5 "-0.10001111110110110100100100000000001111011111100001000E-57"
#define OUT5 "101000.00010101111100111011010001011111110100111000001"
#define VAL6 "-0.10001111110110110100100100000000001111011101100011001E-57"
#define OUT6 "101000.0001010111110011101101000101111111010011101111"

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

  mpfr_set_str_binary (x, VAL1);
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, OUT1);
  MPFR_ASSERTN(sign == -1 && mpfr_equal_p(x, y));

  mpfr_set_str_binary (x, VAL2);
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, OUT2);
  MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));

  mpfr_set_str_binary (x, VAL3);
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, OUT3);
  MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));

  mpfr_set_str_binary (x, VAL4);
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, OUT4);
  MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));

  mpfr_set_str_binary (x, VAL5);
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, OUT5);
  MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));

  mpfr_set_str_binary (x, VAL6);
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, OUT6);
  MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));

  /* further test from Kaveh Ghazi */
  mpfr_set_str_binary (x, "-0.10011010101001010010001110010111010111011101010111001E-53");
  mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "100101.00111101101010000000101010111010001111001101111");
  MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));

  /* bug found by Kevin Rauch on 26 Oct 2007 */
  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();
  mpfr_set_emin (-1000000000);
  mpfr_set_emax (1000000000);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_lgamma (x, &sign, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_get_emin () == -1000000000);
  MPFR_ASSERTN(mpfr_get_emax () == 1000000000);
  mpfr_set_emin (emin);
  mpfr_set_emax (emax);

  /* two other bugs reported by Kevin Rauch on 27 Oct 2007 */
  mpfr_set_prec (x, 128);
  mpfr_set_prec (y, 128);
  mpfr_set_str_binary (x, "0.11000110011110111111110010100110000000000000000000000000000000000000000000000000000000000000000001000011000110100100110111101010E-765689");
  inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "10000001100100101111011011010000111010001001110000111010011000101001011111011111110011011010110100101111110111001001010100011101E-108");
  MPFR_ASSERTN(inex < 0 && mpfr_cmp (y, x) == 0 && sign > 0);

  mpfr_set_prec (x, 128);
  mpfr_set_prec (y, 256);
  mpfr_set_str_binary (x, "0.1011111111111111100000111011111E-31871");
  inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
  mpfr_set_prec (x, 256);
  mpfr_set_str (x, "AC9729B83707E6797612D0D76DAF42B1240A677FF1B6E3783FD4E53037143B1P-237", 16, MPFR_RNDN);
  MPFR_ASSERTN(inex < 0 && mpfr_cmp (y, x) == 0 && sign > 0);

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

  tests_start_mpfr ();

  mpf_init (y);
  mpf_init (z);

  mpf_set_d (y, 0.0);

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

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

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

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

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

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

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

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

  emax = mpfr_get_emax ();

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

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

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

  tests_end_mpfr ();
  return 0;
}
Пример #6
0
/* If x^y is exactly representable (with maybe a larger precision than z),
   round it in z and return the (mpc) inexact flag in [0, 10].

   If x^y is not exactly representable, return -1.

   If intermediate computations lead to numbers of more than maxprec bits,
   then abort and return -2 (in that case, to avoid loops, mpc_pow_exact
   should be called again with a larger value of maxprec).

   Assume one of Re(x) or Im(x) is non-zero, and y is non-zero (y is real).
*/
static int
mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd,
               mp_prec_t maxprec)
{
  mp_exp_t ec, ed, ey, emin, emax;
  mpz_t my, a, b, c, d, u;
  unsigned long int t;
  int ret = -2;

  mpz_init (my);
  mpz_init (a);
  mpz_init (b);
  mpz_init (c);
  mpz_init (d);
  mpz_init (u);

  ey = mpfr_get_z_exp (my, y);
  /* normalize so that my is odd */
  t = mpz_scan1 (my, 0);
  ey += t;
  mpz_tdiv_q_2exp (my, my, t);

  if (mpfr_zero_p (MPC_RE(x)))
    {
      mpz_set_ui (c, 0);
      ec = 0;
    }
  else
    ec = mpfr_get_z_exp (c, MPC_RE(x));
  if (mpfr_zero_p (MPC_IM(x)))
    {
      mpz_set_ui (d, 0);
      ed = ec;
    }
  else
    {
      ed = mpfr_get_z_exp (d, MPC_IM(x));
      if (mpfr_zero_p (MPC_RE(x)))
        ec = ed;
    }
  /* x = c*2^ec + I * d*2^ed */
  /* equalize the exponents of x */
  if (ec < ed)
    {
      mpz_mul_2exp (d, d, ed - ec);
      if (mpz_sizeinbase (d, 2) > maxprec)
        goto end;
      ed = ec;
    }
  else if (ed < ec)
    {
      mpz_mul_2exp (c, c, ec - ed);
      if (mpz_sizeinbase (c, 2) > maxprec)
        goto end;
      ec = ed;
    }
  /* now ec=ed and x = (c + I * d) * 2^ec */

  /* divide by two if possible */
  if (mpz_cmp_ui (c, 0) == 0)
    {
      t = mpz_scan1 (d, 0);
      mpz_tdiv_q_2exp (d, d, t);
      ec += t;
    }
  else if (mpz_cmp_ui (d, 0) == 0)
    {
      t = mpz_scan1 (c, 0);
      mpz_tdiv_q_2exp (c, c, t);
      ec += t;
    }
  else /* neither c nor d is zero */
    {
      unsigned long v;
      t = mpz_scan1 (c, 0);
      v = mpz_scan1 (d, 0);
      if (v < t)
        t = v;
      mpz_tdiv_q_2exp (c, c, t);
      mpz_tdiv_q_2exp (d, d, t);
      ec += t;
    }

  /* now either one of c, d is odd */

  while (ey < 0)
    {
      /* check if x is a square */
      if (ec & 1)
        {
          mpz_mul_2exp (c, c, 1);
          mpz_mul_2exp (d, d, 1);
          ec --;
        }
      /* now ec is even */
      if (mpc_perfect_square_p (a, b, c, d) == 0)
        break;
      mpz_swap (a, c);
      mpz_swap (b, d);
      ec /= 2;
      ey ++;
    }

  if (ey < 0)
    {
      ret = -1; /* not representable */
      goto end;
    }

  /* Now ey >= 0, it thus suffices to check that x^my is representable.
     If my > 0, this is always true. If my < 0, we first try to invert
     (c+I*d)*2^ec.
  */
  if (mpz_cmp_ui (my, 0) < 0)
    {
      /* If my < 0, 1 / (c + I*d) = (c - I*d)/(c^2 + d^2), thus a sufficient
         condition is that c^2 + d^2 is a power of two, assuming |c| <> |d|.
         Assume a prime p <> 2 divides c^2 + d^2,
         then if p does not divide c or d, 1 / (c + I*d) cannot be exact.
         If p divides both c and d, then we can write c = p*c', d = p*d',
         and 1 / (c + I*d) = 1/p * 1/(c' + I*d'). This shows that if 1/(c+I*d)
         is exact, then 1/(c' + I*d') is exact too, and we are back to the
         previous case. In conclusion, a necessary and sufficient condition
         is that c^2 + d^2 is a power of two.
      */
      /* FIXME: we could first compute c^2+d^2 mod a limb for example */
      mpz_mul (a, c, c);
      mpz_addmul (a, d, d);
      t = mpz_scan1 (a, 0);
      if (mpz_sizeinbase (a, 2) != 1 + t) /* a is not a power of two */
        {
          ret = -1; /* not representable */
          goto end;
        }
      /* replace (c,d) by (c/(c^2+d^2), -d/(c^2+d^2)) */
      mpz_neg (d, d);
      ec = -ec - t;
      mpz_neg (my, my);
    }

  /* now ey >= 0 and my >= 0, and we want to compute
     [(c + I * d) * 2^ec] ^ (my * 2^ey).

     We first compute [(c + I * d) * 2^ec]^my, then square ey times. */
  t = mpz_sizeinbase (my, 2) - 1;
  mpz_set (a, c);
  mpz_set (b, d);
  ed = ec;
  /* invariant: (a + I*b) * 2^ed = ((c + I*d) * 2^ec)^trunc(my/2^t) */
  while (t-- > 0)
    {
      unsigned long v, w;
      /* square a + I*b */
      mpz_mul (u, a, b);
      mpz_mul (a, a, a);
      mpz_submul (a, b, b);
      mpz_mul_2exp (b, u, 1);
      ed *= 2;
      if (mpz_tstbit (my, t)) /* multiply by c + I*d */
        {
          mpz_mul (u, a, c);
          mpz_submul (u, b, d); /* ac-bd */
          mpz_mul (b, b, c);
          mpz_addmul (b, a, d); /* bc+ad */
          mpz_swap (a, u);
          ed += ec;
        }
      /* remove powers of two in (a,b) */
      if (mpz_cmp_ui (a, 0) == 0)
        {
          w = mpz_scan1 (b, 0);
          mpz_tdiv_q_2exp (b, b, w);
          ed += w;
        }
      else if (mpz_cmp_ui (b, 0) == 0)
        {
          w = mpz_scan1 (a, 0);
          mpz_tdiv_q_2exp (a, a, w);
          ed += w;
        }
      else
        {
          w = mpz_scan1 (a, 0);
          v = mpz_scan1 (b, 0);
          if (v < w)
            w = v;
          mpz_tdiv_q_2exp (a, a, w);
          mpz_tdiv_q_2exp (b, b, w);
          ed += w;
        }
      if (mpz_sizeinbase (a, 2) > maxprec || mpz_sizeinbase (b, 2) > maxprec)
        goto end;
    }
  /* now a+I*b = (c+I*d)^my */

  while (ey-- > 0)
    {
      unsigned long sa, sb;

      /* square a + I*b */
      mpz_mul (u, a, b);
      mpz_mul (a, a, a);
      mpz_submul (a, b, b);
      mpz_mul_2exp (b, u, 1);
      ed *= 2;

      /* divide by largest 2^n possible, to avoid many loops for e.g.,
         (2+2*I)^16777216 */
      sa = mpz_scan1 (a, 0);
      sb = mpz_scan1 (b, 0);
      sa = (sa <= sb) ? sa : sb;
      mpz_tdiv_q_2exp (a, a, sa);
      mpz_tdiv_q_2exp (b, b, sa);
      ed += sa;

      if (mpz_sizeinbase (a, 2) > maxprec || mpz_sizeinbase (b, 2) > maxprec)
        goto end;
    }

  /* save emin, emax */
  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();
  mpfr_set_emin (mpfr_get_emin_min ());
  mpfr_set_emax (mpfr_get_emax_max ());
  ret = mpfr_set_z (MPC_RE(z), a, MPC_RND_RE(rnd));
  ret = MPC_INEX(ret, mpfr_set_z (MPC_IM(z), b, MPC_RND_IM(rnd)));
  mpfr_mul_2si (MPC_RE(z), MPC_RE(z), ed, MPC_RND_RE(rnd));
  mpfr_mul_2si (MPC_IM(z), MPC_IM(z), ed, MPC_RND_IM(rnd));
  /* restore emin, emax */
  mpfr_set_emin (emin);
  mpfr_set_emax (emax);

 end:
  mpz_clear (my);
  mpz_clear (a);
  mpz_clear (b);
  mpz_clear (c);
  mpz_clear (d);
  mpz_clear (u);

  return ret;
}
Пример #7
0
/* Test n random bad cases. A precision py in [pymin,pymax] and
 * a number y of precision py are chosen randomly. One computes
 * x = inv(y) in precision px = py + psup (rounded to nearest).
 * Then (in general), y is a bad case for fct in precision py (in
 * the directed rounding modes, but also in the rounding-to-nearest
 * mode for some lower precision: see data_check).
 * fct, inv, name: data related to the function.
 * pos, emin, emax: arguments for tests_default_random.
 * For debugging purpose (e.g. in case of crash or infinite loop),
 * you can set the MPFR_DEBUG_BADCASES environment variable to 1 in
 * order to output information about the tested worst cases. You can
 * also enable logging (when supported), but this may give too much
 * information.
 */
void
bad_cases (int (*fct)(FLIST), int (*inv)(FLIST), const char *name,
           int pos, mpfr_exp_t emin, mpfr_exp_t emax,
           mpfr_prec_t pymin, mpfr_prec_t pymax, mpfr_prec_t psup,
           int n)
{
  mpfr_t x, y, z;
  char *dbgenv;
  int i, dbg;
  mpfr_exp_t old_emin, old_emax;

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

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

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

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

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  mpfr_init (t);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  mpfr_init (u);
#endif

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

      /* Note: in precision p1, we test 4 special cases. */
      for (n = 0; n < (prec == p1 ? N + 4 : N); n++)
        {
          xprec = prec;
          if (randlimb () & 1)
            {
              xprec *= (double) randlimb () / MP_LIMB_T_MAX;
              if (xprec < MPFR_PREC_MIN)
                xprec = MPFR_PREC_MIN;
            }
          mpfr_set_prec (x, xprec);
#ifdef TWO_ARGS
          mpfr_set_prec (u, xprec);
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
          mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
#endif

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

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

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

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

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (t);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  mpfr_clear (u);
#endif
}
Пример #9
0
static void
test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
{
  mpfr_prec_t prec, xprec, yprec;
  mpfr_t x, y, z, t, w;
#if defined(TWO_ARGS_ALL)
  mpfr_t u;
#endif
#if defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  double d;
#endif
#if defined(ULONG_ARG1) || defined(ULONG_ARG2)
  unsigned long i;
#endif
  mpfr_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n;
  unsigned long ctrt = 0, ctrn = 0;
  int test_of = 1, test_uf = 1;
  mpfr_exp_t old_emin, old_emax;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  mpfr_clears (x, y, z, t, w, (mpfr_ptr) 0);
#if defined(TWO_ARGS_ALL)
  mpfr_clear (u);
#endif
}
Пример #10
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y;
  mpfr_exp_t emin, emax;

  tests_start_mpfr ();

  test_set_underflow ();
  test_set_overflow ();
  check_default_rnd();

  mpfr_init (x);
  mpfr_init (y);

  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();
  if (emin >= emax)
    {
      printf ("Error: emin >= emax\n");
      exit (1);
    }

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
  mpfr_set_double_range ();
  mpfr_check_range (x, 0, MPFR_RNDN);
  if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
    {
      printf ("Error: 2^1024 rounded to nearest should give +Inf\n");
      exit (1);
    }

  set_emax (1025);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
  mpfr_set_double_range ();
  mpfr_check_range (x, 0, MPFR_RNDD);
  if (!mpfr_number_p (x))
    {
      printf ("Error: 2^1024 rounded down should give a normal number\n");
      exit (1);
    }

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_mul_2exp (x, x, 1023, MPFR_RNDN);
  mpfr_add (x, x, x, MPFR_RNDN);
  if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
    {
      printf ("Error: x+x rounded to nearest for x=2^1023 should give +Inf\n");
      printf ("emax = %ld\n", (long) mpfr_get_emax ());
      printf ("got "); mpfr_print_binary (x); puts ("");
      exit (1);
    }

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_mul_2exp (x, x, 1023, MPFR_RNDN);
  mpfr_add (x, x, x, MPFR_RNDD);
  if (!mpfr_number_p (x))
    {
      printf ("Error: x+x rounded down for x=2^1023 should give"
              " a normal number\n");
      exit (1);
    }

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_div_2exp (x, x, 1022, MPFR_RNDN);
  mpfr_set_str_binary (y, "1.1e-1022"); /* y = 3/2*x */
  mpfr_sub (y, y, x, MPFR_RNDZ);
  if (mpfr_cmp_ui (y, 0))
    {
      printf ("Error: y-x rounded to zero should give 0"
              " for y=3/2*2^(-1022), x=2^(-1022)\n");
      printf ("y="); mpfr_print_binary (y); puts ("");
      exit (1);
    }

  set_emin (-1026);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_div_2exp (x, x, 1025, MPFR_RNDN);
  mpfr_set_double_range ();
  mpfr_check_range (x, 0, MPFR_RNDN);
  if (!MPFR_IS_ZERO (x) )
    {
      printf ("Error: x rounded to nearest for x=2^-1024 should give Zero\n");
      printf ("emin = %ld\n", (long) mpfr_get_emin ());
      printf ("got "); mpfr_dump (x);
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);

  set_emin (emin);
  set_emax (emax);

  check_emin_emax();
  check_flags();
  check_set_get_prec ();
  check_powerof2 ();
  check_set ();
  check_groups ();

  tests_end_mpfr ();
  return 0;
}
Пример #11
0
static void
special (void)
{
  mpfr_t x, y;
  int inex;
  mpfr_exp_t emin, emax;

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

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

  /* Check special case: An overflow in const_pi could occurs! */
  set_emin (-125);
  set_emax (128);
  mpfr_set_prec (y, 24*2);
  mpfr_set_prec (x, 24);
  mpfr_set_str_binary (x, "0.111110101010101011110101E0");
  test_log (y, x, MPFR_RNDN);
  set_emin (emin);
  set_emax (emax);

  mpfr_set_prec (y, 53);
  mpfr_set_prec (x, 53);
  mpfr_set_ui (x, 3, MPFR_RNDD);
  test_log (y, x, MPFR_RNDD);
  if (mpfr_cmp_str1 (y, "1.09861228866810956"))
    {
      printf ("Error in mpfr_log(3) for MPFR_RNDD\n");
      exit (1);
    }

  /* check large precision */
  mpfr_set_prec (x, 3322);
  mpfr_set_prec (y, 3322);
  mpfr_set_ui (x, 3, MPFR_RNDN);
  mpfr_sqrt (x, x, MPFR_RNDN);
  test_log (y, x, MPFR_RNDN);

  /* negative argument */
  mpfr_set_si (x, -1, MPFR_RNDN);
  test_log (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_nan_p (y));

  /* infinite loop when  */
  set_emax (128);
  mpfr_set_prec (x, 251);
  mpfr_set_prec (y, 251);
  mpfr_set_str_binary (x, "0.10010111000000000001101E8");
  /* x = 4947981/32768, log(x) ~ 5.017282... */
  test_log (y, x, MPFR_RNDN);

  set_emax (emax);

  mpfr_set_ui (x, 0, MPFR_RNDN);
  inex = test_log (y, x, MPFR_RNDN);
  MPFR_ASSERTN (inex == 0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (mpfr_sgn (y) < 0);

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_neg (x, x, MPFR_RNDN);
  inex = test_log (y, x, MPFR_RNDN);
  MPFR_ASSERTN (inex == 0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (mpfr_sgn (y) < 0);

  mpfr_clear (x);
  mpfr_clear (y);
}
Пример #12
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;
}
Пример #13
0
static void
large_arg (void)
{
  mpfr_t x, y;
  unsigned int flags;

  mpfr_init2 (x, 88);
  mpfr_init2 (y, 98);

  mpfr_set_si_2exp (x, -1, 173, MPFR_RNDN);
  mpfr_clear_flags ();
  mpfr_erfc (y, x, MPFR_RNDN);
  flags = __gmpfr_flags;
  if (mpfr_cmp_ui (y, 2) != 0)
    {
      printf ("mpfr_erfc failed for large x (1)\n");
      exit (1);
    }
  if (flags != MPFR_FLAGS_INEXACT)
    {
      printf ("mpfr_erfc sets incorrect flags for large x (1)\n");
      printf ("Expected %u, got %u\n",
              (unsigned int) MPFR_FLAGS_INEXACT, flags);
      exit (1);
    }

  mpfr_set_si_2exp (x, -1, mpfr_get_emax () - 3, MPFR_RNDN);
  mpfr_clear_flags ();
  mpfr_erfc (y, x, MPFR_RNDN);
  flags = __gmpfr_flags;
  if (mpfr_cmp_ui (y, 2) != 0)
    {
      printf ("mpfr_erfc failed for large x (1b)\n");
      exit (1);
    }
  if (flags != MPFR_FLAGS_INEXACT)
    {
      printf ("mpfr_erfc sets incorrect flags for large x (1b)\n");
      printf ("Expected %u, got %u\n",
              (unsigned int) MPFR_FLAGS_INEXACT, flags);
      exit (1);
    }

  mpfr_set_prec (x, 33);
  mpfr_set_prec (y, 43);
  mpfr_set_str_binary (x, "1.11000101010111011000111100101001e6");
  mpfr_erfc (y, x, MPFR_RNDD);
  mpfr_set_prec (x, 43);
  mpfr_set_str_binary (x, "100010011100101100001101100101011101101E-18579");
  if (mpfr_cmp (x, y) != 0)
    {
      printf ("mpfr_erfc failed for large x (2)\n");
      exit (1);
    }

  mpfr_set_prec (y, 43);
  mpfr_set_si_2exp (x, 1, 11, MPFR_RNDN);
  mpfr_erfc (y, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.1100000100100010101111001111010010001000110E-6051113");
  if (mpfr_cmp (x, y) != 0)
    {
      printf ("mpfr_erfc failed for large x (3)\n");
      exit (1);
    }

  mpfr_set_prec (x, 75);
  mpfr_set_prec (y, 85);
  mpfr_set_str_binary (x, "0.111110111111010011101011001100001010011110101010011111010010111101010001011E15");
  mpfr_erfc (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
      printf ("mpfr_erfc failed for large x (3b)\n");
      exit (1);
    }

  mpfr_set_prec (x, 2);
  mpfr_set_prec (y, 21);
  mpfr_set_str_binary (x, "-1.0e3");
  mpfr_clear_flags ();
  mpfr_erfc (y, x, MPFR_RNDZ);
  flags = __gmpfr_flags;
  mpfr_set_prec (x, 21);
  mpfr_set_str_binary (x, "1.11111111111111111111");
  if (mpfr_cmp (x, y) != 0)
    {
      printf ("mpfr_erfc failed for large x (4)\n");
      exit (1);
    }
  if (flags != MPFR_FLAGS_INEXACT)
    {
      printf ("mpfr_erfc sets incorrect flags for large x (4)\n");
      printf ("Expected %u, got %u\n",
              (unsigned int) MPFR_FLAGS_INEXACT, flags);
      exit (1);
    }

  mpfr_set_prec (x, 2);
  mpfr_set_prec (y, 31);
  mpfr_set_str_binary (x, "-1.0e3");
  mpfr_clear_flags ();
  mpfr_erfc (y, x, MPFR_RNDZ);
  flags = __gmpfr_flags;
  mpfr_set_prec (x, 31);
  mpfr_set_str_binary (x, "1.111111111111111111111111111111");
  if (mpfr_cmp (x, y) != 0)
    {
      printf ("mpfr_erfc failed for x=-8, prec=31 (5)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }
  if (flags != MPFR_FLAGS_INEXACT)
    {
      printf ("mpfr_erfc sets incorrect flags for large x (5)\n");
      printf ("Expected %u, got %u\n",
              (unsigned int) MPFR_FLAGS_INEXACT, flags);
      exit (1);
    }

  /* Reported by Christopher Creutzig on 2007-07-10. */
  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);
  mpfr_set_si_2exp (x, 54563, -1, MPFR_RNDN);
  mpfr_erfc (y, x, MPFR_RNDZ);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  if (! mpfr_equal_p (y, x))
    {
      printf ("mpfr_erfc failed for x=27281.5, prec=53 (6)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }

  /* same test with rounding away from zero */
  mpfr_set_si_2exp (x, 54563, -1, MPFR_RNDN);
  mpfr_erfc (y, x, MPFR_RNDU);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_nextabove (x);
  if (! mpfr_equal_p (y, x))
    {
      printf ("mpfr_erfc failed for x=27281.5, prec=53 (7)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
Пример #14
0
static void
special (void)
{
  mpfr_t x, y;
  mpfr_exp_t emax;

  mpfr_init (x);
  mpfr_init (y);

  mpfr_set_nan (x);
  mpfr_rint (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_nan_p (y));

  mpfr_set_inf (x, 1);
  mpfr_rint (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);

  mpfr_set_inf (x, -1);
  mpfr_rint (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) < 0);

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_rint (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y));

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_neg (x, x, MPFR_RNDN);
  mpfr_rint (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG(y));

  /* coverage test */
  mpfr_set_prec (x, 2);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_mul_2exp (x, x, mp_bits_per_limb, MPFR_RNDN);
  mpfr_rint (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp (y, x) == 0);

  /* another coverage test */
  emax = mpfr_get_emax ();
  set_emax (1);
  mpfr_set_prec (x, 3);
  mpfr_set_str_binary (x, "1.11E0");
  mpfr_set_prec (y, 2);
  mpfr_rint (y, x, MPFR_RNDU); /* x rounds to 1.0E1=0.1E2 which overflows */
  MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
  set_emax (emax);

  /* yet another */
  mpfr_set_prec (x, 97);
  mpfr_set_prec (y, 96);
  mpfr_set_str_binary (x, "-0.1011111001101111000111011100011100000110110110110000000111010001000101001111101010101011010111100E97");
  mpfr_rint (y, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp (y, x) == 0);

  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);
  mpfr_set_str_binary (x, "0.10101100000000101001010101111111000000011111010000010E-1");
  mpfr_rint (y, x, MPFR_RNDU);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
  mpfr_rint (y, x, MPFR_RNDD);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y));

  mpfr_set_prec (x, 36);
  mpfr_set_prec (y, 2);
  mpfr_set_str_binary (x, "-11000110101010111111110111001.0000100");
  mpfr_rint (y, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "-11E27");
  MPFR_ASSERTN(mpfr_cmp (y, x) == 0);

  mpfr_set_prec (x, 39);
  mpfr_set_prec (y, 29);
  mpfr_set_str_binary (x, "-0.100010110100011010001111001001001100111E39");
  mpfr_rint (y, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "-0.10001011010001101000111100101E39");
  MPFR_ASSERTN(mpfr_cmp (y, x) == 0);

  mpfr_set_prec (x, 46);
  mpfr_set_prec (y, 32);
  mpfr_set_str_binary (x, "-0.1011100110100101000001011111101011001001101001E32");
  mpfr_rint (y, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "-0.10111001101001010000010111111011E32");
  MPFR_ASSERTN(mpfr_cmp (y, x) == 0);

  /* coverage test for mpfr_round */
  mpfr_set_prec (x, 3);
  mpfr_set_str_binary (x, "1.01E1"); /* 2.5 */
  mpfr_set_prec (y, 2);
  mpfr_round (y, x);
  /* since mpfr_round breaks ties away, should give 3 and not 2 as with
     the "round to even" rule */
  MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0);
  /* same test for the function */
  (mpfr_round) (y, x);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0);

  mpfr_set_prec (x, 6);
  mpfr_set_prec (y, 3);
  mpfr_set_str_binary (x, "110.111");
  mpfr_round (y, x);
  if (mpfr_cmp_ui (y, 7))
    {
      printf ("Error in round(110.111)\n");
      exit (1);
    }

  /* Bug found by  Mark J Watkins */
  mpfr_set_prec (x, 84);
  mpfr_set_str_binary (x,
   "0.110011010010001000000111101101001111111100101110010000000000000" \
                       "000000000000000000000E32");
  mpfr_round (x, x);
  if (mpfr_cmp_str (x, "0.1100110100100010000001111011010100000000000000" \
                    "00000000000000000000000000000000000000E32", 2, MPFR_RNDN))
    {
      printf ("Rounding error when dest=src\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
Пример #15
0
static void
test_large_small (void)
{
  mpfr_t x, y, z;
  int inexact, inex2, r;

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

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

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

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

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Пример #16
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);
}
Пример #17
0
static void
special_overflow (void)
{
  mpfr_t x, y;
  int i;
  mp_exp_t emin, emax;

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

  mpfr_clear_overflow ();
  set_emin (-125);
  set_emax (128);
  mpfr_init2 (x, 24);
  mpfr_init2 (y, 24);

  mpfr_set_str_binary (x, "0.101100100000000000110100E7");
  i = mpfr_tanh (y, x, GMP_RNDN);
  if (mpfr_cmp_ui (y, 1) || i != 1)
    {
      printf("Overflow error (1). i=%d\ny=", i);
      mpfr_dump (y);
      exit (1);
    }
  MPFR_ASSERTN (!mpfr_overflow_p ());

  i = mpfr_tanh (y, x, GMP_RNDZ);
  if (mpfr_cmp_str (y, "0.111111111111111111111111E0", 2, GMP_RNDN)
      || i != -1)
    {
      printf("Overflow error (2).i=%d\ny=", i);
      mpfr_dump (y);
      exit (1);
    }
  MPFR_ASSERTN (!mpfr_overflow_p ());

  set_emin (emin);
  set_emax (emax);

  mpfr_set_str_binary (x, "0.1E1000000000");
  i = mpfr_tanh (y, x, GMP_RNDN);
  if (mpfr_cmp_ui (y, 1) || i != 1)
    {
      printf("Overflow error (3). i=%d\ny=", i);
      mpfr_dump (y);
      exit (1);
    }
  MPFR_ASSERTN (!mpfr_overflow_p ());
  mpfr_set_str_binary (x, "-0.1E1000000000");
  i = mpfr_tanh (y, x, GMP_RNDU);
  if (mpfr_cmp_str (y, "-0.111111111111111111111111E0", 2, GMP_RNDN)
      || i != 1)
    {
      printf("Overflow error (4). i=%d\ny=", i);
      mpfr_dump (y);
      exit (1);
    }

  mpfr_clear (y);
  mpfr_clear (x);
}
Пример #18
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);
}
Пример #19
0
static void
check1 (void)
{
  mpfr_t x;
  int i, j, k, s, old_inex, tiny, expj;
  mpfr_exp_t emin, emax;
  unsigned int expflags, flags;

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

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

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

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

  set_emin (emin);
  set_emax (emax);
}
Пример #20
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y, z, s;
  mpfr_exp_t emin, emax;

  tests_start_mpfr ();

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

  bug20101018 ();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    mpfr_init (t);
    mpfr_init (slong);

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

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

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

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

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

  test_exact ();

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

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

  tests_end_mpfr ();
  return 0;
}
Пример #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);
}
Пример #22
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y;
  mpfr_exp_t emin, emax;
  int inex, ov;

  tests_start_mpfr ();

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

  mpfr_init (x);
  mpfr_init (y);

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

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

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

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

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

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

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

  test_generic (2, 100, 100);

  mpfr_clear (x);
  mpfr_clear (y);

  overfl_exp10_0 ();

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

  tests_end_mpfr ();
  return 0;
}
Пример #23
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);
}
Пример #24
0
inline ExponentType<BigFloat>
MaxExponent<BigFloat>( const BigFloat& alpha )
{ return mpfr_get_emax(); }
Пример #25
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);
}
Пример #26
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);
}
Пример #27
0
static void
check_pow_si (void)
{
    mpfr_t x;

    mpfr_init (x);

    mpfr_set_nan (x);
    mpfr_pow_si (x, x, -1, GMP_RNDN);
    MPFR_ASSERTN(mpfr_nan_p (x));

    mpfr_set_inf (x, 1);
    mpfr_pow_si (x, x, -1, GMP_RNDN);
    MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));

    mpfr_set_inf (x, -1);
    mpfr_pow_si (x, x, -1, GMP_RNDN);
    MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG(x));

    mpfr_set_inf (x, -1);
    mpfr_pow_si (x, x, -2, GMP_RNDN);
    MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));

    mpfr_set_ui (x, 0, GMP_RNDN);
    mpfr_pow_si (x, x, -1, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);

    mpfr_set_ui (x, 0, GMP_RNDN);
    mpfr_neg (x, x, GMP_RNDN);
    mpfr_pow_si (x, x, -1, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);

    mpfr_set_ui (x, 0, GMP_RNDN);
    mpfr_neg (x, x, GMP_RNDN);
    mpfr_pow_si (x, x, -2, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);

    mpfr_set_si (x, 2, GMP_RNDN);
    mpfr_pow_si (x, x, LONG_MAX, GMP_RNDN);  /* 2^LONG_MAX */
    if (LONG_MAX > mpfr_get_emax () - 1)  /* LONG_MAX + 1 > emax */
    {
        MPFR_ASSERTN (mpfr_inf_p (x));
    }
    else
    {
        MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, LONG_MAX));
    }

    mpfr_set_si (x, 2, GMP_RNDN);
    mpfr_pow_si (x, x, LONG_MIN, GMP_RNDN);  /* 2^LONG_MIN */
    if (LONG_MIN + 1 < mpfr_get_emin ())
    {
        MPFR_ASSERTN (mpfr_zero_p (x));
    }
    else
    {
        MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, LONG_MIN));
    }

    mpfr_set_si (x, 2, GMP_RNDN);
    mpfr_pow_si (x, x, LONG_MIN + 1, GMP_RNDN);  /* 2^(LONG_MIN+1) */
    if (mpfr_nan_p (x))
    {
        printf ("Error in pow_si(2, LONG_MIN+1): got NaN\n");
        exit (1);
    }
    if (LONG_MIN + 2 < mpfr_get_emin ())
    {
        MPFR_ASSERTN (mpfr_zero_p (x));
    }
    else
    {
        MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, LONG_MIN + 1));
    }

    mpfr_set_si_2exp (x, 1, -1, GMP_RNDN);  /* 0.5 */
    mpfr_pow_si (x, x, LONG_MIN, GMP_RNDN);  /* 2^(-LONG_MIN) */
    if (LONG_MIN < 1 - mpfr_get_emax ())  /* 1 - LONG_MIN > emax */
    {
        MPFR_ASSERTN (mpfr_inf_p (x));
    }
    else
    {
        MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 2, - (LONG_MIN + 1)));
    }

    mpfr_clear (x);
}
Пример #28
0
int
main (int argc, char *argv[])
{
  int b;
  mpfr_t x;
  mpfr_rnd_t r;
  char s[MAX_DIGITS + 2];
  mpfr_exp_t e, f;
  size_t m;
  mpfr_prec_t p;
  int i;

  tests_start_mpfr ();

  check_small ();

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

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

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

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

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

  check_bug_base2k ();
  check_reduced_exprange ();

  tests_end_mpfr ();
  return 0;
}
Пример #29
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);
}
Пример #30
0
/* tgeneric(prec_min, prec_max, step, exp_max) checks rounding with random
   numbers:
   - with precision ranging from prec_min to prec_max with an increment of
   step,
   - with exponent between -exp_max and exp_max.

   It also checks parameter reuse (it is assumed here that either two mpc_t
   variables are equal or they are different, in the sense that the real part
   of one of them cannot be the imaginary part of the other). */
void
tgeneric (mpc_function function, mpfr_prec_t prec_min,
          mpfr_prec_t prec_max, mpfr_prec_t step, mpfr_exp_t exp_max)
{
  unsigned long ul1 = 0, ul2 = 0;
  long lo = 0;
  int i = 0;
  mpfr_t x1, x2, xxxx;
  mpc_t  z1, z2, z3, z4, z5, zzzz, zzzz2;

  mpfr_rnd_t rnd_re, rnd_im, rnd2_re, rnd2_im;
  mpfr_prec_t prec;
  mpfr_exp_t exp_min;
  int special, special_cases;

  mpc_init2 (z1, prec_max);
  switch (function.type)
    {
    case C_CC:
      mpc_init2 (z2, prec_max);
      mpc_init2 (z3, prec_max);
      mpc_init2 (z4, prec_max);
      mpc_init2 (zzzz, 4*prec_max);
      special_cases = 8;
      break;
    case CCCC:
      mpc_init2 (z2, prec_max);
      mpc_init2 (z3, prec_max);
      mpc_init2 (z4, prec_max);
      mpc_init2 (z5, prec_max);
      mpc_init2 (zzzz, 4*prec_max);
      special_cases = 8;
      break;
    case FC:
      mpfr_init2 (x1, prec_max);
      mpfr_init2 (x2, prec_max);
      mpfr_init2 (xxxx, 4*prec_max);
      mpc_init2 (z2, prec_max);
      special_cases = 4;
      break;
    case CCF: case CFC:
      mpfr_init2 (x1, prec_max);
      mpc_init2 (z2, prec_max);
      mpc_init2 (z3, prec_max);
      mpc_init2 (zzzz, 4*prec_max);
      special_cases = 6;
      break;
    case CCI: case CCS:
    case CCU: case CUC:
      mpc_init2 (z2, prec_max);
      mpc_init2 (z3, prec_max);
      mpc_init2 (zzzz, 4*prec_max);
      special_cases = 5;
      break;
    case CUUC:
      mpc_init2 (z2, prec_max);
      mpc_init2 (z3, prec_max);
      mpc_init2 (zzzz, 4*prec_max);
      special_cases = 6;
      break;
    case CC_C:
      mpc_init2 (z2, prec_max);
      mpc_init2 (z3, prec_max);
      mpc_init2 (z4, prec_max);
      mpc_init2 (z5, prec_max);
      mpc_init2 (zzzz, 4*prec_max);
      mpc_init2 (zzzz2, 4*prec_max);
      special_cases = 4;
      break;
    case CC:
    default:
      mpc_init2 (z2, prec_max);
      mpc_init2 (z3, prec_max);
      mpc_init2 (zzzz, 4*prec_max);
      special_cases = 4;
    }

  exp_min = mpfr_get_emin ();
  if (exp_max <= 0 || exp_max > mpfr_get_emax ())
    exp_max = mpfr_get_emax();
  if (-exp_max > exp_min)
    exp_min = - exp_max;

  if (step < 1)
    step = 1;

  for (prec = prec_min, special = 0;
       prec <= prec_max || special <= special_cases;
       prec+=step, special += (prec > prec_max ? 1 : 0)) {
       /* In the end, test functions in special cases of purely real, purely
          imaginary or infinite arguments. */

      /* probability of one zero part in 256th (25 is almost 10%) */
      const unsigned int zero_probability = special != 0 ? 0 : 25;

      mpc_set_prec (z1, prec);
      test_default_random (z1, exp_min, exp_max, 128, zero_probability);

      switch (function.type)
        {
        case C_CC:
          mpc_set_prec (z2, prec);
          test_default_random (z2, exp_min, exp_max, 128, zero_probability);
          mpc_set_prec (z3, prec);
          mpc_set_prec (z4, prec);
          mpc_set_prec (zzzz, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            case 5:
              mpfr_set_ui (mpc_realref (z2), 0, MPFR_RNDN);
              break;
            case 6:
              mpfr_set_inf (mpc_realref (z2), -1);
              break;
            case 7:
              mpfr_set_ui (mpc_imagref (z2), 0, MPFR_RNDN);
              break;
            case 8:
              mpfr_set_inf (mpc_imagref (z2), +1);
              break;
            }
          break;
        case CCCC:
          mpc_set_prec (z2, prec);
          test_default_random (z2, exp_min, exp_max, 128, zero_probability);
          mpc_set_prec (z3, prec);
          mpc_set_prec (z4, prec);
          mpc_set_prec (z5, prec);
          mpc_set_prec (zzzz, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            case 5:
              mpfr_set_ui (mpc_realref (z2), 0, MPFR_RNDN);
              break;
            case 6:
              mpfr_set_inf (mpc_realref (z2), -1);
              break;
            case 7:
              mpfr_set_ui (mpc_imagref (z2), 0, MPFR_RNDN);
              break;
            case 8:
              mpfr_set_inf (mpc_imagref (z2), +1);
              break;
            }
          break;
        case FC:
          mpc_set_prec (z2, prec);
          mpfr_set_prec (x1, prec);
          mpfr_set_prec (x2, prec);
          mpfr_set_prec (xxxx, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            }
          break;
        case CCU: case CUC:
          mpc_set_prec (z2, 128);
          do {
            test_default_random (z2, 0, 64, 128, zero_probability);
          } while (!mpfr_fits_ulong_p (mpc_realref (z2), MPFR_RNDN));
          ul1 = mpfr_get_ui (mpc_realref(z2), MPFR_RNDN);
          mpc_set_prec (z2, prec);
          mpc_set_prec (z3, prec);
          mpc_set_prec (zzzz, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            case 5:
              ul1 = 0;
              break;
            }
          break;
        case CUUC:
          mpc_set_prec (z2, 128);
          do {
            test_default_random (z2, 0, 64, 128, zero_probability);
          } while (!mpfr_fits_ulong_p (mpc_realref (z2), MPFR_RNDN)
                   ||!mpfr_fits_ulong_p (mpc_imagref (z2), MPFR_RNDN));
          ul1 = mpfr_get_ui (mpc_realref(z2), MPFR_RNDN);
          ul2 = mpfr_get_ui (mpc_imagref(z2), MPFR_RNDN);
          mpc_set_prec (z2, prec);
          mpc_set_prec (z3, prec);
          mpc_set_prec (zzzz, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            case 5:
              ul1 = 0;
              break;
            case 6:
              ul2 = 0;
              break;
            }
          break;
        case CCS:
          mpc_set_prec (z2, 128);
          do {
            test_default_random (z2, 0, 64, 128, zero_probability);
          } while (!mpfr_fits_slong_p (mpc_realref (z2), MPFR_RNDN));
          lo = mpfr_get_si (mpc_realref(z2), MPFR_RNDN);
          mpc_set_prec (z2, prec);
          mpc_set_prec (z3, prec);
          mpc_set_prec (zzzz, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            case 5:
              lo = 0;
              break;
            }
          break;
        case CCI:
          mpc_set_prec (z2, 128);
          do {
            test_default_random (z2, 0, 64, 128, zero_probability);
          } while (!mpfr_fits_slong_p (mpc_realref (z2), MPFR_RNDN));
          i = (int)mpfr_get_si (mpc_realref(z2), MPFR_RNDN);
          mpc_set_prec (z2, prec);
          mpc_set_prec (z3, prec);
          mpc_set_prec (zzzz, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            case 5:
              i = 0;
              break;
            }
          break;
        case CCF: case CFC:
          mpfr_set_prec (x1, prec);
          mpfr_set (x1, mpc_realref (z1), MPFR_RNDN);
          test_default_random (z1, exp_min, exp_max, 128, zero_probability);
          mpc_set_prec (z2, prec);
          mpc_set_prec (z3, prec);
          mpc_set_prec (zzzz, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            case 5:
              mpfr_set_ui (x1, 0, MPFR_RNDN);
              break;
            case 6:
              mpfr_set_inf (x1, +1);
              break;
            }
          break;
        case CC_C:
          mpc_set_prec (z2, prec);
          mpc_set_prec (z3, prec);
          mpc_set_prec (z4, prec);
          mpc_set_prec (z5, prec);
          mpc_set_prec (zzzz, 4*prec);
          mpc_set_prec (zzzz2, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            }
          break;
        case CC:
        default:
          mpc_set_prec (z2, prec);
          mpc_set_prec (z3, prec);
          mpc_set_prec (zzzz, 4*prec);
          switch (special)
            {
            case 1:
              mpfr_set_ui (mpc_realref (z1), 0, MPFR_RNDN);
              break;
            case 2:
              mpfr_set_inf (mpc_realref (z1), +1);
              break;
            case 3:
              mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
              break;
            case 4:
              mpfr_set_inf (mpc_imagref (z1), -1);
              break;
            }
        }

      for (rnd_re = first_rnd_mode (); is_valid_rnd_mode (rnd_re); rnd_re = next_rnd_mode (rnd_re))
        switch (function.type)
          {
          case C_CC:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_c_cc (&function, z1, z2, z3, zzzz, z4,
			     MPC_RND (rnd_re, rnd_im));
            reuse_c_cc (&function, z1, z2, z3, z4);
            break;
          case CCCC:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_cccc (&function, z1, z2, z3, z4, zzzz, z5,
                            MPC_RND (rnd_re, rnd_im));
            reuse_cccc (&function, z1, z2, z3, z4, z5);
            break;
          case FC:
            tgeneric_fc (&function, z1, x1, xxxx, x2, rnd_re);
            reuse_fc (&function, z1, z2, x1);
            break;
          case CC:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_cc (&function, z1, z2, zzzz, z3,
                           MPC_RND (rnd_re, rnd_im));
            reuse_cc (&function, z1, z2, z3);
            break;
          case CC_C:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
               for (rnd2_re = first_rnd_mode (); is_valid_rnd_mode (rnd2_re); rnd2_re = next_rnd_mode (rnd2_re))
                  for (rnd2_im = first_rnd_mode (); is_valid_rnd_mode (rnd2_im); rnd2_im = next_rnd_mode (rnd2_im))
                     tgeneric_cc_c (&function, z1, z2, z3, zzzz, zzzz2, z4, z5,
                           MPC_RND (rnd_re, rnd_im), MPC_RND (rnd2_re, rnd2_im));
             reuse_cc_c (&function, z1, z2, z3, z4, z5);
            break;
          case CFC:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_cfc (&function, x1, z1, z2, zzzz, z3,
                            MPC_RND (rnd_re, rnd_im));
            reuse_cfc (&function, z1, x1, z2, z3);
            break;
          case CCF:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_ccf (&function, z1, x1, z2, zzzz, z3,
                            MPC_RND (rnd_re, rnd_im));
            reuse_ccf (&function, z1, x1, z2, z3);
            break;
          case CCU:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_ccu (&function, z1, ul1, z2, zzzz, z3,
                            MPC_RND (rnd_re, rnd_im));
            reuse_ccu (&function, z1, ul1, z2, z3);
            break;
          case CUC:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_cuc (&function, ul1, z1, z2, zzzz, z3,
                            MPC_RND (rnd_re, rnd_im));
            reuse_cuc (&function, ul1, z1, z2, z3);
            break;
          case CCS:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_ccs (&function, z1, lo, z2, zzzz, z3,
                            MPC_RND (rnd_re, rnd_im));
            reuse_ccs (&function, z1, lo, z2, z3);
            break;
          case CCI:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_cci (&function, z1, i, z2, zzzz, z3,
                            MPC_RND (rnd_re, rnd_im));
            reuse_cci (&function, z1, i, z2, z3);
            break;
          case CUUC:
            for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
              tgeneric_cuuc (&function, ul1, ul2, z1, z2, zzzz, z3,
                             MPC_RND (rnd_re, rnd_im));
            reuse_cuuc (&function, ul1, ul2, z1, z2, z3);
            break;
          default:
            printf ("tgeneric not yet implemented for this kind of"
                    "function\n");
            exit (1);
          }
    }

  mpc_clear (z1);
  switch (function.type)
    {
    case C_CC:
      mpc_clear (z2);
      mpc_clear (z3);
      mpc_clear (z4);
      mpc_clear (zzzz);
      break;
    case CCCC:
      mpc_clear (z2);
      mpc_clear (z3);
      mpc_clear (z4);
      mpc_clear (z5);
      mpc_clear (zzzz);
      break;
    case FC:
      mpc_clear (z2);
      mpfr_clear (x1);
      mpfr_clear (x2);
      mpfr_clear (xxxx);
      break;
    case CCF: case CFC:
      mpfr_clear (x1);
      mpc_clear (z2);
      mpc_clear (z3);
      mpc_clear (zzzz);
      break;
    case CC_C:
      mpc_clear (z2);
      mpc_clear (z3);
      mpc_clear (z4);
      mpc_clear (z5);
      mpc_clear (zzzz);
      mpc_clear (zzzz2);
      break;
    case CUUC:
    case CCI: case CCS:
    case CCU: case CUC:
    case CC:
    default:
      mpc_clear (z2);
      mpc_clear (z3);
      mpc_clear (zzzz);
    }
}