Example #1
0
File: tadd.c Project: mahdiz/mpclib
/* idem than check for mpfr_add(x, y, x) */
void
check4 (double x, double y, mp_rnd_t rnd_mode)
{
  double z1, z2;
  mpfr_t xx, yy;
  int neg;

  neg = LONG_RAND() % 2;
  mpfr_init2(xx, 53);
  mpfr_init2(yy, 53);
  mpfr_set_d(xx, x, rnd_mode);
  mpfr_set_d(yy, y, rnd_mode);
  if (neg) mpfr_sub(xx, yy, xx, rnd_mode);
  else mpfr_add(xx, yy, xx, rnd_mode);
  mpfr_set_machine_rnd_mode(rnd_mode);
  z1 = (neg) ? y-x : x+y;
  z2 = mpfr_get_d1 (xx);
  mpfr_set_d (yy, z2, GMP_RNDN);
  /* check that xx is representable as a double and no overflow occurred */
  if ((mpfr_cmp (xx, yy) == 0) && (z1 != z2)) {
    printf("expected result is %1.20e, got %1.20e\n", z1, z2);
    printf("mpfr_%s(x,y,x) failed for x=%1.20e y=%1.20e with rnd_mode=%s\n",
	   (neg) ? "sub" : "add", x, y, mpfr_print_rnd_mode(rnd_mode));
    exit(1);
  }
  mpfr_clear(xx); mpfr_clear(yy);
}
Example #2
0
File: tadd.c Project: mahdiz/mpclib
/* checks that x+y gives the same results in double
   and with mpfr with 53 bits of precision */
