Exemple #1
0
static void
tcmp2 (double x, double y, int i)
{
  mpfr_t xx, yy;
  mp_prec_t j;

  if (i == -1)
    {
      if (x == y)
        i = 53;
      else
        i = (int) (__gmpfr_floor_log2 (x) - __gmpfr_floor_log2 (x - y));
    }
  mpfr_init2(xx, 53); mpfr_init2(yy, 53);
  mpfr_set_d (xx, x, GMP_RNDN);
  mpfr_set_d (yy, y, GMP_RNDN);
  j = 0;
  if (mpfr_cmp2 (xx, yy, &j) == 0)
    {
      if (x != y)
        {
          printf ("Error in mpfr_cmp2 for\nx=");
          mpfr_out_str (stdout, 2, 0, xx, GMP_RNDN);
          printf ("\ny=");
          mpfr_out_str (stdout, 2, 0, yy, GMP_RNDN);
          printf ("\ngot sign 0 for x != y\n");
          exit (1);
        }
    }
  else if (j != (unsigned) i)
    {
      printf ("Error in mpfr_cmp2 for\nx=");
      mpfr_out_str (stdout, 2, 0, xx, GMP_RNDN);
      printf ("\ny=");
      mpfr_out_str (stdout, 2, 0, yy, GMP_RNDN);
      printf ("\ngot %lu instead of %d\n", j, i);
      exit (1);
    }
  mpfr_clear(xx); mpfr_clear(yy);
}
Exemple #2
0
/* agm(x,y) is between x and y, so we don't need to save exponent range */
int
mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode)
{
  int compare, inexact;
  mp_size_t s;
  mp_prec_t p, q;
  mp_limb_t *up, *vp, *tmpp;
  mpfr_t u, v, tmp;
  unsigned long n; /* number of iterations */
  unsigned long err = 0;
  MPFR_ZIV_DECL (loop);
  MPFR_TMP_DECL(marker);

  MPFR_LOG_FUNC (("op2[%#R]=%R op1[%#R]=%R rnd=%d", op2,op2,op1,op1,rnd_mode),
                 ("r[%#R]=%R inexact=%d", r, r, inexact));

  /* Deal with special values */
  if (MPFR_ARE_SINGULAR (op1, op2))
    {
      /* If a or b is NaN, the result is NaN */
      if (MPFR_IS_NAN(op1) || MPFR_IS_NAN(op2))
        {
          MPFR_SET_NAN(r);
          MPFR_RET_NAN;
        }
      /* now one of a or b is Inf or 0 */
      /* If a and b is +Inf, the result is +Inf.
         Otherwise if a or b is -Inf or 0, the result is NaN */
      else if (MPFR_IS_INF(op1) || MPFR_IS_INF(op2))
        {
          if (MPFR_IS_STRICTPOS(op1) && MPFR_IS_STRICTPOS(op2))
            {
              MPFR_SET_INF(r);
              MPFR_SET_SAME_SIGN(r, op1);
              MPFR_RET(0); /* exact */
            }
          else
            {
              MPFR_SET_NAN(r);
              MPFR_RET_NAN;
            }
        }
      else /* a and b are neither NaN nor Inf, and one is zero */
        {  /* If a or b is 0, the result is +0 since a sqrt is positive */
          MPFR_ASSERTD (MPFR_IS_ZERO (op1) || MPFR_IS_ZERO (op2));
          MPFR_SET_POS (r);
          MPFR_SET_ZERO (r);
          MPFR_RET (0); /* exact */
        }
    }
  MPFR_CLEAR_FLAGS (r);

  /* If a or b is negative (excluding -Infinity), the result is NaN */
  if (MPFR_UNLIKELY(MPFR_IS_NEG(op1) || MPFR_IS_NEG(op2)))
    {
      MPFR_SET_NAN(r);
      MPFR_RET_NAN;
    }

  /* Precision of the following calculus */
  q = MPFR_PREC(r);
  p = q + MPFR_INT_CEIL_LOG2(q) + 15;
  MPFR_ASSERTD (p >= 7); /* see algorithms.tex */
  s = (p - 1) / BITS_PER_MP_LIMB + 1;

  /* b (op2) and a (op1) are the 2 operands but we want b >= a */
  compare = mpfr_cmp (op1, op2);
  if (MPFR_UNLIKELY( compare == 0 ))
    {
      mpfr_set (r, op1, rnd_mode);
      MPFR_RET (0); /* exact */
    }
  else if (compare > 0)
    {
      mpfr_srcptr t = op1;
      op1 = op2;
      op2 = t;
    }
  /* Now b(=op2) >= a (=op1) */

  MPFR_TMP_MARK(marker);

  /* Main loop */
  MPFR_ZIV_INIT (loop, p);
  for (;;)
    {
      mp_prec_t eq;

      /* Init temporary vars */
      MPFR_TMP_INIT (up, u, p, s);
      MPFR_TMP_INIT (vp, v, p, s);
      MPFR_TMP_INIT (tmpp, tmp, p, s);

      /* Calculus of un and vn */
      mpfr_mul (u, op1, op2, GMP_RNDN); /* Faster since PREC(op) < PREC(u) */
      mpfr_sqrt (u, u, GMP_RNDN);
      mpfr_add (v, op1, op2, GMP_RNDN); /* add with !=prec is still good*/
      mpfr_div_2ui (v, v, 1, GMP_RNDN);
      n = 1;
      while (mpfr_cmp2 (u, v, &eq) != 0 && eq <= p - 2)
        {
          mpfr_add (tmp, u, v, GMP_RNDN);
          mpfr_div_2ui (tmp, tmp, 1, GMP_RNDN);
          /* See proof in algorithms.tex */
          if (4*eq > p)
            {
              mpfr_t w;
              /* tmp = U(k) */
              mpfr_init2 (w, (p + 1) / 2);
              mpfr_sub (w, v, u, GMP_RNDN);         /* e = V(k-1)-U(k-1) */
              mpfr_sqr (w, w, GMP_RNDN);            /* e = e^2 */
              mpfr_div_2ui (w, w, 4, GMP_RNDN);     /* e*= (1/2)^2*1/4  */
              mpfr_div (w, w, tmp, GMP_RNDN);       /* 1/4*e^2/U(k) */
              mpfr_sub (v, tmp, w, GMP_RNDN);
              err = MPFR_GET_EXP (tmp) - MPFR_GET_EXP (v); /* 0 or 1 */
              mpfr_clear (w);
              break;
            }
          mpfr_mul (u, u, v, GMP_RNDN);
          mpfr_sqrt (u, u, GMP_RNDN);
          mpfr_swap (v, tmp);
          n ++;
        }
      /* the error on v is bounded by (18n+51) ulps, or twice if there
         was an exponent loss in the final subtraction */
      err += MPFR_INT_CEIL_LOG2(18 * n + 51); /* 18n+51 should not overflow
                                                 since n is about log(p) */
      /* we should have n+2 <= 2^(p/4) [see algorithms.tex] */
      if (MPFR_LIKELY (MPFR_INT_CEIL_LOG2(n + 2) <= p / 4 &&
                       MPFR_CAN_ROUND (v, p - err, q, rnd_mode)))
        break; /* Stop the loop */

      /* Next iteration */
      MPFR_ZIV_NEXT (loop, p);
      s = (p - 1) / BITS_PER_MP_LIMB + 1;
    }
  MPFR_ZIV_FREE (loop);

  /* Setting of the result */
  inexact = mpfr_set (r, v, rnd_mode);

  /* Let's clean */
  MPFR_TMP_FREE(marker);

  return inexact; /* agm(u,v) can be exact for u, v rational only for u=v.
                     Proof (due to Nicolas Brisebarre): it suffices to consider
                     u=1 and v<1. Then 1/AGM(1,v) = 2F1(1/2,1/2,1;1-v^2),
                     and a theorem due to G.V. Chudnovsky states that for x a
                     non-zero algebraic number with |x|<1, then
                     2F1(1/2,1/2,1;x) and 2F1(-1/2,1/2,1;x) are algebraically
                     independent over Q. */
}
Exemple #3
0
int
main (void)
{
  double x, y;
  mpfr_t xx, yy;
  int c;
  long i;
  mpfr_prec_t p;

  tests_start_mpfr ();

  mpfr_init (xx);
  mpfr_init (yy);

  mpfr_set_prec (xx, 2);
  mpfr_set_prec (yy, 2);
  mpfr_set_str_binary(xx, "-0.10E0");
  mpfr_set_str_binary(yy, "-0.10E0");
  if ((mpfr_cmp) (xx, yy))
    {
      printf ("mpfr_cmp (xx, yy) returns non-zero for prec=2\n");
      exit (1);
    }

  mpfr_set_prec (xx, 65);
  mpfr_set_prec (yy, 65);
  mpfr_set_str_binary(xx, "0.10011010101000110101010000000011001001001110001011101011111011101E623");
  mpfr_set_str_binary(yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623");
  p = 0;
  if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 64)
    {
      printf ("Error (1) in mpfr_cmp2\n");
      exit (1);
    }
  mpfr_set_str_binary(xx, "0.10100010001110110111000010001000010011111101000100011101000011100");
  mpfr_set_str_binary(yy, "0.10100010001110110111000010001000010011111101000100011101000011011");
  p = 0;
  if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 64)
    {
      printf ("Error (2) in mpfr_cmp2\n");
      exit (1);
    }

  mpfr_set_prec (xx, 160); mpfr_set_prec (yy, 160);
  mpfr_set_str_binary (xx, "0.1E1");
  mpfr_set_str_binary (yy, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100");
  p = 0;
  if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 144)
    {
      printf ("Error (3) in mpfr_cmp2\n");
      exit (1);
    }

  mpfr_set_prec (xx, 53);
  mpfr_set_prec (yy, 200);
  mpfr_set_ui (xx, 1, (mpfr_rnd_t) 0);
  mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0);
  if (mpfr_cmp (xx, yy) != 0)
    {
      printf ("Error in mpfr_cmp: 1.0 != 1.0\n");
      exit (1);
    }
  mpfr_set_prec (yy, 31);
  mpfr_set_str (xx, "1.0000000002", 10, (mpfr_rnd_t) 0);
  mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0);
  if (!(mpfr_cmp (xx,yy)>0))
    {
      printf ("Error in mpfr_cmp: not 1.0000000002 > 1.0\n");
      exit (1);
    }
  mpfr_set_prec (yy, 53);

  /* bug found by Gerardo Ballabio */
  mpfr_set_ui(xx, 0, MPFR_RNDN);
  mpfr_set_str (yy, "0.1", 10, MPFR_RNDN);
  if ((c = mpfr_cmp (xx, yy)) >= 0)
    {
      printf ("Error in mpfr_cmp(0.0, 0.1), gives %d\n", c);
      exit (1);
    }

  mpfr_set_inf (xx, 1);
  mpfr_set_str (yy, "-23489745.0329", 10, MPFR_RNDN);
  if ((c = mpfr_cmp (xx, yy)) <= 0)
    {
      printf ("Error in mpfr_cmp(Infp, 23489745.0329), gives %d\n", c);
      exit (1);
    }

  mpfr_set_inf (xx, 1);
  mpfr_set_inf (yy, -1);
  if ((c = mpfr_cmp (xx, yy)) <= 0)
    {
      printf ("Error in mpfr_cmp(Infp, Infm), gives %d\n", c);
      exit (1);
    }

  mpfr_set_inf (xx, -1);
  mpfr_set_inf (yy, 1);
  if ((c = mpfr_cmp (xx, yy)) >= 0)
    {
      printf ("Error in mpfr_cmp(Infm, Infp), gives %d\n", c);
      exit (1);
    }

  mpfr_set_inf (xx, 1);
  mpfr_set_inf (yy, 1);
  if ((c = mpfr_cmp (xx, yy)) != 0)
    {
      printf ("Error in mpfr_cmp(Infp, Infp), gives %d\n", c);
      exit (1);
    }

  mpfr_set_inf (xx, -1);
  mpfr_set_inf (yy, -1);
  if ((c = mpfr_cmp (xx, yy)) != 0)
    {
      printf ("Error in mpfr_cmp(Infm, Infm), gives %d\n", c);
      exit (1);
    }

  mpfr_set_inf (xx, -1);
  mpfr_set_str (yy, "2346.09234", 10, MPFR_RNDN);
  if ((c = mpfr_cmp (xx, yy)) >= 0)
    {
      printf ("Error in mpfr_cmp(Infm, 2346.09234), gives %d\n", c);
      exit (1);
    }

  mpfr_set_ui (xx, 0, MPFR_RNDN);
  mpfr_set_ui (yy, 1, MPFR_RNDN);
  if ((c = mpfr_cmp3 (xx, yy, 1)) >= 0)
    {
      printf ("Error: mpfr_cmp3 (0, 1, 1) gives %d instead of"
              " a negative value\n", c);
      exit (1);
    }
  if ((c = mpfr_cmp3 (xx, yy, -1)) <= 0)
    {
      printf ("Error: mpfr_cmp3 (0, 1, -1) gives %d instead of"
              " a positive value\n", c);
      exit (1);
    }

  for (i=0; i<500000; )
    {
      x = DBL_RAND ();
      y = DBL_RAND ();
      if (!Isnan(x) && !Isnan(y))
        {
          i++;
          mpfr_set_d (xx, x, MPFR_RNDN);
          mpfr_set_d (yy, y, MPFR_RNDN);
          c = mpfr_cmp (xx,yy);
          if ((c>0 && x<=y) || (c==0 && x!=y) || (c<0 && x>=y))
            {
              printf ("Error in mpfr_cmp with x=%1.20e, y=%1.20e"
                      " mpfr_cmp(x,y)=%d\n", x, y, c);
              exit (1);
            }
        }
    }

  /* Check for NAN */
  mpfr_set_nan (xx);
  mpfr_clear_erangeflag ();
  c = (mpfr_cmp) (xx, yy);
  if (c != 0 || !mpfr_erangeflag_p () )
    {
      printf ("NAN error (1)\n");
      exit (1);
    }
  mpfr_clear_erangeflag ();
  c = (mpfr_cmp) (yy, xx);
  if (c != 0 || !mpfr_erangeflag_p () )
    {
      printf ("NAN error (2)\n");
      exit (1);
    }
  mpfr_clear_erangeflag ();
  c = (mpfr_cmp) (xx, xx);
  if (c != 0 || !mpfr_erangeflag_p () )
    {
      printf ("NAN error (3)\n");
      exit (1);
    }

  mpfr_clear (xx);
  mpfr_clear (yy);

  tests_end_mpfr ();
  return 0;
}
Exemple #4
0
/* check that for x = 1.u 1 v 0^k low(x)
                  y = 1.u 0 v 1^k low(y)
   mpfr_cmp2 (x, y) returns 1 + |u| + |v| + k for low(x) >= low(y),
                        and 1 + |u| + |v| + k + 1 otherwise */
