Esempio n. 1
0
int
mpfr_max (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
{
  if (MPFR_IS_NAN(x) && MPFR_IS_NAN(y) ) 
    {  
      MPFR_SET_NAN(z);
      MPFR_RET_NAN;
    }
  MPFR_CLEAR_NAN(z);

  if (MPFR_IS_NAN(x))
    return mpfr_set(z, y, rnd_mode);

  if (MPFR_IS_NAN(y))
    return mpfr_set(z, x, rnd_mode);

  if (MPFR_IS_FP(x) && MPFR_IS_ZERO(x) && MPFR_IS_FP(y) && MPFR_IS_ZERO(y))
    {
      if (MPFR_SIGN(x) < 0)
        return mpfr_set(z, y, rnd_mode);
      else
        return mpfr_set(z, x, rnd_mode);
    }

  if (mpfr_cmp(x,y) <= 0)
    return mpfr_set(z, y, rnd_mode);
  else
    return mpfr_set(z, x, rnd_mode);
}
Esempio n. 2
0
static mpfr_prec_t
get_prec_max (mpfr_t *tab, unsigned long n, mpfr_prec_t f)
{
  mpfr_prec_t res;
  mpfr_exp_t min, max;
  unsigned long i;

  i = 0;
  while (MPFR_IS_ZERO (tab[i]))
    {
      i++;
      if (i == n)
        return MPFR_PREC_MIN;  /* all values are 0 */
    }

  if (! mpfr_check (tab[i]))
    {
      printf ("tab[%lu] is not valid.\n", i);
      exit (1);
    }
  MPFR_ASSERTN (MPFR_IS_FP (tab[i]));
  min = max = MPFR_GET_EXP(tab[i]);
  for (i++; i < n; i++)
    {
      if (! mpfr_check (tab[i]))
        {
          printf ("tab[%lu] is not valid.\n", i);
          exit (1);
        }
      MPFR_ASSERTN (MPFR_IS_FP (tab[i]));
      if (! MPFR_IS_ZERO (tab[i]))
        {
          if (MPFR_GET_EXP(tab[i]) > max)
            max = MPFR_GET_EXP(tab[i]);
          if (MPFR_GET_EXP(tab[i]) < min)
            min = MPFR_GET_EXP(tab[i]);
        }
    }
  res = max - min;
  res += f;
  res += __gmpfr_ceil_log2 (n) + 1;
  return res;
}
Esempio n. 3
0
int
mpfr_check_range (mpfr_ptr x, mp_rnd_t rnd_mode)
{
  if (MPFR_IS_FP(x) && MPFR_NOTZERO(x))
    { /* x is a non-zero FP */
      mp_exp_t exp = MPFR_EXP(x);
      if (exp < __mpfr_emin)
        return mpfr_set_underflow(x, rnd_mode, MPFR_SIGN(x));
      if (exp > __mpfr_emax)
        return mpfr_set_overflow(x, rnd_mode, MPFR_SIGN(x));
    }
  return 0;
}
Esempio n. 4
0
uintmax_t
mpfr_get_uj (mpfr_srcptr f, mpfr_rnd_t rnd)
{
  uintmax_t r;
  mpfr_prec_t prec;
  mpfr_t x;

  if (MPFR_UNLIKELY (!mpfr_fits_uintmax_p (f, rnd)))
    {
      MPFR_SET_ERANGEFLAG ();
      return MPFR_IS_NAN (f) || MPFR_IS_NEG (f) ?
        (uintmax_t) 0 : MPFR_UINTMAX_MAX;
    }

  if (MPFR_IS_ZERO (f))
    return (uintmax_t) 0;

  /* determine the precision of uintmax_t */
  for (r = MPFR_UINTMAX_MAX, prec = 0; r != 0; r /= 2, prec++)
    { }

  /* Now, r = 0. */

  mpfr_init2 (x, prec);
  mpfr_rint (x, f, rnd);
  MPFR_ASSERTN (MPFR_IS_FP (x));

  if (MPFR_NOTZERO (x))
    {
      mp_limb_t *xp;
      int sh, n;  /* An int should be sufficient in this context. */

      MPFR_ASSERTN (MPFR_IS_POS (x));
      xp = MPFR_MANT (x);
      sh = MPFR_GET_EXP (x);
      MPFR_ASSERTN ((mpfr_prec_t) sh <= prec);
      for (n = MPFR_LIMB_SIZE(x) - 1; n >= 0; n--)
        {
          sh -= GMP_NUMB_BITS;
          r += (sh >= 0
                ? (uintmax_t) xp[n] << sh
                : (uintmax_t) xp[n] >> (- sh));
        }
    }

  mpfr_clear (x);

  return r;
}
Esempio n. 5
0
int
mpfr_get_z (mpz_ptr z, mpfr_srcptr f, mpfr_rnd_t rnd)
{
  int inex;
  mpfr_t r;
  mpfr_exp_t exp;
  MPFR_SAVE_EXPO_DECL (expo);

  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
    {
      if (MPFR_UNLIKELY (MPFR_NOTZERO (f)))
        MPFR_SET_ERANGEFLAG ();
      mpz_set_ui (z, 0);
      /* The ternary value is 0 even for infinity. Giving the rounding
         direction in this case would not make much sense anyway, and
         the direction would not necessarily match rnd. */
      return 0;
    }

  MPFR_SAVE_EXPO_MARK (expo);

  exp = MPFR_GET_EXP (f);
  /* if exp <= 0, then |f|<1, thus |o(f)|<=1 */
  MPFR_ASSERTN (exp < 0 || exp <= MPFR_PREC_MAX);
  mpfr_init2 (r, (exp < (mpfr_exp_t) MPFR_PREC_MIN ?
                  MPFR_PREC_MIN : (mpfr_prec_t) exp));
  inex = mpfr_rint (r, f, rnd);
  MPFR_ASSERTN (inex != 1 && inex != -1); /* integral part of f is
                                             representable in r */
  MPFR_ASSERTN (MPFR_IS_FP (r));

  /* The flags from mpfr_rint are the wanted ones. In particular,
     it sets the inexact flag when necessary. */
  MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);

  exp = mpfr_get_z_2exp (z, r);
  if (exp >= 0)
    mpz_mul_2exp (z, z, exp);
  else
    mpz_fdiv_q_2exp (z, z, -exp);
  mpfr_clear (r);

  MPFR_SAVE_EXPO_FREE (expo);

  return inex;
}
Esempio n. 6
0
void
mpfr_get_z (mpz_ptr z, mpfr_srcptr f, mp_rnd_t rnd)
{
  mpfr_t r;
  mp_exp_t exp = MPFR_EXP (f);

  /* if exp <= 0, then |f|<1, thus |o(f)|<=1 */
  MPFR_ASSERTN (exp < 0 || exp <= MPFR_PREC_MAX);
  mpfr_init2 (r, (exp < (mp_exp_t) MPFR_PREC_MIN ?
                  MPFR_PREC_MIN : (mpfr_prec_t) exp));
  mpfr_rint (r, f, rnd);
  MPFR_ASSERTN (MPFR_IS_FP (r) );
  exp = mpfr_get_z_exp (z, r);
  if (exp >= 0)
    mpz_mul_2exp (z, z, exp);
  else
    mpz_div_2exp (z, z, -exp);
  mpfr_clear (r);
}
Esempio n. 7
0
int
mpfr_div_2si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
{
  int inexact;

  inexact = y != x ? mpfr_set (y, x, rnd_mode) : 0;

  if (MPFR_IS_FP(y) && MPFR_NOTZERO(y))
    {
      if (n > 0 && (__mpfr_emin > MPFR_EMAX_MAX - n ||
                    MPFR_EXP(y) < __mpfr_emin + n))
        return mpfr_set_underflow (y, rnd_mode, MPFR_SIGN(y));

      if (n < 0 && (__mpfr_emax < MPFR_EMIN_MIN - n ||
                    MPFR_EXP(y) > __mpfr_emax + n))
        return mpfr_set_overflow (y, rnd_mode, MPFR_SIGN(y));

      MPFR_EXP(y) -= n;
    }

  return inexact;
}
Esempio n. 8
0
mp_exp_t
mpfr_get_z_exp (mpz_ptr z, mpfr_srcptr f)
{
    mp_size_t fn;
    int sh;

    MPFR_ASSERTD (MPFR_IS_FP (f));

    if (MPFR_UNLIKELY (MPFR_IS_ZERO (f)))
    {
        mpz_set_ui (z, 0);
        return __gmpfr_emin;
    }

    fn = MPFR_LIMB_SIZE(f);

    /* check whether allocated space for z is enough */
    if (MPFR_UNLIKELY (ALLOC (z) < fn))
        MPZ_REALLOC (z, fn);

    MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (f));
    if (MPFR_LIKELY (sh))
        mpn_rshift (PTR (z), MPFR_MANT (f), fn, sh);
    else
        MPN_COPY (PTR (z), MPFR_MANT (f), fn);

    SIZ(z) = MPFR_IS_NEG (f) ? -fn : fn;

    /* Test if the result is representable. Later, we could choose
       to return MPFR_EXP_MIN if it isn't, or perhaps MPFR_EXP_MAX
       to signal an error. The mantissa would still be meaningful. */
    MPFR_ASSERTD ((mp_exp_unsigned_t) MPFR_GET_EXP (f) - MPFR_EXP_MIN
                  >= (mp_exp_unsigned_t) MPFR_PREC(f));

    return MPFR_GET_EXP (f) - MPFR_PREC (f);
}
Esempio n. 9
0
static void
check_max(void)
{
  mpfr_t xx, yy, zz;
  mpfr_exp_t emin;

  mpfr_init2(xx, 4);
  mpfr_init2(yy, 4);
  mpfr_init2(zz, 4);
  mpfr_set_str1 (xx, "0.68750");
  mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, MPFR_RNDN);
  mpfr_set_str1 (yy, "0.68750");
  mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, MPFR_RNDN);
  mpfr_clear_flags();
  test_mul(zz, xx, yy, MPFR_RNDU);
  if (!(mpfr_overflow_p() && MPFR_IS_INF(zz)))
    {
      printf("check_max failed (should be an overflow)\n");
      exit(1);
    }

  mpfr_clear_flags();
  test_mul(zz, xx, yy, MPFR_RNDD);
  if (mpfr_overflow_p() || MPFR_IS_INF(zz))
    {
      printf("check_max failed (should NOT be an overflow)\n");
      exit(1);
    }
  mpfr_set_str1 (xx, "0.93750");
  mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, MPFR_RNDN);
  if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz)))
    {
      printf("check_max failed (internal error)\n");
      exit(1);
    }
  if (mpfr_cmp(xx, zz) != 0)
    {
      printf("check_max failed: got ");
      mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ);
      printf(" instead of ");
      mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ);
      printf("\n");
      exit(1);
    }

  /* check underflow */
  emin = mpfr_get_emin ();
  set_emin (0);
  mpfr_set_str_binary (xx, "0.1E0");
  mpfr_set_str_binary (yy, "0.1E0");
  test_mul (zz, xx, yy, MPFR_RNDN);
  /* exact result is 0.1E-1, which should round to 0 */
  MPFR_ASSERTN(mpfr_cmp_ui (zz, 0) == 0 && MPFR_IS_POS(zz));
  set_emin (emin);

  /* coverage test for mpfr_powerof2_raw */
  emin = mpfr_get_emin ();
  set_emin (0);
  mpfr_set_prec (xx, mp_bits_per_limb + 1);
  mpfr_set_str_binary (xx, "0.1E0");
  mpfr_nextabove (xx);
  mpfr_set_str_binary (yy, "0.1E0");
  test_mul (zz, xx, yy, MPFR_RNDN);
  /* exact result is just above 0.1E-1, which should round to minfloat */
  MPFR_ASSERTN(mpfr_cmp (zz, yy) == 0);
  set_emin (emin);

  mpfr_clear(xx);
  mpfr_clear(yy);
  mpfr_clear(zz);
}
Esempio n. 10
0
int
mpfr_number_p (mpfr_srcptr x)
{
  return MPFR_IS_FP(x);
}
Esempio n. 11
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);
}
Esempio n. 12
0
static void
test_urandomb (long nbtests, mpfr_prec_t prec, int verbose)
{
    mpfr_t x;
    int *tab, size_tab, k, sh, xn;
    double d, av = 0, var = 0, chi2 = 0, th;
    mpfr_exp_t emin;

    size_tab = (nbtests >= 1000 ? nbtests / 50 : 20);
    tab = (int *) calloc (size_tab, sizeof(int));
    if (tab == NULL)
    {
        fprintf (stderr, "trandom: can't allocate memory in test_urandomb\n");
        exit (1);
    }

    mpfr_init2 (x, prec);
    xn = 1 + (prec - 1) / mp_bits_per_limb;
    sh = xn * mp_bits_per_limb - prec;

    for (k = 0; k < nbtests; k++)
    {
        mpfr_urandomb (x, RANDS);
        MPFR_ASSERTN (MPFR_IS_FP (x));
        /* check that lower bits are zero */
        if (MPFR_NOTZERO(x) && (MPFR_MANT(x)[0] & MPFR_LIMB_MASK(sh)))
        {
            printf ("Error: mpfr_urandomb() returns invalid numbers:\n");
            mpfr_dump (x);
            exit (1);
        }
        d = mpfr_get_d1 (x);
        av += d;
        var += d*d;
        tab[(int)(size_tab * d)]++;
    }

    /* coverage test */
    emin = mpfr_get_emin ();
    set_emin (1); /* the generated number in [0,1[ is not in the exponent
                        range, except if it is zero */
    k = mpfr_urandomb (x, RANDS);
    if (MPFR_IS_ZERO(x) == 0 && (k == 0 || mpfr_nan_p (x) == 0))
    {
        printf ("Error in mpfr_urandomb, expected NaN, got ");
        mpfr_dump (x);
        exit (1);
    }
    set_emin (emin);

    mpfr_clear (x);
    if (!verbose)
    {
        free(tab);
        return;
    }

    av /= nbtests;
    var = (var / nbtests) - av * av;

    th = (double)nbtests / size_tab;
    printf("Average = %.5f\nVariance = %.5f\n", av, var);
    printf("Repartition for urandomb. Each integer should be close to %d.\n",
           (int)th);

    for (k = 0; k < size_tab; k++)
    {
        chi2 += (tab[k] - th) * (tab[k] - th) / th;
        printf("%d ", tab[k]);
        if (((k+1) & 7) == 0)
            printf("\n");
    }

    printf("\nChi2 statistics value (with %d degrees of freedom) : %.5f\n\n",
           size_tab - 1, chi2);

    free(tab);
    return;
}
Esempio n. 13
0
int
main (int argc, char *argv[])
{
    long nbtests;
    mpfr_prec_t prec;
    int verbose = 0;

    tests_start_mpfr ();

    if (argc > 1)
        verbose = 1;

    nbtests = 10000;
    if (argc > 1)
    {
        long a = atol(argv[1]);
        if (a != 0)
            nbtests = a;
    }

    if (argc <= 2)
        prec = 1000;
    else
        prec = atol(argv[2]);

    test_urandomb (nbtests, prec, verbose);

    if (argc == 1)  /* check also small precision */
    {
        test_urandomb (nbtests, 2, 0);
    }

#ifndef MPFR_USE_MINI_GMP

    /* Since these tests assume a deterministic random generator, and this
       is not implemented in mini-gmp, we omit them with mini-gmp. */

    bug20100914 ();

#if __MPFR_GMP(4,2,0)
    /* Get a non-zero fixed-point number whose first 32 bits are 0 with the
       default GMP PRNG. This corresponds to the case cnt == 0 && k != 0 in
       src/urandomb.c (fixed in r8762) with the 32-bit ABI. */
    {
        gmp_randstate_t s;
        mpfr_t x;
        char *str = "0.1010111100000000000000000000000000000000E-32";
        int k;

        gmp_randinit_default (s);
        gmp_randseed_ui (s, 4518);
        mpfr_init2 (x, 40);

        for (k = 0; k < 575123; k++)
        {
            mpfr_urandomb (x, s);
            MPFR_ASSERTN (MPFR_IS_FP (x));
        }

        if (mpfr_cmp_str (x, str, 2, MPFR_RNDN) != 0)
        {
            printf ("Error in test_urandomb:\n");
            printf ("Expected %s\n", str);
            printf ("Got      ");
            mpfr_dump (x);
            exit (1);
        }

        mpfr_clear (x);
        gmp_randclear (s);
    }
#endif

#endif

    tests_end_mpfr ();
    return 0;
}
Esempio n. 14
0
static void
tst (void)
{
  int sv = sizeof (val) / sizeof (*val);
  int i, j;
  int rnd;
  mpfr_t x, y, z, tmp;

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

  for (i = 0; i < sv; i++)
    for (j = 0; j < sv; j++)
      RND_LOOP (rnd)
        {
          int exact, inex;
          unsigned int flags;

          if (my_setstr (x, val[i]) || my_setstr (y, val[j]))
            {
              printf ("internal error for (%d,%d,%d)\n", i, j, rnd);
              exit (1);
            }
          mpfr_clear_flags ();
          inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd);
          flags = __gmpfr_flags;
          if (! MPFR_IS_NAN (z) && mpfr_nanflag_p ())
            err ("got NaN flag without NaN value", i, j, rnd, z, inex);
          if (MPFR_IS_NAN (z) && ! mpfr_nanflag_p ())
            err ("got NaN value without NaN flag", i, j, rnd, z, inex);
          if (inex != 0 && ! mpfr_inexflag_p ())
            err ("got non-zero ternary value without inexact flag",
                 i, j, rnd, z, inex);
          if (inex == 0 && mpfr_inexflag_p ())
            err ("got null ternary value with inexact flag",
                 i, j, rnd, z, inex);
          if (i >= 3 && j >= 3)
            {
              if (mpfr_underflow_p ())
                err ("got underflow", i, j, rnd, z, inex);
              if (mpfr_overflow_p ())
                err ("got overflow", i, j, rnd, z, inex);
              exact = MPFR_IS_SINGULAR (z) ||
                (mpfr_mul_2ui (tmp, z, 16, MPFR_RNDN), mpfr_integer_p (tmp));
              if (exact && inex != 0)
                err ("got exact value with ternary flag different from 0",
                     i, j, rnd, z, inex);
              if (! exact && inex == 0)
                err ("got inexact value with ternary flag equal to 0",
                     i, j, rnd, z, inex);
            }
          if (MPFR_IS_ZERO (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y))
            {
              if (MPFR_IS_NEG (y) && ! MPFR_IS_INF (z))
                err ("expected an infinity", i, j, rnd, z, inex);
              if (MPFR_IS_POS (y) && ! MPFR_IS_ZERO (z))
                err ("expected a zero", i, j, rnd, z, inex);
              if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z))
                err ("wrong sign", i, j, rnd, z, inex);
            }
          if (! MPFR_IS_NAN (x) && mpfr_cmp_si (x, -1) == 0)
            {
              /* x = -1 */
              if (! (MPFR_IS_INF (y) || mpfr_integer_p (y)) &&
                  ! MPFR_IS_NAN (z))
                err ("expected NaN", i, j, rnd, z, inex);
              if ((MPFR_IS_INF (y) || (mpfr_integer_p (y) && ! is_odd (y)))
                  && ! mpfr_equal_p (z, __gmpfr_one))
                err ("expected 1", i, j, rnd, z, inex);
              if (is_odd (y) &&
                  (MPFR_IS_NAN (z) || mpfr_cmp_si (z, -1) != 0))
                err ("expected -1", i, j, rnd, z, inex);
            }
          if ((mpfr_equal_p (x, __gmpfr_one) || MPFR_IS_ZERO (y)) &&
              ! mpfr_equal_p (z, __gmpfr_one))
            err ("expected 1", i, j, rnd, z, inex);
          if (MPFR_IS_PURE_FP (x) && MPFR_IS_NEG (x) &&
              MPFR_IS_FP (y) && ! mpfr_integer_p (y) &&
              ! MPFR_IS_NAN (z))
            err ("expected NaN", i, j, rnd, z, inex);
          if (MPFR_IS_INF (y) && MPFR_NOTZERO (x))
            {
              int cmpabs1 = mpfr_cmpabs (x, __gmpfr_one);

              if ((MPFR_IS_NEG (y) ? (cmpabs1 < 0) : (cmpabs1 > 0)) &&
                  ! (MPFR_IS_POS (z) && MPFR_IS_INF (z)))
                err ("expected +Inf", i, j, rnd, z, inex);
              if ((MPFR_IS_NEG (y) ? (cmpabs1 > 0) : (cmpabs1 < 0)) &&
                  ! (MPFR_IS_POS (z) && MPFR_IS_ZERO (z)))
                err ("expected +0", i, j, rnd, z, inex);
            }
          if (MPFR_IS_INF (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y))
            {
              if (MPFR_IS_POS (y) && ! MPFR_IS_INF (z))
                err ("expected an infinity", i, j, rnd, z, inex);
              if (MPFR_IS_NEG (y) && ! MPFR_IS_ZERO (z))
                err ("expected a zero", i, j, rnd, z, inex);
              if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z))
                err ("wrong sign", i, j, rnd, z, inex);
            }
          test_others (val[i], val[j], (mpfr_rnd_t) rnd, x, y, z, inex, flags,
                       "tst");
        }
  mpfr_clears (x, y, z, tmp, (mpfr_ptr) 0);
}
Esempio n. 15
0
File: fma.c Progetto: mahdiz/mpclib
int
mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
          mp_rnd_t rnd_mode)
{
  int inexact;
  mpfr_t u;

  /* particular cases */
  if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) || MPFR_IS_NAN(z))
    {
      MPFR_SET_NAN(s);
      MPFR_RET_NAN;
    }

  if (MPFR_IS_INF(x) || MPFR_IS_INF(y))
    {
      /* cases Inf*0+z, 0*Inf+z, Inf-Inf */
      if ((MPFR_IS_FP(y) && MPFR_IS_ZERO(y)) ||
          (MPFR_IS_FP(x) && MPFR_IS_ZERO(x)) ||
          (MPFR_IS_INF(z) && ((MPFR_SIGN(x) * MPFR_SIGN(y)) != MPFR_SIGN(z))))
        {
          MPFR_SET_NAN(s);
          MPFR_RET_NAN;
        }

      MPFR_CLEAR_NAN(s);

      if (MPFR_IS_INF(z)) /* case Inf-Inf already checked above */
        {
          MPFR_SET_INF(s);
          MPFR_SET_SAME_SIGN(s, z);
          MPFR_RET(0);
        }
      else /* z is finite */
        {
          MPFR_SET_INF(s);
          if (MPFR_SIGN(s) != (MPFR_SIGN(x) * MPFR_SIGN(y)))
            MPFR_CHANGE_SIGN(s);
          MPFR_RET(0);
        }
    }

  MPFR_CLEAR_NAN(s);

  /* now x and y are finite */
  if (MPFR_IS_INF(z))
    {
      MPFR_SET_INF(s);
      MPFR_SET_SAME_SIGN(s, z);
      MPFR_RET(0);
    }

  MPFR_CLEAR_INF(s);

  if (MPFR_IS_ZERO(x) || MPFR_IS_ZERO(y))
    {
      if (MPFR_IS_ZERO(z))
        {
          int sign_p, sign_z;
          sign_p = MPFR_SIGN(x) * MPFR_SIGN(y);
          sign_z = MPFR_SIGN(z);
          if (MPFR_SIGN(s) !=
              (rnd_mode != GMP_RNDD ?
               ((sign_p < 0 && sign_z < 0) ? -1 : 1) :
               ((sign_p > 0 && sign_z > 0) ? 1 : -1)))
            {
              MPFR_CHANGE_SIGN(s);
            }
          MPFR_SET_ZERO(s);
          MPFR_RET(0);
        }
      else
        return mpfr_set (s, z, rnd_mode);
    }

  if (MPFR_IS_ZERO(z))
    return mpfr_mul (s, x, y, rnd_mode);

  /* if we take prec(u) >= prec(x) + prec(y), the product
     u <- x*y is always exact */
  mpfr_init2 (u, MPFR_PREC(x) + MPFR_PREC(y));
  mpfr_mul (u, x, y, GMP_RNDN); /* always exact */
  inexact = mpfr_add (s, z, u, rnd_mode);
  mpfr_clear(u);

  return inexact;
}