void
_check (double x, double y, double z1, mp_rnd_t rnd_mode, unsigned int px, 
        unsigned int py, unsigned int pz)
{
  double z2; mpfr_t xx,yy,zz; int cert=0;

  mpfr_init2(xx, px);
  mpfr_init2(yy, py);
  mpfr_init2(zz, pz);
  mpfr_set_d(xx, x, rnd_mode);
  mpfr_set_d(yy, y, rnd_mode);
  mpfr_add(zz, xx, yy, rnd_mode);
#ifdef MPFR_HAVE_FESETROUND
  mpfr_set_machine_rnd_mode(rnd_mode);
  if (px==53 && py==53 && pz==53) cert=1;
#endif
  if (z1==0.0) z1=x+y; else cert=1;
  z2 = mpfr_get_d1 (zz);
  mpfr_set_d (yy, z2, GMP_RNDN);
  if (!mpfr_cmp (zz, yy) && cert && z1!=z2 && !(isnan(z1) && isnan(z2))) {
    printf("expected sum is %1.20e, got %1.20e\n",z1,z2);
    printf("mpfr_add failed for x=%1.20e y=%1.20e with rnd_mode=%s\n",
	   x, y, mpfr_print_rnd_mode(rnd_mode));
    exit(1);
  }
  mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
}
Example #3
0
File: tadd.c Project: mahdiz/mpclib
/* idem than check for mpfr_add(x, x, x) */
void
check5 (double x, mp_rnd_t rnd_mode)
{
  double z1,z2; mpfr_t xx, yy; int neg;

  mpfr_init2(xx, 53);
  mpfr_init2(yy, 53);
  neg = LONG_RAND() % 2;
  mpfr_set_d(xx, x, rnd_mode);
  if (neg) mpfr_sub(xx, xx, xx, rnd_mode);
  else mpfr_add(xx, xx, xx, rnd_mode);
  mpfr_set_machine_rnd_mode(rnd_mode);
  z1 = (neg) ? x-x : x+x;
  z2 = mpfr_get_d1 (xx);
  mpfr_set_d (yy, z2, GMP_RNDN);
  /* check NaNs first since mpfr_cmp does not like them */
  if (!(isnan(z1) && isnan(z2)) && !mpfr_cmp (xx, yy) && z1!=z2)
    {
      printf ("expected result is %1.20e, got %1.20e\n",z1,z2);
      printf ("mpfr_%s(x,x,x) failed for x=%1.20e with rnd_mode=%s\n",
              (neg) ? "sub" : "add", x, mpfr_print_rnd_mode (rnd_mode));
      exit (1);
    }
  mpfr_clear(xx);
  mpfr_clear(yy);
}
Example #4
0
int
main (int argc, char *argv[])
{
  mpfr_t x;
  int p;
  mp_rnd_t rnd;

  p = (argc>1) ? atoi(argv[1]) : 53;
  rnd = (argc>2) ? atoi(argv[2]) : GMP_RNDZ;

  mpfr_init (x);

  check (2, 1000);

  /* check precision of 2 bits */
  mpfr_set_prec (x, 2);
  mpfr_const_log2 (x, GMP_RNDN);
  if (mpfr_get_d1 (x) != 0.75)
    {
      fprintf (stderr, "mpfr_const_log2 failed for prec=2, rnd=GMP_RNDN\n");
      fprintf (stderr, "expected 0.75, got %f\n", mpfr_get_d1 (x));
      exit (1);
    }

  if (argc>=2)
    {
      mpfr_set_prec (x, p);
      mpfr_const_log2 (x, rnd);
      printf ("log(2)=");
      mpfr_out_str (stdout, 10, 0, x, rnd);
      putchar('\n');
    }
  
  mpfr_set_prec (x, 53);
  mpfr_const_log2 (x, rnd);
  if (mpfr_get_d1 (x) != 6.9314718055994530941e-1)
    {
      fprintf (stderr, "mpfr_const_log2 failed for prec=53\n");
      exit (1);
    }

  mpfr_clear(x);

  return 0;
}
Example #5
0
File: tsin.c Project: mahdiz/mpclib
void
check53 (double x, double sin_x, mp_rnd_t rnd_mode)
{
  mpfr_t xx, s;

  mpfr_init2 (xx, 53);
  mpfr_init2 (s, 53);
  mpfr_set_d (xx, x, rnd_mode); /* should be exact */
  mpfr_sin (s, xx, rnd_mode);
  if (mpfr_get_d1 (s) != sin_x && (!isnan(sin_x) || !mpfr_nan_p(s)))
    {
      fprintf (stderr, "mpfr_sin failed for x=%1.20e, rnd=%s\n", x,
	       mpfr_print_rnd_mode (rnd_mode));
      fprintf (stderr, "mpfr_sin gives sin(x)=%1.20e, expected %1.20e\n",
	       mpfr_get_d1 (s), sin_x);
      exit(1);
    }
  mpfr_clear (xx);
  mpfr_clear (s);
}
Example #6
0
File: tadd.c Project: mahdiz/mpclib
/* checks when source and destination are equal */
void
check_same (void)
{
  mpfr_t x;

  mpfr_init(x); mpfr_set_d(x, 1.0, GMP_RNDZ);
  mpfr_add(x, x, x, GMP_RNDZ);
  if (mpfr_get_d1 (x) != 2.0) {
    printf("Error when all 3 operands are equal\n"); exit(1);
  }
  mpfr_clear(x);
}
Example #7
0
int
main (int argc, char *argv[])
{
  double x, z; mpfr_t w; unsigned long k; 

  mpfr_init2(w, 53); 

  mpfr_set_inf (w, 1);
  mpfr_mul_2exp (w, w, 10, GMP_RNDZ); 
  if (!MPFR_IS_INF(w)) { fprintf(stderr, "Inf != Inf"); exit(-1); }
  
  mpfr_set_nan (w);
  mpfr_mul_2exp (w, w, 10, GMP_RNDZ); 
  if (!MPFR_IS_NAN(w)) { fprintf(stderr, "NaN != NaN"); exit(-1); }

  SEED_RAND (time(NULL));
  for (k = 0; k < 100000; k++) {
    x = DBL_RAND ();
    mpfr_set_d (w, x, 0);
    mpfr_mul_2exp (w, w, 10, GMP_RNDZ);
    if (x != (z = mpfr_get_d1 (w)/1024))
      {
	fprintf(stderr, "%f != %f\n", x, z); 
	return -1;
      }

    mpfr_set_d(w, x, 0);
    mpfr_div_2exp(w, w, 10, GMP_RNDZ);
    if (x != (z = mpfr_get_d1 (w)*1024))
      {
	fprintf(stderr, "%f != %f\n", x, z);
	mpfr_clear(w);
	return -1;
      }
  }

  mpfr_clear(w);

  return 0;
}
Example #8
0
File: tsin.c Project: mahdiz/mpclib
int
main (int argc, char *argv[])
{
  mpfr_t x;

#ifdef HAVE_INFS
  check53 (DBL_NAN, DBL_NAN, GMP_RNDN);
  check53 (DBL_POS_INF, DBL_NAN, GMP_RNDN);
  check53 (DBL_NEG_INF, DBL_NAN, GMP_RNDN);
#endif
  /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */
  check53 (4.984987858808754279e-1, 4.781075595393330379e-1, GMP_RNDN);
  check53 (4.984987858808754279e-1, 4.781075595393329824e-1, GMP_RNDD);
  check53 (4.984987858808754279e-1, 4.781075595393329824e-1, GMP_RNDZ);
  check53 (4.984987858808754279e-1, 4.781075595393330379e-1, GMP_RNDU);
  check53 (1.00031274099908640274,  8.416399183372403892e-1, GMP_RNDN);
  check53 (1.00229256850978698523,  8.427074524447979442e-1, GMP_RNDZ);
  check53 (1.00288304857059840103,  8.430252033025980029e-1, GMP_RNDZ);
  check53 (1.00591265847407274059,  8.446508805292128885e-1, GMP_RNDN);

  check53 (1.00591265847407274059,  8.446508805292128885e-1, GMP_RNDN);

  mpfr_init2 (x, 2);

  mpfr_set_d (x, 0.5, GMP_RNDN);
  mpfr_sin (x, x, GMP_RNDD);
  if (mpfr_get_d1 (x) != 0.375)
    {
      fprintf (stderr, "mpfr_sin(0.5, GMP_RNDD) failed with precision=2\n");
      exit (1);
    }

  /* bug found by Kevin Ryde */
  mpfr_const_pi (x, GMP_RNDN);
  mpfr_mul_ui (x, x, 3L, GMP_RNDN);
  mpfr_div_ui (x, x, 2L, GMP_RNDN);
  mpfr_sin (x, x, GMP_RNDN);
  if (mpfr_cmp_ui (x, 0) >= 0)
    {
      fprintf (stderr, "Error: wrong sign for sin(3*Pi/2)\n");
      exit (1);
    }

  mpfr_clear (x);

  test_generic (2, 100, 80);

  return 0;
}
Example #9
0
File: tget_d.c Project: Canar/mpfr
static void
check_min(void)
{
  double d, e;
  mpfr_t u;

  d = 1.0; while (d > (DBL_MIN * 2.0)) d /= 2.0;
  mpfr_init(u);
  if (mpfr_set_d(u, d, MPFR_RNDN) == 0)
    {
      /* If setting is exact */
      e = mpfr_get_d1(u);
      if (e != d)
        {
          printf("get_d(set_d)(2): %1.20e != %1.20e\n", d, e);
          exit(1);
        }
    }
  mpfr_clear(u);
}
Example #10
0
File: tadd.c Project: mahdiz/mpclib
void
checknan (double x, double y, mp_rnd_t rnd_mode, unsigned int px, 
          unsigned int py, unsigned int pz)
{
  double z2; mpfr_t xx, yy, zz;

  mpfr_init2(xx, px);
  mpfr_init2(yy, py);
  mpfr_init2(zz, pz);
  mpfr_set_d(xx, x, rnd_mode);
  mpfr_set_d(yy, y, rnd_mode);
  mpfr_add(zz, xx, yy, rnd_mode);
#ifdef MPFR_HAVE_FESETROUND
  mpfr_set_machine_rnd_mode(rnd_mode);
#endif
  if (MPFR_IS_NAN(zz) == 0) { printf("Error, not an MPFR_NAN for xx = %1.20e, y = %1.20e\n", x, y); exit(1); }
  z2 = mpfr_get_d1 (zz);
  if (!isnan(z2)) { printf("Error, not a NaN after conversion, xx = %1.20e yy = %1.20e, got %1.20e\n", x, y, z2); exit(1); }

  mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
}
Example #11
0
File: tadd.c Project: mahdiz/mpclib
void
check2 (double x, int px, double y, int py, int pz, mp_rnd_t rnd_mode)
{
  mpfr_t xx, yy, zz; double z,z2; int u;

  mpfr_init2(xx,px); mpfr_init2(yy,py); mpfr_init2(zz,pz);
  mpfr_set_d(xx, x, rnd_mode);
  mpfr_set_d(yy, y, rnd_mode);
  mpfr_add(zz, xx, yy, rnd_mode);
  mpfr_set_machine_rnd_mode(rnd_mode);
  z = x+y; z2=mpfr_get_d1 (zz); u=ulp(z,z2);
  /* one ulp difference is possible due to composed rounding */
  if (px>=53 && py>=53 && pz>=53 && ABS(u)>1) { 
    printf("x=%1.20e,%d y=%1.20e,%d pz=%d,rnd=%s\n",
	   x,px,y,py,pz,mpfr_print_rnd_mode(rnd_mode));
    printf("got %1.20e\n",z2);
    printf("result should be %1.20e (diff=%d ulp)\n",z,u);
    mpfr_set_d(zz, z, rnd_mode);
    printf("i.e."); mpfr_print_binary(zz); putchar('\n');
    exit(1); }
  mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
}
Example #12
0
File: tadd.c Project: mahdiz/mpclib
/* idem than check for mpfr_add(x, x, y) */
void
check3 (double x, double y, mp_rnd_t rnd_mode)
{
  double z1,z2; mpfr_t xx,yy; int neg;

  neg = LONG_RAND() % 2;
  mpfr_init2(xx, 53);
  mpfr_init2(yy, 53);
  mpfr_set_d(xx, x, rnd_mode);
  mpfr_set_d(yy, y, rnd_mode);
  if (neg) mpfr_sub(xx, xx, yy, rnd_mode);
  else mpfr_add(xx, xx, yy, rnd_mode);
  mpfr_set_machine_rnd_mode(rnd_mode);
  z1 = (neg) ? x-y : x+y;
  z2 = mpfr_get_d1 (xx);
  mpfr_set_d (yy, z2, GMP_RNDN);
  if (!mpfr_cmp (xx, yy) && z1!=z2 && !(isnan(z1) && isnan(z2))) {
    printf("expected result is %1.20e, got %1.20e\n",z1,z2);
    printf("mpfr_%s(x,x,y) failed for x=%1.20e y=%1.20e with rnd_mode=%u\n",
	   (neg) ? "sub" : "add",x,y,rnd_mode);
    exit(1);
  }
  mpfr_clear(xx); mpfr_clear(yy);
}
Example #13
0
/* use Brent's formula exp(x) = (1+r+r^2/2!+r^3/3!+...)^(2^K)*2^n
   where x = n*log(2)+(2^K)*r
   together with Brent-Kung O(t^(1/2)) algorithm for the evaluation of
   power series. The resulting complexity is O(n^(1/3)*M(n)).
*/
int
mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
  long n;
  unsigned long K, k, l, err; /* FIXME: Which type ? */
  int error_r;
  mp_exp_t exps;
  mp_prec_t q, precy;
  int inexact;
  mpfr_t r, s, t;
  mpz_t ss;
  TMP_DECL(marker);

  precy = MPFR_PREC(y);
  
  MPFR_TRACE ( printf("Py=%d Px=%d", MPFR_PREC(y), MPFR_PREC(x)) );
  MPFR_TRACE ( MPFR_DUMP (x) );

  n = (long) (mpfr_get_d1 (x) / LOG2);

  /* error bounds the cancelled bits in x - n*log(2) */
  if (MPFR_UNLIKELY(n == 0))
    error_r = 0;
  else
    count_leading_zeros (error_r, (mp_limb_t) (n < 0) ? -n : n);
  error_r = BITS_PER_MP_LIMB - error_r + 2;

  /* for the O(n^(1/2)*M(n)) method, the Taylor series computation of
     n/K terms costs about n/(2K) multiplications when computed in fixed
     point */
  K = (precy < SWITCH) ? __gmpfr_isqrt ((precy + 1) / 2)
    : __gmpfr_cuberoot (4*precy);
  l = (precy - 1) / K + 1;
  err = K + MPFR_INT_CEIL_LOG2 (2 * l + 18);
  /* add K extra bits, i.e. failure probability <= 1/2^K = O(1/precy) */
  q = precy + err + K + 5;
  
  /*q = ( (q-1)/BITS_PER_MP_LIMB + 1) * BITS_PER_MP_LIMB; */

  mpfr_init2 (r, q + error_r);
  mpfr_init2 (s, q + error_r);
  mpfr_init2 (t, q);

  /* the algorithm consists in computing an upper bound of exp(x) using
     a precision of q bits, and see if we can round to MPFR_PREC(y) taking
     into account the maximal error. Otherwise we increase q. */
  for (;;)
    {
      MPFR_TRACE ( printf("n=%d K=%d l=%d q=%d\n",n,K,l,q) );
      
      /* if n<0, we have to get an upper bound of log(2)
	 in order to get an upper bound of r = x-n*log(2) */
      mpfr_const_log2 (s, (n >= 0) ? GMP_RNDZ : GMP_RNDU);
      /* s is within 1 ulp of log(2) */
      
      mpfr_mul_ui (r, s, (n < 0) ? -n : n, (n >= 0) ? GMP_RNDZ : GMP_RNDU);
      /* r is within 3 ulps of n*log(2) */
      if (n < 0)
	mpfr_neg (r, r, GMP_RNDD); /* exact */
      /* r = floor(n*log(2)), within 3 ulps */
      
      MPFR_TRACE ( MPFR_DUMP (x) );
      MPFR_TRACE ( MPFR_DUMP (r) );
      
      mpfr_sub (r, x, r, GMP_RNDU);
      /* possible cancellation here: the error on r is at most
	 3*2^(EXP(old_r)-EXP(new_r)) */
      while (MPFR_IS_NEG (r))
	{ /* initial approximation n was too large */
	  n--;
	  mpfr_add (r, r, s, GMP_RNDU);
	}
      mpfr_prec_round (r, q, GMP_RNDU);
      MPFR_TRACE ( MPFR_DUMP (r) );
      MPFR_ASSERTD (MPFR_IS_POS (r));
      mpfr_div_2ui (r, r, K, GMP_RNDU); /* r = (x-n*log(2))/2^K, exact */
      
      TMP_MARK(marker);
      MY_INIT_MPZ(ss, 3 + 2*((q-1)/BITS_PER_MP_LIMB));
      exps = mpfr_get_z_exp (ss, s);
      /* s <- 1 + r/1! + r^2/2! + ... + r^l/l! */
      l = (precy < SWITCH) ? 
	mpfr_exp2_aux (ss, r, q, &exps)      /* naive method */
	: mpfr_exp2_aux2 (ss, r, q, &exps);  /* Brent/Kung method */
      
      MPFR_TRACE(printf("l=%d q=%d (K+l)*q^2=%1.3e\n", l, q, (K+l)*(double)q*q));
      
      for (k = 0; k < K; k++)
	{
	  mpz_mul (ss, ss, ss);
	  exps <<= 1;
	  exps += mpz_normalize (ss, ss, q);
	}
      mpfr_set_z (s, ss, GMP_RNDN);
      
      MPFR_SET_EXP(s, MPFR_GET_EXP (s) + exps);
      TMP_FREE(marker); /* don't need ss anymore */
      
      if (n>0) 
	mpfr_mul_2ui(s, s, n, GMP_RNDU);
      else 
	mpfr_div_2ui(s, s, -n, GMP_RNDU);
      
      /* error is at most 2^K*(3l*(l+1)) ulp for mpfr_exp2_aux */
      l = (precy < SWITCH) ? 3*l*(l+1) : l*(l+4) ;
      k = MPFR_INT_CEIL_LOG2 (l);
      /* k = 0; while (l) { k++; l >>= 1; } */

      /* now k = ceil(log(error in ulps)/log(2)) */
      K += k;

      MPFR_TRACE ( printf("after mult. by 2^n:\n") );
      MPFR_TRACE ( MPFR_DUMP (s) );
      MPFR_TRACE ( printf("err=%d bits\n", K) );
      
      if (mpfr_can_round (s, q - K, GMP_RNDN, GMP_RNDZ,
			  precy + (rnd_mode == GMP_RNDN)) )
	break;
      MPFR_TRACE (printf("prec++, use %d\n", q+BITS_PER_MP_LIMB) );
      MPFR_TRACE (printf("q=%d q-K=%d precy=%d\n",q,q-K,precy) );
      q += BITS_PER_MP_LIMB;
      mpfr_set_prec (r, q);
      mpfr_set_prec (s, q);
      mpfr_set_prec (t, q);
    }
  
  inexact = mpfr_set (y, s, rnd_mode);

  mpfr_clear (r); 
  mpfr_clear (s); 
  mpfr_clear (t);

  return inexact;
}
static void
test_urandom (long nbtests, mpfr_prec_t prec, mpfr_rnd_t rnd, long bit_index,
              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;
  mp_size_t limb_index = 0;
  mp_limb_t limb_mask = 0;
  long count = 0;
  int i;
  int inex = 1;

  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_urandom\n");
      exit (1);
    }

  mpfr_init2 (x, prec);
  xn = 1 + (prec - 1) / mp_bits_per_limb;
  sh = xn * mp_bits_per_limb - prec;
  if (bit_index >= 0 && bit_index < prec)
    {
      /* compute the limb index and limb mask to fetch the bit #bit_index */
      limb_index = (prec - bit_index) / mp_bits_per_limb;
      i = 1 + bit_index - (bit_index / mp_bits_per_limb) * mp_bits_per_limb;
      limb_mask = MPFR_LIMB_ONE << (mp_bits_per_limb - i);
    }

  for (k = 0; k < nbtests; k++)
    {
      i = mpfr_urandom (x, RANDS, rnd);
      inex = (i != 0) && inex;
      /* check that lower bits are zero */
      if (MPFR_MANT(x)[0] & MPFR_LIMB_MASK(sh) && !MPFR_IS_ZERO (x))
        {
          printf ("Error: mpfr_urandom() returns invalid numbers:\n");
          mpfr_print_binary (x); puts ("");
          exit (1);
        }
      /* check that the value is in [0,1] */
      if (mpfr_cmp_ui (x, 0) < 0 || mpfr_cmp_ui (x, 1) > 0)
        {
          printf ("Error: mpfr_urandom() returns number outside [0, 1]:\n");
          mpfr_print_binary (x); puts ("");
          exit (1);
        }

      d = mpfr_get_d1 (x); av += d; var += d*d;
      i = (int)(size_tab * d);
      if (d == 1.0) i --;
      tab[i]++;

      if (limb_mask && (MPFR_MANT (x)[limb_index] & limb_mask))
        count ++;
    }

  if (inex == 0)
    {
      /* one call in the loop pretended to return an exact number! */
      printf ("Error: mpfr_urandom() returns a zero ternary value.\n");
      exit (1);
    }

  /* coverage test */
  emin = mpfr_get_emin ();
  for (k = 0; k < 5; k++)
    {
      set_emin (k+1);
      inex = mpfr_urandom (x, RANDS, rnd);
      if ((   (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
              && (!MPFR_IS_ZERO (x) || inex != -1))
          || ((rnd == MPFR_RNDU || rnd == MPFR_RNDA)
              && (mpfr_cmp_ui (x, 1 << k) != 0 || inex != +1))
          || (rnd == MPFR_RNDN
              && (k > 0 || mpfr_cmp_ui (x, 1 << k) != 0 || inex != +1)
              && (!MPFR_IS_ZERO (x) || inex != -1)))
        {
          printf ("Error: mpfr_urandom() do not handle correctly a restricted"
                  " exponent range.\nrounding mode: %s\nternary value: %d\n"
                  "random value: ", mpfr_print_rnd_mode (rnd), inex);
          mpfr_print_binary (x); puts ("");
          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 urandom with rounding mode %s. "
          "Each integer should be close to %d.\n",
         mpfr_print_rnd_mode (rnd), (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",
         size_tab - 1, chi2);

  if (limb_mask)
    printf ("Bit #%ld is set %ld/%ld = %.1f %% of time\n",
            bit_index, count, nbtests, count * 100.0 / nbtests);

  puts ("");

  free(tab);
  return;
}
Example #15
0
int
main (int argc, char *argv[])
{
    mpfr_t x;
    long k, z, d;
    unsigned long zl, dl, N;
    int inex;

    mpfr_init2(x, 100);

    SEED_RAND (time(NULL));

    N = (argc==1) ? 1000000 : atoi(argv[1]);

    for (k = 1; k <= N; k++)
    {
        z = random() - (1 << 30);
        inex = mpfr_set_si(x, z, GMP_RNDZ);
        d = (long) mpfr_get_d1 (x);
        if (d != z) {
            fprintf(stderr, "Error in mpfr_set_si: expected %ld got %ld\n", z, d);
            exit(1);
        }
        if (inex)
        {
            fprintf(stderr,
                    "Error in mpfr_set_si: inex value incorrect for %ld: %d\n",
                    z, inex);
            exit(1);
        }
    }

    for (k = 1; k <= N; k++)
    {
        zl = random();
        inex = mpfr_set_ui (x, zl, GMP_RNDZ);
        dl = (unsigned long) mpfr_get_d1 (x);
        if (dl != zl) {
            fprintf(stderr, "Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl);
            exit(1);
        }
        if (inex)
        {
            fprintf(stderr,
                    "Error in mpfr_set_ui: inex value incorrect for %lu: %d\n",
                    zl, inex);
            exit(1);
        }
    }

    mpfr_set_prec (x, 2);
    if (mpfr_set_si (x, 5, GMP_RNDZ) >= 0)
    {
        fprintf (stderr, "Wrong inexact flag for x=5, rnd=GMP_RNDZ\n");
        exit (1);
    }

    mpfr_set_prec (x, 2);
    if (mpfr_set_si (x, -5, GMP_RNDZ) <= 0)
    {
        fprintf (stderr, "Wrong inexact flag for x=-5, rnd=GMP_RNDZ\n");
        exit (1);
    }

    mpfr_set_prec (x, 3);
    inex = mpfr_set_si(x, 77617, GMP_RNDD); /* should be 65536 */
    if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
            || inex >= 0)
    {
        fprintf(stderr, "Error in mpfr_set_si(x:3, 77617, GMP_RNDD)\n");
        mpfr_print_binary(x);
        putchar('\n');
        exit(1);
    }
    inex = mpfr_set_ui(x, 77617, GMP_RNDD); /* should be 65536 */
    if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
            || inex >= 0)
    {
        fprintf(stderr, "Error in mpfr_set_ui(x:3, 77617, GMP_RNDD)\n");
        mpfr_print_binary(x);
        putchar('\n');
        exit(1);
    }

    mpfr_set_prec(x, 2);
    inex = mpfr_set_si(x, 33096, GMP_RNDU);
    if (mpfr_get_d1 (x) != 49152.0 || inex <= 0)
    {
        fprintf(stderr, "Error in mpfr_set_si, expected 49152, got %lu, inex %d\n",
                (unsigned long) mpfr_get_d1 (x), inex);
        exit(1);
    }
    inex = mpfr_set_ui(x, 33096, GMP_RNDU);
    if (mpfr_get_d1 (x) != 49152.0)
    {
        fprintf(stderr, "Error in mpfr_set_ui, expected 49152, got %lu, inex %d\n",
                (unsigned long) mpfr_get_d1 (x), inex);
        exit(1);
    }

    mpfr_set_si (x, -1, GMP_RNDN);
    mpfr_set_ui (x, 0, GMP_RNDN);
    if (MPFR_SIGN (x) < 0)
    {
        fprintf (stderr, "mpfr_set_ui (x, 0) gives -0\n");
        exit (1);
    }

    mpfr_set_si (x, -1, GMP_RNDN);
    mpfr_set_si (x, 0, GMP_RNDN);
    if (MPFR_SIGN (x) < 0)
    {
        fprintf (stderr, "mpfr_set_si (x, 0) gives -0\n");
        exit (1);
    }

    /* check potential bug in case mp_limb_t is unsigned */
    mpfr_set_emax (0);
    mpfr_set_si (x, -1, GMP_RNDN);
    if (mpfr_sgn (x) >= 0)
    {
        fprintf (stderr, "mpfr_set_si (x, -1) fails\n");
        exit (1);
    }

    mpfr_set_emax (5);
    mpfr_set_prec (x, 2);
    mpfr_set_si (x, -31, GMP_RNDN);
    if (mpfr_sgn (x) >= 0)
    {
        fprintf (stderr, "mpfr_set_si (x, -31) fails\n");
        exit (1);
    }

    mpfr_clear(x);

    return 0;
}
Example #16
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y, z;
  unsigned long k, n;
  volatile double d;
  double dd;

  tests_start_mpfr ();
  mpfr_test_init ();

#ifndef MPFR_DOUBLE_SPEC
  printf ("Warning! The MPFR_DOUBLE_SPEC macro is not defined. This means\n"
          "that you do not have a conforming C implementation and problems\n"
          "may occur with conversions between MPFR numbers and standard\n"
          "floating-point types. Please contact the MPFR team.\n");
#elif MPFR_DOUBLE_SPEC == 0
  /*
  printf ("The type 'double' of your C implementation does not seem to\n"
          "correspond to the IEEE-754 double precision. Though code has\n"
          "been written to support such implementations, tests have been\n"
          "done only on IEEE-754 double-precision implementations and\n"
          "conversions between MPFR numbers and standard floating-point\n"
          "types may be inaccurate. You may wish to contact the MPFR team\n"
          "for further testing.\n");
  */
  printf ("The type 'double' of your C implementation does not seem to\n"
          "correspond to the IEEE-754 double precision. Such particular\n"
          "implementations are not supported yet, and conversions between\n"
          "MPFR numbers and standard floating-point types may be very\n"
          "inaccurate.\n");
  printf ("FLT_RADIX    = %ld\n", (long) FLT_RADIX);
  printf ("DBL_MANT_DIG = %ld\n", (long) DBL_MANT_DIG);
  printf ("DBL_MIN_EXP  = %ld\n", (long) DBL_MIN_EXP);
  printf ("DBL_MAX_EXP  = %ld\n", (long) DBL_MAX_EXP);
#endif

  mpfr_init (x);

  mpfr_set_nan (x);
  d = mpfr_get_d (x, MPFR_RNDN);
  if (! DOUBLE_ISNAN (d))
    {
      printf ("ERROR for NAN (1)\n");
#ifdef MPFR_NANISNAN
      printf ("The reason is that NAN == NAN. Please look at the configure "
              "output\nand Section \"In case of problem\" of the INSTALL "
              "file.\n");
#endif
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_set_d (x, d, MPFR_RNDN);
  if (! mpfr_nan_p (x))
    {
      printf ("ERROR for NAN (2)\n");
#ifdef MPFR_NANISNAN
      printf ("The reason is that NAN == NAN. Please look at the configure "
              "output\nand Section \"In case of problem\" of the INSTALL "
              "file.\n");
#endif
      exit (1);
    }

  d = 0.0;
  mpfr_set_d (x, d, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
  d = -d;
  mpfr_set_d (x, d, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 0) != 0 || MPFR_IS_POS(x))
    {
      printf ("Error in mpfr_set_d on -0\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  d = mpfr_get_d (x, MPFR_RNDN);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_set_d (x, d, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);

  mpfr_set_inf (x, -1);
  d = mpfr_get_d (x, MPFR_RNDN);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_set_d (x, d, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);

  mpfr_set_prec (x, 2);

  /* checks that denormalized are not flushed to zero */
  d = DBL_MIN; /* 2^(-1022) */
  for (n=0; n<52; n++, d /= 2.0)
    if (d != 0.0) /* should be 2^(-1022-n) */
      {
        mpfr_set_d (x, d, MPFR_RNDN);
        if (mpfr_cmp_ui_2exp (x, 1, -1022-n))
          {
            printf ("Wrong result for d=2^(%ld), ", -1022-n);
            printf ("got ");
            mpfr_out_str (stdout, 10, 10, x, MPFR_RNDN);
            printf ("\n");
            mpfr_print_binary (x);
            puts ("");
            exit (1);
          }
      }

   /* checks that rounds to nearest sets the last
     bit to zero in case of equal distance */
   mpfr_set_d (x, 5.0, MPFR_RNDN);
   if (mpfr_cmp_ui (x, 4))
     {
       printf ("Error in tset_d: expected 4.0, got ");
       mpfr_print_binary (x); putchar('\n');
       exit (1);
     }
   mpfr_set_d (x, -5.0, MPFR_RNDN);
   if (mpfr_cmp_si (x, -4))
     {
       printf ("Error in tset_d: expected -4.0, got ");
       mpfr_print_binary (x); putchar('\n');
       exit (1);
     }

   mpfr_set_d (x, 9.84891017624509146344e-01, MPFR_RNDU);
   if (mpfr_cmp_ui (x, 1))
     {
       printf ("Error in tset_d: expected 1.0, got ");
       mpfr_print_binary (x); putchar('\n');
       exit (1);
     }

  mpfr_init2 (z, 32);
  mpfr_set_d (z, 1.0, (mpfr_rnd_t) 0);
  if (mpfr_cmp_ui (z, 1))
    {
      mpfr_print_binary (z); puts ("");
      printf ("Error: 1.0 != 1.0\n");
      exit (1);
    }
  mpfr_set_prec (x, 53);
  mpfr_init2 (y, 53);
  mpfr_set_d (x, d=-1.08007920352320089721e+150, (mpfr_rnd_t) 0);
  if (mpfr_get_d1 (x) != d)
    {
      mpfr_print_binary (x); puts ("");
      printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
              d, mpfr_get_d1 (x));
      exit (1);
    }

  mpfr_set_d (x, 8.06294740693074521573e-310, (mpfr_rnd_t) 0);
  d = -6.72658901114033715233e-165;
  mpfr_set_d (x, d, (mpfr_rnd_t) 0);
  if (d != mpfr_get_d1 (x))
    {
      mpfr_print_binary (x);
      puts ("");
      printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
              d, mpfr_get_d1 (x));
      exit (1);
    }

  n = (argc==1) ? 500000 : atoi(argv[1]);
  for (k = 1; k <= n; k++)
    {
      do
        {
          d = DBL_RAND ();
        }
#ifdef HAVE_DENORMS
      while (0);
#else
      while (ABS(d) < DBL_MIN);
#endif
      mpfr_set_d (x, d, (mpfr_rnd_t) 0);
      dd = mpfr_get_d1 (x);
      if (d != dd && !(Isnan(d) && Isnan(dd)))
        {
          printf ("Mismatch on : %1.18g != %1.18g\n", d, mpfr_get_d1 (x));
          mpfr_print_binary (x);
          puts ("");
          exit (1);
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);

  tests_end_mpfr ();
  return 0;
}
Example #17
0
File: tadd.c Project: mahdiz/mpclib
void
check64 (void)
{
  mpfr_t x, t, u;

  mpfr_init (x);
  mpfr_init (t);
  mpfr_init (u);

  mpfr_set_prec (x, 29);
  mpfr_set_str_raw (x, "1.1101001000101111011010010110e-3");
  mpfr_set_prec (t, 58);
  mpfr_set_str_raw (t, "0.11100010011111001001100110010111110110011000000100101E-1");
  mpfr_set_prec (u, 29);
  mpfr_add (u, x, t, GMP_RNDD);
  mpfr_set_str_raw (t, "1.0101011100001000011100111110e-1");
  if (mpfr_cmp (u, t))
    {
      fprintf (stderr, "mpfr_add(u, x, t) failed for prec(x)=29, prec(t)=58\n");
      printf ("expected "); mpfr_out_str (stdout, 2, 29, t, GMP_RNDN);
      putchar ('\n');
      printf ("got      "); mpfr_out_str (stdout, 2, 29, u, GMP_RNDN);
      putchar ('\n');
      exit(1);
    }

  mpfr_set_prec (x, 4);
  mpfr_set_str_raw (x, "-1.0E-2");
  mpfr_set_prec (t, 2);
  mpfr_set_str_raw (t, "-1.1e-2");
  mpfr_set_prec (u, 2);
  mpfr_add (u, x, t, GMP_RNDN);
  if (MPFR_MANT(u)[0] << 2)
    {
      fprintf (stderr, "result not normalized for prec=2\n");
      mpfr_print_binary (u); putchar ('\n');
      exit (1);
    }
  mpfr_set_str_raw (t, "-1.0e-1");
  if (mpfr_cmp (u, t))
    {
      fprintf (stderr, "mpfr_add(u, x, t) failed for prec(x)=4, prec(t)=2\n");
      printf ("expected -1.0e-1\n");
      printf ("got      "); mpfr_out_str (stdout, 2, 4, u, GMP_RNDN);
      putchar ('\n');
      exit (1);
    }

  mpfr_set_prec (x, 8);
  mpfr_set_str_raw (x, "-0.10011010"); /* -77/128 */
  mpfr_set_prec (t, 4);
  mpfr_set_str_raw (t, "-1.110e-5"); /* -7/128 */
  mpfr_set_prec (u, 4);
  mpfr_add (u, x, t, GMP_RNDN); /* should give -5/8 */
  mpfr_set_str_raw (t, "-1.010e-1");
  if (mpfr_cmp (u, t)) {
    fprintf (stderr, "mpfr_add(u, x, t) failed for prec(x)=8, prec(t)=4\n");
    printf ("expected -1.010e-1\n");
    printf ("got      "); mpfr_out_str (stdout, 2, 4, u, GMP_RNDN);
    putchar ('\n');
    exit (1);
  }

  mpfr_set_prec (x, 112); mpfr_set_prec (t, 98); mpfr_set_prec (u, 54);
  mpfr_set_str_raw (x, "-0.11111100100000000011000011100000101101010001000111E-401");
  mpfr_set_str_raw (t, "0.10110000100100000101101100011111111011101000111000101E-464");
  mpfr_add (u, x, t, GMP_RNDN);
  if (mpfr_cmp (u, x)) {
    fprintf (stderr, "mpfr_add(u, x, t) failed for prec(x)=112, prec(t)=98\n");
    exit (1);
  }

  mpfr_set_prec (x, 92); mpfr_set_prec (t, 86); mpfr_set_prec (u, 53);
  mpfr_set_d (x, -5.03525136761487735093e-74, GMP_RNDN);
  mpfr_set_d (t, 8.51539046314262304109e-91, GMP_RNDN);
  mpfr_add (u, x, t, GMP_RNDN);
  if (mpfr_get_d1 (u) != -5.0352513676148773509283672e-74) {
    fprintf (stderr, "mpfr_add(u, x, t) failed for prec(x)=92, prec(t)=86\n");
    exit (1);
  }

  mpfr_set_prec(x, 53); mpfr_set_prec(t, 76); mpfr_set_prec(u, 76);
  mpfr_set_str_raw(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
  mpfr_set_str_raw(t, "-0.1011000101110010000101111111011111010001110011110111100110101011110010011111");
  mpfr_sub(u, x, t, GMP_RNDU);
  mpfr_set_str_raw(t, "0.1011000101110010000101111111011100111111101010011011110110101011101000000100");
  if (mpfr_cmp(u,t)) {
    printf("expect "); mpfr_print_binary(t); putchar('\n');
    fprintf (stderr, "mpfr_add failed for precisions 53-76\n"); exit(1);
  }
  mpfr_set_prec(x, 53); mpfr_set_prec(t, 108); mpfr_set_prec(u, 108);
  mpfr_set_str_raw(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
  mpfr_set_str_raw(t, "-0.101100010111001000010111111101111101000111001111011110011010101111001001111000111011001110011000000000111111");
  mpfr_sub(u, x, t, GMP_RNDU);
  mpfr_set_str_raw(t, "0.101100010111001000010111111101110011111110101001101111011010101110100000001011000010101110011000000000111111");
  if (mpfr_cmp(u,t)) {
    printf("expect "); mpfr_print_binary(t); putchar('\n');
    fprintf(stderr, "mpfr_add failed for precisions 53-108\n"); exit(1);
  }
  mpfr_set_prec(x, 97); mpfr_set_prec(t, 97); mpfr_set_prec(u, 97);
  mpfr_set_str_raw(x, "0.1111101100001000000001011000110111101000001011111000100001000101010100011111110010000000000000000E-39");
  mpfr_set_ui(t, 1, GMP_RNDN);
  mpfr_add(u, x, t, GMP_RNDN);
  mpfr_set_str_raw(x, "0.1000000000000000000000000000000000000000111110110000100000000101100011011110100000101111100010001E1");
  if (mpfr_cmp(u,x)) {
    fprintf(stderr, "mpfr_add failed for precision 97\n"); exit(1);
  }
  mpfr_set_prec(x, 128); mpfr_set_prec(t, 128); mpfr_set_prec(u, 128);
  mpfr_set_str_raw(x, "0.10101011111001001010111011001000101100111101000000111111111011010100001100011101010001010111111101111010100110111111100101100010E-4");
  mpfr_set(t, x, GMP_RNDN);
  mpfr_sub(u, x, t, GMP_RNDN);
  mpfr_set_prec(x, 96); mpfr_set_prec(t, 96); mpfr_set_prec(u, 96);
  mpfr_set_str_raw(x, "0.111000000001110100111100110101101001001010010011010011100111100011010100011001010011011011000010E-4");
  mpfr_set(t, x, GMP_RNDN);
  mpfr_sub(u, x, t, GMP_RNDN);
  mpfr_set_prec(x, 85); mpfr_set_prec(t, 85); mpfr_set_prec(u, 85);
  mpfr_set_str_raw(x, "0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4");
  mpfr_set_str_raw(t, "0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4");
  mpfr_sub(u, x, t, GMP_RNDU);
  mpfr_sub(x, x, t, GMP_RNDU);
  if (mpfr_cmp(x, u) != 0) {
    printf("Error in mpfr_sub: u=x-t and x=x-t give different results\n");
    exit(1);
  }
  if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] & 
      ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0) {
    printf("Error in mpfr_sub: result is not msb-normalized (1)\n"); exit(1);
  }
  mpfr_set_prec(x, 65); mpfr_set_prec(t, 65); mpfr_set_prec(u, 65);
  mpfr_set_str_raw(x, "0.10011010101000110101010000000011001001001110001011101011111011101E623");
  mpfr_set_str_raw(t, "0.10011010101000110101010000000011001001001110001011101011111011100E623");
  mpfr_sub(u, x, t, GMP_RNDU);
  if (mpfr_get_d1 (u) != 9.4349060620538533806e167) { /* 2^558 */
    printf("Error (1) in mpfr_sub\n"); exit(1);
  }

  mpfr_set_prec(x, 64); mpfr_set_prec(t, 64); mpfr_set_prec(u, 64);
  mpfr_set_str_raw(x, "0.1000011110101111011110111111000011101011101111101101101100000100E-220");
  mpfr_set_str_raw(t, "0.1000011110101111011110111111000011101011101111101101010011111101E-220");
  mpfr_add(u, x, t, GMP_RNDU);
  if ((MPFR_MANT(u)[0] & 1) != 1) { 
    printf("error in mpfr_add with rnd_mode=GMP_RNDU\n");
    printf("b=  "); mpfr_print_binary(x); putchar('\n');
    printf("c=  "); mpfr_print_binary(t); putchar('\n');
    printf("b+c="); mpfr_print_binary(u); putchar('\n');
    exit(1);
  }

  /* bug found by Norbert Mueller, 14 Sep 2000 */
  mpfr_set_prec(x, 56); mpfr_set_prec(t, 83); mpfr_set_prec(u, 10);
  mpfr_set_str_raw(x, "0.10001001011011001111101100110100000101111010010111010111E-7");
  mpfr_set_str_raw(t, "0.10001001011011001111101100110100000101111010010111010111000000000111110110110000100E-7");
  mpfr_sub(u, x, t, GMP_RNDU);

  /* array bound write found by Norbert Mueller, 26 Sep 2000 */
  mpfr_set_prec(x, 109); mpfr_set_prec(t, 153); mpfr_set_prec(u, 95);
  mpfr_set_str_raw(x,"0.1001010000101011101100111000110001111111111111111111111111111111111111111111111111111111111111100000000000000E33");
  mpfr_set_str_raw(t,"-0.100101000010101110110011100011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100101101000000100100001100110111E33");
  mpfr_add(u, x, t, GMP_RNDN);

  /* array bound writes found by Norbert Mueller, 27 Sep 2000 */
  mpfr_set_prec(x, 106); mpfr_set_prec(t, 53); mpfr_set_prec(u, 23);
  mpfr_set_str_raw(x, "-0.1000011110101111111001010001000100001011000000000000000000000000000000000000000000000000000000000000000000E-59");
  mpfr_set_str_raw(t, "-0.10000111101011111110010100010001101100011100110100000E-59");
  mpfr_sub(u, x, t, GMP_RNDN);
  mpfr_set_prec(x, 177); mpfr_set_prec(t, 217); mpfr_set_prec(u, 160);
  mpfr_set_str_raw(x, "-0.111010001011010000111001001010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E35");
  mpfr_set_str_raw(t, "0.1110100010110100001110010010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111011010011100001111001E35");
  mpfr_add(u, x, t, GMP_RNDN);
  mpfr_set_prec(x, 214); mpfr_set_prec(t, 278); mpfr_set_prec(u, 207);
  mpfr_set_str_raw(x, "0.1000100110100110101101101101000000010000100111000001001110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E66");
  mpfr_set_str_raw(t, "-0.10001001101001101011011011010000000100001001110000010011100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111011111001001100011E66");
  mpfr_add(u, x, t, GMP_RNDN);
  mpfr_set_prec(x, 32); mpfr_set_prec(t, 247); mpfr_set_prec(u, 223);
  mpfr_set_str_raw(x, "0.10000000000000000000000000000000E1");
  mpfr_set_str_raw(t, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100000100011110000101110110011101110100110110111111011010111100100000000000000000000000000E0");
  mpfr_sub(u, x, t, GMP_RNDN);
  if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] & 
      ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0) {
    printf("Error in mpfr_sub: result is not msb-normalized (2)\n"); exit(1);
  }

  /* bug found by Nathalie Revol, 21 March 2001 */
  mpfr_set_prec (x, 65);
  mpfr_set_prec (t, 65);
  mpfr_set_prec (u, 65);
  mpfr_set_str_raw (x, "0.11100100101101001100111011111111110001101001000011101001001010010E-35");
  mpfr_set_str_raw (t, "0.10000000000000000000000000000000000001110010010110100110011110000E1");
  mpfr_sub (u, t, x, GMP_RNDU);
  if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] & 
      ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0) {
    fprintf(stderr, "Error in mpfr_sub: result is not msb-normalized (3)\n");
    exit (1);
  }

  /* bug found by Fabrice Rouillier, 27 Mar 2001 */
  mpfr_set_prec (x, 107);
  mpfr_set_prec (t, 107);
  mpfr_set_prec (u, 107);
  mpfr_set_str_raw (x, "0.10111001001111010010001000000010111111011011011101000001001000101000000000000000000000000000000000000000000E315");
  mpfr_set_str_raw (t, "0.10000000000000000000000000000000000101110100100101110110000001100101011111001000011101111100100100111011000E350");
  mpfr_sub (u, x, t, GMP_RNDU);
  if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] & 
      ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0) {
    fprintf(stderr, "Error in mpfr_sub: result is not msb-normalized (4)\n");
    exit (1);
  }
  
  /* checks that NaN flag is correctly reset */
  mpfr_set_d (t, 1.0, GMP_RNDN);
  mpfr_set_d (u, 1.0, GMP_RNDN);
  mpfr_set_nan (x);
  mpfr_add (x, t, u, GMP_RNDN);
  if (mpfr_cmp_ui (x, 2)) {
    fprintf (stderr, "Error in mpfr_add: 1+1 gives %e\n", mpfr_get_d1 (x));
    exit (1);
  }

  mpfr_clear(x); mpfr_clear(t); mpfr_clear(u);
}
Example #18
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);
      /* check that lower bits are zero */
      if (MPFR_MANT(x)[0] & MPFR_LIMB_MASK(sh))
        {
          printf ("Error: mpfr_urandomb() returns invalid numbers:\n");
          mpfr_print_binary (x); puts ("");
          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;
}
Example #19
0
/* use Brent's formula exp(x) = (1+r+r^2/2!+r^3/3!+...)^(2^K)*2^n
   where x = n*log(2)+(2^K)*r
   together with Brent-Kung O(t^(1/2)) algorithm for the evaluation of
   power series. The resulting complexity is O(n^(1/3)*M(n)).
*/
int 
mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) 
{
  int n, K, precy, q, k, l, err, exps, inexact;
  mpfr_t r, s, t; mpz_t ss;
  TMP_DECL(marker);

  precy = MPFR_PREC(y);

  n = (int) (mpfr_get_d1 (x) / LOG2);

  /* for the O(n^(1/2)*M(n)) method, the Taylor series computation of
     n/K terms costs about n/(2K) multiplications when computed in fixed
     point */
  K = (precy<SWITCH) ? _mpfr_isqrt((precy + 1) / 2) : _mpfr_cuberoot (4*precy);
  l = (precy-1)/K + 1;
  err = K + (int) _mpfr_ceil_log2 (2.0 * (double) l + 18.0);
  /* add K extra bits, i.e. failure probability <= 1/2^K = O(1/precy) */
  q = precy + err + K + 3;
  mpfr_init2 (r, q);
  mpfr_init2 (s, q);
  mpfr_init2 (t, q);
  /* the algorithm consists in computing an upper bound of exp(x) using
     a precision of q bits, and see if we can round to MPFR_PREC(y) taking
     into account the maximal error. Otherwise we increase q. */
  do {
#ifdef DEBUG
  printf("n=%d K=%d l=%d q=%d\n",n,K,l,q);
#endif

  /* if n<0, we have to get an upper bound of log(2)
     in order to get an upper bound of r = x-n*log(2) */
  mpfr_const_log2 (s, (n>=0) ? GMP_RNDZ : GMP_RNDU);
#ifdef DEBUG
  printf("n=%d log(2)=",n); mpfr_print_binary(s); putchar('\n');
#endif
  mpfr_mul_ui (r, s, (n<0) ? -n : n, (n>=0) ? GMP_RNDZ : GMP_RNDU); 
  if (n<0) mpfr_neg(r, r, GMP_RNDD);
  /* r = floor(n*log(2)) */

#ifdef DEBUG
  printf("x=%1.20e\n", mpfr_get_d1 (x));
  printf(" ="); mpfr_print_binary(x); putchar('\n');
  printf("r=%1.20e\n", mpfr_get_d1 (r));
  printf(" ="); mpfr_print_binary(r); putchar('\n');
#endif
  mpfr_sub(r, x, r, GMP_RNDU);
  if (MPFR_SIGN(r)<0) { /* initial approximation n was too large */
    n--;
    mpfr_mul_ui(r, s, (n<0) ? -n : n, GMP_RNDZ);
    if (n<0) mpfr_neg(r, r, GMP_RNDD);
    mpfr_sub(r, x, r, GMP_RNDU);
  }
#ifdef DEBUG
  printf("x-r=%1.20e\n", mpfr_get_d1 (r));
  printf(" ="); mpfr_print_binary(r); putchar('\n');
  if (MPFR_SIGN(r)<0) { fprintf(stderr,"Error in mpfr_exp: r<0\n"); exit(1); }
#endif
  mpfr_div_2ui(r, r, K, GMP_RNDU); /* r = (x-n*log(2))/2^K */

  TMP_MARK(marker);
  MY_INIT_MPZ(ss, 3 + 2*((q-1)/BITS_PER_MP_LIMB));
  exps = mpfr_get_z_exp(ss, s);
  /* s <- 1 + r/1! + r^2/2! + ... + r^l/l! */
  l = (precy<SWITCH) ? mpfr_exp2_aux(ss, r, q, &exps) /* naive method */
    : mpfr_exp2_aux2(ss, r, q, &exps); /* Brent/Kung method */

#ifdef DEBUG
  printf("l=%d q=%d (K+l)*q^2=%1.3e\n", l, q, (K+l)*(double)q*q);
#endif

  for (k=0;k<K;k++) {
    mpz_mul(ss, ss, ss); exps <<= 1;
    exps += mpz_normalize(ss, ss, q);
  }
  mpfr_set_z(s, ss, GMP_RNDN); MPFR_EXP(s) += exps;
  TMP_FREE(marker); /* don't need ss anymore */

  if (n>0) mpfr_mul_2ui(s, s, n, GMP_RNDU);
  else mpfr_div_2ui(s, s, -n, GMP_RNDU);

  /* error is at most 2^K*(3l*(l+1)) ulp for mpfr_exp2_aux */
  if (precy<SWITCH) l = 3*l*(l+1);
  else l = l*(l+4);
  k=0; while (l) { k++; l >>= 1; }
  /* now k = ceil(log(error in ulps)/log(2)) */
  K += k;
#ifdef DEBUG
    printf("after mult. by 2^n:\n");
    if (MPFR_EXP(s) > -1024)
      printf("s=%1.20e\n", mpfr_get_d1 (s));
    printf(" ="); mpfr_print_binary(s); putchar('\n');
    printf("err=%d bits\n", K);
#endif

  l = mpfr_can_round(s, q-K, GMP_RNDN, rnd_mode, precy);
  if (l==0) {
#ifdef DEBUG
     printf("not enough precision, use %d\n", q+BITS_PER_MP_LIMB);
     printf("q=%d q-K=%d precy=%d\n",q,q-K,precy);
#endif
     q += BITS_PER_MP_LIMB;
     mpfr_set_prec(r, q); mpfr_set_prec(s, q); mpfr_set_prec(t, q);
  }
  } while (l==0);

  inexact = mpfr_set (y, s, rnd_mode);

  mpfr_clear(r); mpfr_clear(s); mpfr_clear(t);
  return inexact;
}