static void
worst_cases (void)
{
  mpfr_t x, y;
  unsigned int i, j, k, b, expected;
  mp_prec_t l;

  mpfr_init2 (x, 200);
  mpfr_init2 (y, 200);

  mpfr_set_ui (y, 1, GMP_RNDN);
  for (i=1; i<MPFR_PREC(x); i++)
    {
      mpfr_set_ui (x, 1, GMP_RNDN);
      mpfr_div_2exp (y, y, 1, GMP_RNDN); /* y = 1/2^i */

      l = 0;
      if (mpfr_cmp2 (x, y, &l) <= 0 || l != 1)
        {
          printf ("Error in mpfr_cmp2:\nx=");
          mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
          printf ("\ny=");
          mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
          printf ("\ngot %lu instead of %u\n", l, 1);
          exit (1);
        }

      mpfr_add (x, x, y, GMP_RNDN); /* x = 1 + 1/2^i */
      l = 0;
      if (mpfr_cmp2 (x, y, &l) <= 0 || l != 0)
        {
          printf ("Error in mpfr_cmp2:\nx=");
          mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
          printf ("\ny=");
          mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
          printf ("\ngot %lu instead of %u\n", l, 0);
          exit (1);
        }
    }

  for (i=0; i<64; i++) /* |u| = i */
    {
      mpfr_random (x);
      mpfr_set (y, x, GMP_RNDN);
      set_bit (x, i + 1, 1);
      set_bit (y, i + 1, 0);
      for (j=0; j<64; j++) /* |v| = j */
        {
          b = randlimb () % 2;
          set_bit (x, i + j + 2, b);
          set_bit (y, i + j + 2, b);
          for (k=0; k<64; k++)
            {
              if (k)
                set_bit (x, i + j + k + 1, 0);
              if (k)
                set_bit (y, i + j + k + 1, 1);
              set_bit (x, i + j + k + 2, 1);
              set_bit (y, i + j + k + 2, 0);
              l = 0; mpfr_cmp2 (x, y, &l);
              expected = i + j + k + 1;
              if (l != expected)
                {
                  printf ("Error in mpfr_cmp2:\nx=");
                  mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
                  printf ("\ny=");
                  mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
                  printf ("\ngot %lu instead of %u\n", l, expected);
                  exit (1);
                }
              set_bit (x, i + j + k + 2, 0);
              set_bit (x, i + j + k + 3, 0);
              set_bit (y, i + j + k + 3, 1);
              l = 0; mpfr_cmp2 (x, y, &l);
              expected = i + j + k + 2;
              if (l != expected)
                {
                  printf ("Error in mpfr_cmp2:\nx=");
                  mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
                  printf ("\ny=");
                  mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
                  printf ("\ngot %lu instead of %u\n", l, expected);
                  exit (1);
                }
            }
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
Exemple #5
0
static void
special (void)
{
  mpfr_t x, y;
  mp_prec_t j;

  mpfr_init (x); mpfr_init (y);

  /* bug found by Nathalie Revol, 21 March 2001 */
  mpfr_set_prec (x, 65);
  mpfr_set_prec (y, 65);
  mpfr_set_str_binary (x, "0.10000000000000000000000000000000000001110010010110100110011110000E1");
  mpfr_set_str_binary (y, "0.11100100101101001100111011111111110001101001000011101001001010010E-35");
  j = 0;
  if (mpfr_cmp2 (x, y, &j) <= 0 || j != 1)
    {
      printf ("Error in mpfr_cmp2:\n");
      printf ("x=");
      mpfr_print_binary (x);
      puts ("");
      printf ("y=");
      mpfr_print_binary (y);
      puts ("");
      printf ("got %lu, expected 1\n", j);
      exit (1);
    }

  mpfr_set_prec(x, 127); mpfr_set_prec(y, 127);
  mpfr_set_str_binary(x, "0.1011010000110111111000000101011110110001000101101011011110010010011110010000101101000010011001100110010000000010110000101000101E6");
  mpfr_set_str_binary(y, "0.1011010000110111111000000101011011111100011101000011001111000010100010100110110100110010011001100110010000110010010110000010110E6");
  j = 0;
  if (mpfr_cmp2(x, y, &j) <= 0 || j != 32)
    {
      printf ("Error in mpfr_cmp2:\n");
      printf ("x="); mpfr_print_binary(x); puts ("");
      printf ("y="); mpfr_print_binary(y); puts ("");
      printf ("got %lu, expected 32\n", j);
      exit (1);
    }

  mpfr_set_prec (x, 128); mpfr_set_prec (y, 239);
  mpfr_set_str_binary (x, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100100000000000E167");
  mpfr_set_str_binary (y, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100011111111111111111111111111111111111111111111111011111100101011100011001101000100111000010000000000101100110000111111000101E167");
  j = 0;
  if (mpfr_cmp2(x, y, &j) <= 0 || j != 164)
    {
      printf ("Error in mpfr_cmp2:\n");
      printf ("x="); mpfr_print_binary(x); puts ("");
      printf ("y="); mpfr_print_binary(y); puts ("");
      printf ("got %lu, expected 164\n", j);
      exit (1);
    }

  /* bug found by Nathalie Revol, 29 March 2001 */
  mpfr_set_prec (x, 130); mpfr_set_prec (y, 130);
  mpfr_set_str_binary (x, "0.1100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E2");
  mpfr_set_str_binary (y, "0.1011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100E2");
  j = 0;
  if (mpfr_cmp2(x, y, &j) <= 0 || j != 127)
    {
      printf ("Error in mpfr_cmp2:\n");
      printf ("x="); mpfr_print_binary(x); puts ("");
      printf ("y="); mpfr_print_binary(y); puts ("");
      printf ("got %lu, expected 127\n", j);
      exit (1);
    }

  /* bug found by Nathalie Revol, 2 Apr 2001 */
  mpfr_set_prec (x, 65); mpfr_set_prec (y, 65);
  mpfr_set_ui (x, 5, GMP_RNDN);
  mpfr_set_str_binary (y, "0.10011111111111111111111111111111111111111111111111111111111111101E3");
  j = 0;
  if (mpfr_cmp2(x, y, &j) <= 0 || j != 63)
    {
      printf ("Error in mpfr_cmp2:\n");
      printf ("x="); mpfr_print_binary(x); puts ("");
      printf ("y="); mpfr_print_binary(y); puts ("");
      printf ("got %lu, expected 63\n", j);
      exit (1);
    }

  /* bug found by Nathalie Revol, 2 Apr 2001 */
  mpfr_set_prec (x, 65); mpfr_set_prec (y, 65);
  mpfr_set_str_binary (x, "0.10011011111000101001110000000000000000000000000000000000000000000E-69");
  mpfr_set_str_binary (y, "0.10011011111000101001101111111111111111111111111111111111111111101E-69");
  j = 0;
  if (mpfr_cmp2(x, y, &j) <= 0 || j != 63)
    {
      printf ("Error in mpfr_cmp2:\n");
      printf ("x="); mpfr_print_binary(x); puts ("");
      printf ("y="); mpfr_print_binary(y); puts ("");
      printf ("got %lu, expected 63\n", j);
      exit (1);
    }

  mpfr_set_prec (x, 65);
  mpfr_set_prec (y, 32);
  mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
  mpfr_set_str_binary (y, "0.11101110111100011101110111111111");
  if (mpfr_cmp2 (x, y, &j) <= 0 || j != 0)
    {
      printf ("Error in mpfr_cmp2 (1)\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}