コード例 #1
0
ファイル: tadd_ui.c プロジェクト: mmanley/Antares
static void
check_nans (void)
{
  mpfr_t  x, y;

  mpfr_init2 (x, 123L);
  mpfr_init2 (y, 123L);

  /* nan + 2394875 == nan */
  mpfr_set_nan (x);
  mpfr_add_ui (y, x, 2394875L, GMP_RNDN);
  MPFR_ASSERTN (mpfr_nan_p (y));

  /* +inf + 2394875 == +inf */
  mpfr_set_inf (x, 1);
  mpfr_add_ui (y, x, 2394875L, GMP_RNDN);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (mpfr_sgn (y) > 0);

  /* -inf + 2394875 == -inf */
  mpfr_set_inf (x, -1);
  mpfr_add_ui (y, x, 2394875L, GMP_RNDN);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (mpfr_sgn (y) < 0);

  mpfr_clear (x);
  mpfr_clear (y);
}
コード例 #2
0
static void check_intmax (void)
{
#ifdef _MPFR_H_HAVE_INTMAX_T
  mpfr_t x;

  mpfr_init2 (x, sizeof(uintmax_t)*CHAR_BIT);
  
  /* Check NAN */
  mpfr_set_nan(x);
  if (mpfr_fits_uintmax_p(x, GMP_RNDN))
    ERROR1;
  if (mpfr_fits_intmax_p(x, GMP_RNDN))
    ERROR1;

  /* Check INF */
  mpfr_set_inf(x, 1);
  if (mpfr_fits_uintmax_p(x, GMP_RNDN))
    ERROR1;
  if (mpfr_fits_intmax_p(x, GMP_RNDN))
    ERROR1;
  
  /* Check Zero */
  MPFR_SET_ZERO(x);
  if (!mpfr_fits_uintmax_p(x, GMP_RNDN))
    ERROR2;
  if (!mpfr_fits_intmax_p(x, GMP_RNDN))
    ERROR2;

  /* Check small op */
  mpfr_set_str1 (x, "1@-1");
  if (!mpfr_fits_uintmax_p(x, GMP_RNDN))
    ERROR2;
  if (!mpfr_fits_intmax_p(x, GMP_RNDN))
    ERROR2;

  /* Check all other values */
  mpfr_set_uj (x, UINTMAX_MAX, GMP_RNDN);
  mpfr_add_ui (x, x, 1, GMP_RNDN);
  if (mpfr_fits_uintmax_p (x, GMP_RNDN))
    ERROR1;
  mpfr_set_uj (x, UINTMAX_MAX, GMP_RNDN);
  if (!mpfr_fits_uintmax_p (x, GMP_RNDN))
    ERROR2;
  mpfr_set_sj (x, INTMAX_MAX, GMP_RNDN);
  mpfr_add_ui (x, x, 1, GMP_RNDN);
  if (mpfr_fits_intmax_p (x, GMP_RNDN))
    ERROR1;
  mpfr_set_sj (x, INTMAX_MAX, GMP_RNDN);
  if (!mpfr_fits_intmax_p (x, GMP_RNDN))
    ERROR2;
  mpfr_set_sj (x, INTMAX_MIN, GMP_RNDN);
  if (!mpfr_fits_intmax_p (x, GMP_RNDN))
    ERROR2;
  mpfr_sub_ui (x, x, 1, GMP_RNDN);
  if (mpfr_fits_intmax_p (x, GMP_RNDN))
    ERROR1;

  mpfr_clear (x);
#endif
}
コード例 #3
0
ファイル: tadd.c プロジェクト: qsnake/mpfr
/* check case when c does not overlap with a, but both b and c count
   for rounding */
static void
check_case_1b (void)
{
    mpfr_t a, b, c;
    unsigned int prec_a, prec_b, prec_c, dif;

    mpfr_init (a);
    mpfr_init (b);
    mpfr_init (c);

    {
        prec_a = MPFR_PREC_MIN + (randlimb () % 63);
        mpfr_set_prec (a, prec_a);
        for (prec_b = prec_a + 2; prec_b <= 64; prec_b++)
        {
            dif = prec_b - prec_a;
            mpfr_set_prec (b, prec_b);
            /* b = 1 - 2^(-prec_a) + 2^(-prec_b) */
            mpfr_set_ui (b, 1, MPFR_RNDN);
            mpfr_div_2exp (b, b, dif, MPFR_RNDN);
            mpfr_sub_ui (b, b, 1, MPFR_RNDN);
            mpfr_div_2exp (b, b, prec_a, MPFR_RNDN);
            mpfr_add_ui (b, b, 1, MPFR_RNDN);
            for (prec_c = dif; prec_c <= 64; prec_c++)
            {
                /* c = 2^(-prec_a) - 2^(-prec_b) */
                mpfr_set_prec (c, prec_c);
                mpfr_set_si (c, -1, MPFR_RNDN);
                mpfr_div_2exp (c, c, dif, MPFR_RNDN);
                mpfr_add_ui (c, c, 1, MPFR_RNDN);
                mpfr_div_2exp (c, c, prec_a, MPFR_RNDN);
                test_add (a, b, c, MPFR_RNDN);
                if (mpfr_cmp_ui (a, 1) != 0)
                {
                    printf ("case (1b) failed for prec_a=%u, prec_b=%u,"
                            " prec_c=%u\n", prec_a, prec_b, prec_c);
                    printf ("b=");
                    mpfr_print_binary(b);
                    puts ("");
                    printf ("c=");
                    mpfr_print_binary(c);
                    puts ("");
                    printf ("a=");
                    mpfr_print_binary(a);
                    puts ("");
                    exit (1);
                }
            }
        }
    }

    mpfr_clear (a);
    mpfr_clear (b);
    mpfr_clear (c);
}
コード例 #4
0
ファイル: tadd.c プロジェクト: mahdiz/mpclib
/* check case when c does not overlap with a, but both b and c count
   for rounding */
void
check_case_1b (void)
{
  mpfr_t a, b, c;
  unsigned int prec_a, prec_b, prec_c, dif;

  mpfr_init (a);
  mpfr_init (b);
  mpfr_init (c);

  for (prec_a = 2; prec_a <= 64; prec_a++)
    {
      mpfr_set_prec (a, prec_a);
      for (prec_b = prec_a + 2; prec_b <= 64; prec_b++)
	{
	  dif = prec_b - prec_a;
	  mpfr_set_prec (b, prec_b);
	  /* b = 1 - 2^(-prec_a) + 2^(-prec_b) */
	  mpfr_set_ui (b, 1, GMP_RNDN);
	  mpfr_div_2exp (b, b, dif, GMP_RNDN);
	  mpfr_sub_ui (b, b, 1, GMP_RNDN);
	  mpfr_div_2exp (b, b, prec_a, GMP_RNDN);
	  mpfr_add_ui (b, b, 1, GMP_RNDN);
	  for (prec_c = dif; prec_c <= 64; prec_c++)
	    {
	      /* c = 2^(-prec_a) - 2^(-prec_b) */
	      mpfr_set_prec (c, prec_c);
	      mpfr_set_si (c, -1, GMP_RNDN);
	      mpfr_div_2exp (c, c, dif, GMP_RNDN);
	      mpfr_add_ui (c, c, 1, GMP_RNDN);
	      mpfr_div_2exp (c, c, prec_a, GMP_RNDN);
	      mpfr_add (a, b, c, GMP_RNDN);
	      if (mpfr_cmp_ui (a, 1) != 0)
		{
		  fprintf (stderr, "case (1b) failed for prec_a=%u, prec_b=%u, prec_c=%u\n", prec_a, prec_b, prec_c);
		  printf("b="); mpfr_print_binary(b); putchar('\n');
		  printf("c="); mpfr_print_binary(c); putchar('\n');
		  printf("a="); mpfr_print_binary(a); putchar('\n');
		  exit (1);
		}
	    }
	}
    }

  mpfr_clear (a);
  mpfr_clear (b);
  mpfr_clear (c);
}
コード例 #5
0
ファイル: tsub.c プロジェクト: axDev-toolchain/mpfr
/* Bug found by Jakub Jelinek
 * http://bugzilla.redhat.com/643657
 * https://gforge.inria.fr/tracker/index.php?func=detail&aid=11301
 * The consequence can be either an assertion failure (i = 2 in the
 * testcase below, in debug mode) or an incorrectly rounded value.
 */
static void
bug20101017 (void)
{
    mpfr_t a, b, c;
    int inex;
    int i;

    mpfr_init2 (a, GMP_NUMB_BITS * 2);
    mpfr_init2 (b, GMP_NUMB_BITS);
    mpfr_init2 (c, GMP_NUMB_BITS);

    /* a = 2^(2N) + k.2^(2N-1) + 2^N and b = 1
       with N = GMP_NUMB_BITS and k = 0 or 1.
       c = a - b should round to the same value as a. */

    for (i = 2; i <= 3; i++)
    {
        mpfr_set_ui_2exp (a, i, GMP_NUMB_BITS - 1, MPFR_RNDN);
        mpfr_add_ui (a, a, 1, MPFR_RNDN);
        mpfr_mul_2ui (a, a, GMP_NUMB_BITS, MPFR_RNDN);
        mpfr_set_ui (b, 1, MPFR_RNDN);
        inex = mpfr_sub (c, a, b, MPFR_RNDN);
        mpfr_set (b, a, MPFR_RNDN);
        if (! mpfr_equal_p (c, b))
        {
            printf ("Error in bug20101017 for i = %d.\n", i);
            printf ("Expected ");
            mpfr_out_str (stdout, 16, 0, b, MPFR_RNDN);
            putchar ('\n');
            printf ("Got      ");
            mpfr_out_str (stdout, 16, 0, c, MPFR_RNDN);
            putchar ('\n');
            exit (1);
        }
        if (inex >= 0)
        {
            printf ("Error in bug20101017 for i = %d: bad inex value.\n", i);
            printf ("Expected negative, got %d.\n", inex);
            exit (1);
        }
    }

    mpfr_set_prec (a, 64);
    mpfr_set_prec (b, 129);
    mpfr_set_prec (c, 2);
    mpfr_set_str_binary (b, "0.100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001E65");
    mpfr_set_str_binary (c, "0.10E1");
    inex = mpfr_sub (a, b, c, MPFR_RNDN);
    if (mpfr_cmp_ui_2exp (a, 1, 64) != 0 || inex >= 0)
    {
        printf ("Error in mpfr_sub for b-c for b=2^64+1+2^(-64), c=1\n");
        printf ("Expected result 2^64 with inex < 0\n");
        printf ("Got ");
        mpfr_print_binary (a);
        printf (" with inex=%d\n", inex);
        exit (1);
    }

    mpfr_clears (a, b, c, (mpfr_ptr) 0);
}
コード例 #6
0
ファイル: tatan.c プロジェクト: MaddTheSane/haiku-buildtools
/* tests intermediate underflow; WONTFIX */
static int
test_underflow (void)
{
  mpc_t z;
  mpfr_exp_t emin = mpfr_get_emin ();

  mpfr_set_emin (-10);
  mpc_init2 (z, 21);
  mpfr_set_si (mpc_realref(z), -1, GMP_RNDZ);
  mpfr_set_ui_2exp (mpc_imagref(z), 1, 20, GMP_RNDZ);
  mpfr_add_ui (mpc_imagref(z), mpc_imagref(z), 1, GMP_RNDZ);
  mpfr_div_2exp (mpc_imagref(z), mpc_imagref(z), 20, GMP_RNDZ);
  mpc_atan (z, z, MPC_RNDNN);
  if (mpfr_cmp_si_2exp (mpc_realref(z), -1066635, 20) != 0 ||
      mpfr_cmp_si_2exp (mpc_imagref(z), 1687619, 22))
    {
      printf ("Error in test_coverage\n");
      printf ("expected (-1066635/2^20 1687619/2^22)\n");
      printf ("got      ");
      mpc_out_str (stdout, 10, 20, z, MPC_RNDNN);
      printf ("\n");
      exit (1);
    }
  mpc_clear (z);
  mpfr_set_emin (emin);
}
コード例 #7
0
ファイル: context_variables.c プロジェクト: tohtsky/cboot
mpfr_t* compute_rho_to_z_matrix(unsigned long Lambda_arg, long prec){
	/* To avoid writing lambda + 1 so many times...*/
	unsigned long Lambda=Lambda_arg+1;
	mpfr_t* temps=malloc(sizeof(mpfr_t)*(Lambda));
	mpfr_init2(temps[0],prec);
	mpfr_set_ui(temps[0],8,MPFR_RNDN);
	mpfr_sqrt(temps[0],temps[0],MPFR_RNDN);
	mpfr_neg(temps[0],temps[0],MPFR_RNDN);
	for(unsigned long j=1;j<Lambda;j++){
		mpfr_init2(temps[j],prec);
		mpfr_mul_si(temps[j],temps[j-1],2*j-3,MPFR_RNDN);
		mpfr_div_ui(temps[j],temps[j],j,MPFR_RNDN); 
	}
	mpfr_sub_ui(temps[1],temps[1],2,MPFR_RNDN);
	mpfr_add_ui(temps[0],temps[0],3,MPFR_RNDN);
	mpfr_t temp;
	mpfr_init2(temp,prec);
	mpfr_t temp2;
	mpfr_init2(temp2,prec);

	mpfr_t* result=malloc(sizeof(mpfr_t)*(Lambda)*(Lambda));
	mpfr_init2(result[0],prec);
	mpfr_set_ui(result[0],1,MPFR_RNDN);
	for(unsigned long j=1; j<(Lambda*Lambda); j++){
		mpfr_init2(result[j],prec);
		mpfr_set_zero(result[j],1);
	}
	for(unsigned long j=1;j<Lambda;j++){
		mpfr_set_ui(temp,1,MPFR_RNDN);
		for(unsigned long k=0;k<=j;k++){
			mpfr_mul(temp2,temps[j-k],temp,MPFR_RNDN);
			mpfr_add(result[j+Lambda],result[j+Lambda],temp2,MPFR_RNDN);
			mpfr_mul_si(temp,temp,-2,MPFR_RNDN); 
		} 
	}
	for(unsigned long i=2;i<Lambda;i++){
		for(unsigned long j=1;j<Lambda;j++){
			for(unsigned long k=i-1;k<Lambda-j;k++){
				mpfr_mul(temp,result[Lambda*(i-1)+k],result[j+Lambda],MPFR_RNDN);
				mpfr_add(result[Lambda*i+k+j],result[Lambda*i+k+j],temp,MPFR_RNDN);
			}

		} 
	} 

	/* transposition */
	for(unsigned long i=0;i<Lambda;i++){
		for(unsigned long j=0;j<i;j++){
		mpfr_swap(result[i+Lambda*j],result[j+Lambda*i]);
		}
	}
	for(unsigned long j=0;j<Lambda;j++){
		mpfr_clear(temps[j]);
	}
	free(temps);
	mpfr_clear(temp);
	mpfr_clear(temp2);
	return result; 
}
コード例 #8
0
ファイル: si_op.c プロジェクト: SESA/EbbRT-mpfr
int
mpfr_sub_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
{
  if (u >= 0)
    return mpfr_sub_ui (y, x, u, rnd_mode);
  else
    return mpfr_add_ui (y, x, -u, rnd_mode);
}
コード例 #9
0
ファイル: zeta.c プロジェクト: mmanley/Antares
/*
   Parameters:
   s - the input floating-point number
   n, p - parameters from the algorithm
   tc - an array of p floating-point numbers tc[1]..tc[p]
   Output:
   b is the result, i.e.
   sum(tc[i]*product((s+2j)*(s+2j-1)/n^2,j=1..i-1), i=1..p)*s*n^(-s-1)
*/
static void
mpfr_zeta_part_b (mpfr_t b, mpfr_srcptr s, int n, int p, mpfr_t *tc)
{
  mpfr_t s1, d, u;
  unsigned long n2;
  int l, t;
  MPFR_GROUP_DECL (group);

  if (p == 0)
    {
      MPFR_SET_ZERO (b);
      MPFR_SET_POS (b);
      return;
    }

  n2 = n * n;
  MPFR_GROUP_INIT_3 (group, MPFR_PREC (b), s1, d, u);

  /* t equals 2p-2, 2p-3, ... ; s1 equals s+t */
  t = 2 * p - 2;
  mpfr_set (d, tc[p], GMP_RNDN);
  for (l = 1; l < p; l++)
    {
      mpfr_add_ui (s1, s, t, GMP_RNDN); /* s + (2p-2l) */
      mpfr_mul (d, d, s1, GMP_RNDN);
      t = t - 1;
      mpfr_add_ui (s1, s, t, GMP_RNDN); /* s + (2p-2l-1) */
      mpfr_mul (d, d, s1, GMP_RNDN);
      t = t - 1;
      mpfr_div_ui (d, d, n2, GMP_RNDN);
      mpfr_add (d, d, tc[p-l], GMP_RNDN);
      /* since s is positive and the tc[i] have alternate signs,
         the following is unlikely */
      if (MPFR_UNLIKELY (mpfr_cmpabs (d, tc[p-l]) > 0))
        mpfr_set (d, tc[p-l], GMP_RNDN);
    }
  mpfr_mul (d, d, s, GMP_RNDN);
  mpfr_add (s1, s, __gmpfr_one, GMP_RNDN);
  mpfr_neg (s1, s1, GMP_RNDN);
  mpfr_ui_pow (u, n, s1, GMP_RNDN);
  mpfr_mul (b, d, u, GMP_RNDN);

  MPFR_GROUP_CLEAR (group);
}
コード例 #10
0
ファイル: add_ui.c プロジェクト: BrianGladman/MPC
/* return 0 iff both the real and imaginary parts are exact */
int
mpc_add_ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd)
{
  int inex_re, inex_im;

  inex_re = mpfr_add_ui (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
  inex_im = mpfr_set (mpc_imagref(a), mpc_imagref(b), MPC_RND_IM(rnd));

  return MPC_INEX(inex_re, inex_im);
}
コード例 #11
0
ファイル: tset_sj.c プロジェクト: qsnake/mpfr
static void
check_set_uj (mpfr_prec_t pmin, mpfr_prec_t pmax, int N)
{
    mpfr_t x, y;
    mpfr_prec_t p;
    int inex1, inex2, n;
    mp_limb_t limb;

    mpfr_inits2 (pmax, x, y, (mpfr_ptr) 0);

    for ( p = pmin ; p < pmax ; p++)
    {
        mpfr_set_prec (x, p);
        mpfr_set_prec (y, p);
        for (n = 0 ; n < N ; n++)
        {
            /* mp_limb_t may be unsigned long long */
            limb = (unsigned long) randlimb ();
            inex1 = mpfr_set_uj (x, limb, MPFR_RNDN);
            inex2 = mpfr_set_ui (y, limb, MPFR_RNDN);
            if (mpfr_cmp (x, y))
            {
                printf ("ERROR for mpfr_set_uj and j=%lu and p=%lu\n",
                        (unsigned long) limb, (unsigned long) p);
                printf ("X=");
                mpfr_dump (x);
                printf ("Y=");
                mpfr_dump (y);
                exit (1);
            }
            if (inexact_sign (inex1) != inexact_sign (inex2))
            {
                printf ("ERROR for inexact(set_uj): j=%lu p=%lu\n"
                        "Inexact1= %d Inexact2= %d\n",
                        (unsigned long) limb, (unsigned long) p, inex1, inex2);
                exit (1);
            }
        }
    }
    /* Special case */
    mpfr_set_prec (x, sizeof(uintmax_t)*CHAR_BIT);
    inex1 = mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
    if (inex1 != 0 || mpfr_sgn(x) <= 0)
        ERROR ("inexact / UINTMAX_MAX");
    inex1 = mpfr_add_ui (x, x, 1, MPFR_RNDN);
    if (inex1 != 0 || !mpfr_powerof2_raw (x)
            || MPFR_EXP (x) != (sizeof(uintmax_t)*CHAR_BIT+1) )
        ERROR ("power of 2");
    mpfr_set_uj (x, 0, MPFR_RNDN);
    if (!MPFR_IS_ZERO (x))
        ERROR ("Setting 0");

    mpfr_clears (x, y, (mpfr_ptr) 0);
}
コード例 #12
0
ファイル: eint.c プロジェクト: mmanley/Antares
/* Return in y an approximation of Ei(x) using the asymptotic expansion:
   Ei(x) = exp(x)/x * (1 + 1/x + 2/x^2 + ... + k!/x^k + ...)
   Assumes x >= PREC(y) * log(2).
   Returns the error bound in terms of ulp(y).
*/
static mp_exp_t
mpfr_eint_asympt (mpfr_ptr y, mpfr_srcptr x)
{
  mp_prec_t p = MPFR_PREC(y);
  mpfr_t invx, t, err;
  unsigned long k;
  mp_exp_t err_exp;

  mpfr_init2 (t, p);
  mpfr_init2 (invx, p);
  mpfr_init2 (err, 31); /* error in ulps on y */
  mpfr_ui_div (invx, 1, x, GMP_RNDN); /* invx = 1/x*(1+u) with |u|<=2^(1-p) */
  mpfr_set_ui (t, 1, GMP_RNDN); /* exact */
  mpfr_set (y, t, GMP_RNDN);
  mpfr_set_ui (err, 0, GMP_RNDN);
  for (k = 1; MPFR_GET_EXP(t) + (mp_exp_t) p > MPFR_GET_EXP(y); k++)
    {
      mpfr_mul (t, t, invx, GMP_RNDN); /* 2 more roundings */
      mpfr_mul_ui (t, t, k, GMP_RNDN); /* 1 more rounding: t = k!/x^k*(1+u)^e
                                          with u=2^{-p} and |e| <= 3*k */
      /* we use the fact that |(1+u)^n-1| <= 2*|n*u| for |n*u| <= 1, thus
         the error on t is less than 6*k*2^{-p}*t <= 6*k*ulp(t) */
      /* err is in terms of ulp(y): transform it in terms of ulp(t) */
      mpfr_mul_2si (err, err, MPFR_GET_EXP(y) - MPFR_GET_EXP(t), GMP_RNDU);
      mpfr_add_ui (err, err, 6 * k, GMP_RNDU);
      /* transform back in terms of ulp(y) */
      mpfr_div_2si (err, err, MPFR_GET_EXP(y) - MPFR_GET_EXP(t), GMP_RNDU);
      mpfr_add (y, y, t, GMP_RNDN);
    }
  /* add the truncation error bounded by ulp(y): 1 ulp */
  mpfr_mul (y, y, invx, GMP_RNDN); /* err <= 2*err + 3/2 */
  mpfr_exp (t, x, GMP_RNDN); /* err(t) <= 1/2*ulp(t) */
  mpfr_mul (y, y, t, GMP_RNDN); /* again: err <= 2*err + 3/2 */
  mpfr_mul_2ui (err, err, 2, GMP_RNDU);
  mpfr_add_ui (err, err, 8, GMP_RNDU);
  err_exp = MPFR_GET_EXP(err);
  mpfr_clear (t);
  mpfr_clear (invx);
  mpfr_clear (err);
  return err_exp;
}
コード例 #13
0
ファイル: tadd_ui.c プロジェクト: mmanley/Antares
static void
special (void)
{
  mpfr_t x, y;

  mpfr_init2 (x, 63);
  mpfr_init2 (y, 63);
  mpfr_set_str_binary (x, "0.110100000000000001110001110010111111000000000101100011100100011");
  mpfr_add_ui (y, x, 1, GMP_RNDD);
  mpfr_clear (x);
  mpfr_clear (y);
}
コード例 #14
0
ファイル: si_op.c プロジェクト: SESA/EbbRT-mpfr
int
mpfr_si_sub (mpfr_ptr y, long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  if (u >= 0)
    return mpfr_ui_sub (y, u, x, rnd_mode);
  else
    {
    int res = -mpfr_add_ui (y, x, -u, MPFR_INVERT_RND (rnd_mode));
    MPFR_CHANGE_SIGN (y);
    return res;
    }
}
コード例 #15
0
ファイル: zeta.c プロジェクト: MiKTeX/miktex
/* return add = 1 + floor(log(c^3*(13+m1))/log(2))
   where c = (1+eps)*(1+eps*max(8,m1)),
   m1 = 1 + max(1/eps,2*sd)*(1+eps),
   eps = 2^(-precz-14)
   sd = abs(s-1)
 */
static long
compute_add (mpfr_srcptr s, mpfr_prec_t precz)
{
  mpfr_t t, u, m1;
  long add;

  mpfr_inits2 (64, t, u, m1, (mpfr_ptr) 0);
  if (mpfr_cmp_ui (s, 1) >= 0)
    mpfr_sub_ui (t, s, 1, MPFR_RNDU);
  else
    mpfr_ui_sub (t, 1, s, MPFR_RNDU);
  /* now t = sd = abs(s-1), rounded up */
  mpfr_set_ui_2exp (u, 1, - precz - 14, MPFR_RNDU);
  /* u = eps */
  /* since 1/eps = 2^(precz+14), if EXP(sd) >= precz+14, then
     sd >= 1/2*2^(precz+14) thus 2*sd >= 2^(precz+14) >= 1/eps */
  if (mpfr_get_exp (t) >= precz + 14)
    mpfr_mul_2exp (t, t, 1, MPFR_RNDU);
  else
    mpfr_set_ui_2exp (t, 1, precz + 14, MPFR_RNDU);
  /* now t = max(1/eps,2*sd) */
  mpfr_add_ui (u, u, 1, MPFR_RNDU); /* u = 1+eps, rounded up */
  mpfr_mul (t, t, u, MPFR_RNDU); /* t = max(1/eps,2*sd)*(1+eps) */
  mpfr_add_ui (m1, t, 1, MPFR_RNDU);
  if (mpfr_get_exp (m1) <= 3)
    mpfr_set_ui (t, 8, MPFR_RNDU);
  else
    mpfr_set (t, m1, MPFR_RNDU);
  /* now t = max(8,m1) */
  mpfr_div_2exp (t, t, precz + 14, MPFR_RNDU); /* eps*max(8,m1) */
  mpfr_add_ui (t, t, 1, MPFR_RNDU); /* 1+eps*max(8,m1) */
  mpfr_mul (t, t, u, MPFR_RNDU); /* t = c */
  mpfr_add_ui (u, m1, 13, MPFR_RNDU); /* 13+m1 */
  mpfr_mul (u, u, t, MPFR_RNDU); /* c*(13+m1) */
  mpfr_sqr (t, t, MPFR_RNDU); /* c^2 */
  mpfr_mul (u, u, t, MPFR_RNDU); /* c^3*(13+m1) */
  add = mpfr_get_exp (u);
  mpfr_clears (t, u, m1, (mpfr_ptr) 0);
  return add;
}
コード例 #16
0
ファイル: c02.c プロジェクト: jpouderoux/core
int
main (int argc, char *argv[])
{
  unsigned long N = atoi (argv[1]), M;
  mp_prec_t p;
  mpfr_t i, j;
  char *lo;
  mp_exp_t exp_lo;
  int st, st0;

  fprintf (stderr, "Using GMP %s and MPFR %s\n", gmp_version, mpfr_version);
  st = cputime ();

  mpfr_init (i);
  mpfr_init (j);

  M = N;

  do
    {
      M += 10;
      mpfr_set_prec (i, 32);
      mpfr_set_d (i, LOG2_10, GMP_RNDU);
      mpfr_mul_ui (i, i, M, GMP_RNDU);
      mpfr_add_ui (i, i, 3, GMP_RNDU);
      p = mpfr_get_ui (i, GMP_RNDU);
      fprintf (stderr, "Setting precision to %lu\n", p);

      mpfr_set_prec (j, 2);
      mpfr_set_prec (i, p);
      mpfr_set_ui (j, 1, GMP_RNDN);
      mpfr_exp (i, j, GMP_RNDN); /* i = exp(1) */
      mpfr_set_prec (j, p);
      mpfr_const_pi (j, GMP_RNDN);
      mpfr_div (i, i, j, GMP_RNDN);
      mpfr_sqrt (i, i, GMP_RNDN);

      st0 = cputime ();
      lo = mpfr_get_str (NULL, &exp_lo, 10, M, i, GMP_RNDN);
      st0 = cputime () - st0;
    }
  while (can_round (lo, N, M) == 0);

  lo[N] = '\0';
  printf ("%s\n", lo);

  mpfr_clear (i);
  mpfr_clear (j);

  fprintf (stderr, "Cputime: %dms (output %dms)\n", cputime () - st, st0);
  return 0;
}
コード例 #17
0
ファイル: reuse.c プロジェクト: sudheesh001/SEC-LAB
static void
pow_int (mpfr_rnd_t rnd)
{
  mpfr_t ref1, ref2, ref3;
  mpfr_t res1;
  int i;

#ifdef DEBUG
  printf("pow_int\n");
#endif
  mpfr_inits2 ((randlimb () % 200) + MPFR_PREC_MIN,
               ref1, ref2, res1, (mpfr_ptr) 0);
  mpfr_init2 (ref3, 1005);

  for (i = 0; i <= 15; i++)
    {
      mpfr_urandomb (ref2, RANDS);
      if (i & 1)
        mpfr_neg (ref2, ref2, MPFR_RNDN);
      mpfr_set_ui (ref3, 20, MPFR_RNDN);
      /* We need to test huge integers because different algorithms/codes
         are used for not-too-large integers (mpfr_pow_z) and for general
         cases, in particular huge integers (mpfr_pow_general). [r7606] */
      if (i & 2)
        mpfr_mul_2ui (ref3, ref3, 1000, MPFR_RNDN);
      if (i & 4)
        mpfr_add_ui (ref3, ref3, 1, MPFR_RNDN);  /* odd integer */

      /* reference call: pow(a, b, c) */
      mpfr_pow (ref1, ref2, ref3, rnd);

      /* pow(a, a, c) */
      mpfr_set (res1, ref2, rnd); /* exact operation */
      mpfr_pow (res1, res1, ref3, rnd);

      if (mpfr_compare (res1, ref1))
        {
          printf ("Error for pow_int(a, a, c) for ");
          DISP("a=",ref2); DISP2(", c=",ref3);
          printf ("expected "); mpfr_print_binary (ref1); puts ("");
          printf ("got      "); mpfr_print_binary (res1); puts ("");
          exit (1);
        }
    }

  mpfr_clears (ref1, ref2, ref3, res1, (mpfr_ptr) 0);
}
コード例 #18
0
ファイル: pf_qdot.c プロジェクト: PlanetAPL/nars2000
APLVFP PrimFnMonQuoteDotVisV
    (APLVFP     aplVfpRht,
     LPPRIMSPEC lpPrimSpec)

{
    APLMPI mpzRes = {0};
    APLVFP mpfRes = {0};

    // Check for indeterminates:  !N for integer N < 0
    if (mpfr_integer_p (&aplVfpRht)
     && mpfr_cmp_ui (&aplVfpRht, 0) < 0)
        return *mpfr_QuadICValue (&aplVfpRht,       // No left arg
                                   ICNDX_QDOTn,
                                  &aplVfpRht,
                                  &mpfRes,
                                   FALSE);
    // Check for PosInfinity
    if (IsMpfPosInfinity (&aplVfpRht))
        return mpfPosInfinity;

    // If the arg is an integer,
    //   and it fits in a ULONG, ...
    if (mpfr_integer_p (&aplVfpRht)
     && mpfr_fits_uint_p (&aplVfpRht, MPFR_RNDN))
    {
        mpz_init   (&mpzRes);
        mpfr_init0 (&mpfRes);

        mpz_fac_ui (&mpzRes, mpfr_get_ui (&aplVfpRht, MPFR_RNDN));
        mpfr_set_z (&mpfRes, &mpzRes, MPFR_RNDN);

        Myz_clear (&mpzRes);
    } else
    {
        // Initialize the result
        mpfr_init_set (&mpfRes, &aplVfpRht, MPFR_RNDN);
        mpfr_add_ui   (&mpfRes, &mpfRes, 1, MPFR_RNDN);

        // Let MPFR handle it
        mpfr_gamma (&mpfRes, &mpfRes, MPFR_RNDN);
#ifdef DEBUG
        mpfr_free_cache ();
#endif
    } // End IF/ELSE

    return mpfRes;
} // End PrimFnMonQuoteDotVisV
コード例 #19
0
ファイル: tadd_ui.c プロジェクト: mmanley/Antares
/* checks that x+y gives the right results with 53 bits of precision */
static void
check3 (const char *xs, unsigned long y, mp_rnd_t rnd_mode, const char *zs)
{
  mpfr_t xx, zz;

  mpfr_inits2 (53, xx, zz, (void *) 0);
  mpfr_set_str1 (xx, xs);
  mpfr_add_ui (zz, xx, y, rnd_mode);
  if (mpfr_cmp_str1(zz, zs) )
    {
      printf ("expected sum is %s, got ",zs);
      mpfr_out_str(stdout, 10, 0, zz, GMP_RNDN);
      printf ("\nmpfr_add_ui failed for x=%s y=%lu with rnd_mode=%s\n",
              xs, y, mpfr_print_rnd_mode(rnd_mode));
      exit (1);
  }
  mpfr_clears (xx, zz, (void *) 0);
}
コード例 #20
0
ファイル: Hadamard_Cramer.c プロジェクト: krisk0/razin
slong
hadamard_2arg(mpfr_t b,const fmpz_mat_t m)
/*
upper bound on log2( 2*abs(m det) )
returns -1 if zero row found, smallest row index otherwise

b on entry is uninitialized
b on exit is initialized iff no zero row found
*/
 {
  const slong n=m->r;
  slong smallest=0,j;
  // gcc warning: initialization from incompatible pointer type --- don't know
  //  how to fix
  const fmpz** const rows=m->rows;
  mpfr_t v,u;
  if(log2_L2_fmpz_3arg( v, rows[0], n ))
   return -1;
  mpfr_copy_bound(b, v);
  // v and b must be freed
  for(j=1;j<n;j++)
   {
    if(log2_L2_fmpz_3arg( u, rows[j], n ))
     {
      mpfr_clear(b); mpfr_clear(v);
      return -1;
     }
    mpfr_add_bound(b, u);
    if( mpfr_cmp(u, v)<0 )
     {
      smallest=j;
      mpfr_swap(v, u);
     }
    mpfr_clear(u);
    // v and b must be freed
   }
  mpfr_clear(v);
  mpfr_div_ui( b, b, 2, MPFR_RNDU ); // instead of taking root
  mpfr_add_ui( b, b, 1, MPFR_RNDU ); // instead of multiplying by 2
  return smallest;
 }
コード例 #21
0
ファイル: taylor_exp_log.c プロジェクト: Ybrad/Year-4-Project
void mpfr_naive_exp(mpfr_t R, mpfr_t x, mpz_t n)
{
	assert(mpz_cmp_ui(n, 0) >= 0);
	
	mpfr_t z;
	
	mpfr_init_set(z, x, MPFR_RNDN);
	mpfr_div_z(z, z, n, MPFR_RNDN);
	mpfr_add_ui(z, z, 1, MPFR_RNDN);
	
	if(mpfr_cmp_ui(z, 0) > 0)
		mpfr_squaring_int_exp(R, z, n);
	else
	{
		mpfr_neg(z, z, MPFR_RNDN);
		mpfr_squaring_int_exp(R, z, n);
		
		if(mpz_odd_p(n))
			mpfr_neg(R, R, MPFR_RNDN);
	}
}
コード例 #22
0
ファイル: tset_sj.c プロジェクト: 119/aircam-openwrt
static void
check_set_uj_2exp (void)
{
  mpfr_t x;
  int inex;

  mpfr_init2 (x, sizeof(uintmax_t)*CHAR_BIT);

  inex = mpfr_set_uj_2exp (x, 1, 0, MPFR_RNDN);
  if (inex || mpfr_cmp_ui(x, 1))
    ERROR("(1U,0)");

  inex = mpfr_set_uj_2exp (x, 1024, -10, MPFR_RNDN);
  if (inex || mpfr_cmp_ui(x, 1))
    ERROR("(1024U,-10)");

  inex = mpfr_set_uj_2exp (x, 1024, 10, MPFR_RNDN);
  if (inex || mpfr_cmp_ui(x, 1024L * 1024L))
    ERROR("(1024U,+10)");

  inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, 1000, MPFR_RNDN);
  inex |= mpfr_div_2ui (x, x, 1000, MPFR_RNDN);
  inex |= mpfr_add_ui (x, x, 1, MPFR_RNDN);
  if (inex || !mpfr_powerof2_raw (x)
      || MPFR_EXP (x) != (sizeof(uintmax_t)*CHAR_BIT+1) )
    ERROR("(UINTMAX_MAX)");

  inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, MPFR_EMAX_MAX-10, MPFR_RNDN);
  if (inex == 0 || !mpfr_inf_p (x))
    ERROR ("Overflow");

  inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, MPFR_EMIN_MIN-1000, MPFR_RNDN);
  if (inex == 0 || !MPFR_IS_ZERO (x))
    ERROR ("Underflow");

  mpfr_clear (x);
}
コード例 #23
0
ファイル: tsub_ui.c プロジェクト: SESA/EbbRT-mpfr
/* FastTwoSum: if EXP(x) >= EXP(y), u = o(x+y), v = o(u-x), w = o(y-v),
               then x + y = u + w
thus if u = o(y-x), v = o(u+x), w = o(v-y), then y-x = u-w */
static void
check_two_sum (mpfr_prec_t p)
{
  unsigned int x;
  mpfr_t y, u, v, w;
  mpfr_rnd_t rnd;
  int inexact;

  mpfr_inits2 (p, y, u, v, w, (mpfr_ptr) 0);
  do
    {
      x = randlimb ();
    }
  while (x < 1);
  mpfr_urandomb (y, RANDS);
  rnd = MPFR_RNDN;
  inexact = mpfr_sub_ui (u, y, x, rnd);
  mpfr_add_ui (v, u, x, rnd);
  mpfr_sub (w, v, y, rnd);
  /* as u - (y-x) = w, we should have inexact and w of same sign */
  if (((inexact == 0) && mpfr_cmp_ui (w, 0)) ||
      ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) ||
      ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0)))
    {
      printf ("Wrong inexact flag for prec=%u, rnd=%s\n",
              (unsigned int) p, mpfr_print_rnd_mode (rnd));
      printf ("x=%u\n", x);
      printf ("y="); mpfr_print_binary(y); puts ("");
      printf ("u="); mpfr_print_binary(u); puts ("");
      printf ("v="); mpfr_print_binary(v); puts ("");
      printf ("w="); mpfr_print_binary(w); puts ("");
      printf ("inexact = %d\n", inexact);
      exit (1);
    }
  mpfr_clears (y, u, v, w, (mpfr_ptr) 0);
}
コード例 #24
0
ファイル: gamma.c プロジェクト: Canar/mpfr
/* We use the reflection formula
  Gamma(1+t) Gamma(1-t) = - Pi t / sin(Pi (1 + t))
  in order to treat the case x <= 1,
  i.e. with x = 1-t, then Gamma(x) = -Pi*(1-x)/sin(Pi*(2-x))/GAMMA(2-x)
*/
int
mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  mpfr_t xp, GammaTrial, tmp, tmp2;
  mpz_t fact;
  mpfr_prec_t realprec;
  int compared, is_integer;
  int inex = 0;  /* 0 means: result gamma not set yet */
  MPFR_GROUP_DECL (group);
  MPFR_SAVE_EXPO_DECL (expo);
  MPFR_ZIV_DECL (loop);

  MPFR_LOG_FUNC
    (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
     ("gamma[%Pu]=%.*Rg inexact=%d",
      mpfr_get_prec (gamma), mpfr_log_prec, gamma, inex));

  /* Trivial cases */
  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
    {
      if (MPFR_IS_NAN (x))
        {
          MPFR_SET_NAN (gamma);
          MPFR_RET_NAN;
        }
      else if (MPFR_IS_INF (x))
        {
          if (MPFR_IS_NEG (x))
            {
              MPFR_SET_NAN (gamma);
              MPFR_RET_NAN;
            }
          else
            {
              MPFR_SET_INF (gamma);
              MPFR_SET_POS (gamma);
              MPFR_RET (0);  /* exact */
            }
        }
      else /* x is zero */
        {
          MPFR_ASSERTD(MPFR_IS_ZERO(x));
          MPFR_SET_INF(gamma);
          MPFR_SET_SAME_SIGN(gamma, x);
          MPFR_SET_DIVBY0 ();
          MPFR_RET (0);  /* exact */
        }
    }

  /* Check for tiny arguments, where gamma(x) ~ 1/x - euler + ....
     We know from "Bound on Runs of Zeros and Ones for Algebraic Functions",
     Proceedings of Arith15, T. Lang and J.-M. Muller, 2001, that the maximal
     number of consecutive zeroes or ones after the round bit is n-1 for an
     input of n bits. But we need a more precise lower bound. Assume x has
     n bits, and 1/x is near a floating-point number y of n+1 bits. We can
     write x = X*2^e, y = Y/2^f with X, Y integers of n and n+1 bits.
     Thus X*Y^2^(e-f) is near from 1, i.e., X*Y is near from 2^(f-e).
     Two cases can happen:
     (i) either X*Y is exactly 2^(f-e), but this can happen only if X and Y
         are themselves powers of two, i.e., x is a power of two;
     (ii) or X*Y is at distance at least one from 2^(f-e), thus
          |xy-1| >= 2^(e-f), or |y-1/x| >= 2^(e-f)/x = 2^(-f)/X >= 2^(-f-n).
          Since ufp(y) = 2^(n-f) [ufp = unit in first place], this means
          that the distance |y-1/x| >= 2^(-2n) ufp(y).
          Now assuming |gamma(x)-1/x| <= 1, which is true for x <= 1,
          if 2^(-2n) ufp(y) >= 2, the error is at most 2^(-2n-1) ufp(y),
          and round(1/x) with precision >= 2n+2 gives the correct result.
          If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
          A sufficient condition is thus EXP(x) + 2 <= -2 MAX(PREC(x),PREC(Y)).
  */
  if (MPFR_GET_EXP (x) + 2
      <= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(gamma)))
    {
      int sign = MPFR_SIGN (x); /* retrieve sign before possible override */
      int special;
      MPFR_BLOCK_DECL (flags);

      MPFR_SAVE_EXPO_MARK (expo);

      /* for overflow cases, see below; this needs to be done
         before x possibly gets overridden. */
      special =
        MPFR_GET_EXP (x) == 1 - MPFR_EMAX_MAX &&
        MPFR_IS_POS_SIGN (sign) &&
        MPFR_IS_LIKE_RNDD (rnd_mode, sign) &&
        mpfr_powerof2_raw (x);

      MPFR_BLOCK (flags, inex = mpfr_ui_div (gamma, 1, x, rnd_mode));
      if (inex == 0) /* x is a power of two */
        {
          /* return RND(1/x - euler) = RND(+/- 2^k - eps) with eps > 0 */
          if (rnd_mode == MPFR_RNDN || MPFR_IS_LIKE_RNDU (rnd_mode, sign))
            inex = 1;
          else
            {
              mpfr_nextbelow (gamma);
              inex = -1;
            }
        }
      else if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags)))
        {
          /* Overflow in the division 1/x. This is a real overflow, except
             in RNDZ or RNDD when 1/x = 2^emax, i.e. x = 2^(-emax): due to
             the "- euler", the rounded value in unbounded exponent range
             is 0.111...11 * 2^emax (not an overflow). */
          if (!special)
            MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, flags);
        }
      MPFR_SAVE_EXPO_FREE (expo);
      /* Note: an overflow is possible with an infinite result;
         in this case, the overflow flag will automatically be
         restored by mpfr_check_range. */
      return mpfr_check_range (gamma, inex, rnd_mode);
    }

  is_integer = mpfr_integer_p (x);
  /* gamma(x) for x a negative integer gives NaN */
  if (is_integer && MPFR_IS_NEG(x))
    {
      MPFR_SET_NAN (gamma);
      MPFR_RET_NAN;
    }

  compared = mpfr_cmp_ui (x, 1);
  if (compared == 0)
    return mpfr_set_ui (gamma, 1, rnd_mode);

  /* if x is an integer that fits into an unsigned long, use mpfr_fac_ui
     if argument is not too large.
     If precision is p, fac_ui costs O(u*p), whereas gamma costs O(p*M(p)),
     so for u <= M(p), fac_ui should be faster.
     We approximate here M(p) by p*log(p)^2, which is not a bad guess.
     Warning: since the generic code does not handle exact cases,
     we want all cases where gamma(x) is exact to be treated here.
  */
  if (is_integer && mpfr_fits_ulong_p (x, MPFR_RNDN))
    {
      unsigned long int u;
      mpfr_prec_t p = MPFR_PREC(gamma);
      u = mpfr_get_ui (x, MPFR_RNDN);
      if (u < 44787929UL && bits_fac (u - 1) <= p + (rnd_mode == MPFR_RNDN))
        /* bits_fac: lower bound on the number of bits of m,
           where gamma(x) = (u-1)! = m*2^e with m odd. */
        return mpfr_fac_ui (gamma, u - 1, rnd_mode);
      /* if bits_fac(...) > p (resp. p+1 for rounding to nearest),
         then gamma(x) cannot be exact in precision p (resp. p+1).
         FIXME: remove the test u < 44787929UL after changing bits_fac
         to return a mpz_t or mpfr_t. */
    }

  MPFR_SAVE_EXPO_MARK (expo);

  /* check for overflow: according to (6.1.37) in Abramowitz & Stegun,
     gamma(x) >= exp(-x) * x^(x-1/2) * sqrt(2*Pi)
              >= 2 * (x/e)^x / x for x >= 1 */
  if (compared > 0)
    {
      mpfr_t yp;
      mpfr_exp_t expxp;
      MPFR_BLOCK_DECL (flags);

      /* quick test for the default exponent range */
      if (mpfr_get_emax () >= 1073741823UL && MPFR_GET_EXP(x) <= 25)
        {
          MPFR_SAVE_EXPO_FREE (expo);
          return mpfr_gamma_aux (gamma, x, rnd_mode);
        }

      /* 1/e rounded down to 53 bits */
#define EXPM1_STR "0.010111100010110101011000110110001011001110111100111"
      mpfr_init2 (xp, 53);
      mpfr_init2 (yp, 53);
      mpfr_set_str_binary (xp, EXPM1_STR);
      mpfr_mul (xp, x, xp, MPFR_RNDZ);
      mpfr_sub_ui (yp, x, 2, MPFR_RNDZ);
      mpfr_pow (xp, xp, yp, MPFR_RNDZ); /* (x/e)^(x-2) */
      mpfr_set_str_binary (yp, EXPM1_STR);
      mpfr_mul (xp, xp, yp, MPFR_RNDZ); /* x^(x-2) / e^(x-1) */
      mpfr_mul (xp, xp, yp, MPFR_RNDZ); /* x^(x-2) / e^x */
      mpfr_mul (xp, xp, x, MPFR_RNDZ); /* lower bound on x^(x-1) / e^x */
      MPFR_BLOCK (flags, mpfr_mul_2ui (xp, xp, 1, MPFR_RNDZ));
      expxp = MPFR_GET_EXP (xp);
      mpfr_clear (xp);
      mpfr_clear (yp);
      MPFR_SAVE_EXPO_FREE (expo);
      return MPFR_OVERFLOW (flags) || expxp > __gmpfr_emax ?
        mpfr_overflow (gamma, rnd_mode, 1) :
        mpfr_gamma_aux (gamma, x, rnd_mode);
    }

  /* now compared < 0 */

  /* check for underflow: for x < 1,
     gamma(x) = Pi*(x-1)/sin(Pi*(2-x))/gamma(2-x).
     Since gamma(2-x) >= 2 * ((2-x)/e)^(2-x) / (2-x), we have
     |gamma(x)| <= Pi*(1-x)*(2-x)/2/((2-x)/e)^(2-x) / |sin(Pi*(2-x))|
                <= 12 * ((2-x)/e)^x / |sin(Pi*(2-x))|.
     To avoid an underflow in ((2-x)/e)^x, we compute the logarithm.
  */
  if (MPFR_IS_NEG(x))
    {
      int underflow = 0, sgn, ck;
      mpfr_prec_t w;

      mpfr_init2 (xp, 53);
      mpfr_init2 (tmp, 53);
      mpfr_init2 (tmp2, 53);
      /* we want an upper bound for x * [log(2-x)-1].
         since x < 0, we need a lower bound on log(2-x) */
      mpfr_ui_sub (xp, 2, x, MPFR_RNDD);
      mpfr_log (xp, xp, MPFR_RNDD);
      mpfr_sub_ui (xp, xp, 1, MPFR_RNDD);
      mpfr_mul (xp, xp, x, MPFR_RNDU);

      /* we need an upper bound on 1/|sin(Pi*(2-x))|,
         thus a lower bound on |sin(Pi*(2-x))|.
         If 2-x is exact, then the error of Pi*(2-x) is (1+u)^2 with u = 2^(-p)
         thus the error on sin(Pi*(2-x)) is less than 1/2ulp + 3Pi(2-x)u,
         assuming u <= 1, thus <= u + 3Pi(2-x)u */

      w = mpfr_gamma_2_minus_x_exact (x); /* 2-x is exact for prec >= w */
      w += 17; /* to get tmp2 small enough */
      mpfr_set_prec (tmp, w);
      mpfr_set_prec (tmp2, w);
      MPFR_DBGRES (ck = mpfr_ui_sub (tmp, 2, x, MPFR_RNDN));
      MPFR_ASSERTD (ck == 0); /* tmp = 2-x exactly */
      mpfr_const_pi (tmp2, MPFR_RNDN);
      mpfr_mul (tmp2, tmp2, tmp, MPFR_RNDN); /* Pi*(2-x) */
      mpfr_sin (tmp, tmp2, MPFR_RNDN); /* sin(Pi*(2-x)) */
      sgn = mpfr_sgn (tmp);
      mpfr_abs (tmp, tmp, MPFR_RNDN);
      mpfr_mul_ui (tmp2, tmp2, 3, MPFR_RNDU); /* 3Pi(2-x) */
      mpfr_add_ui (tmp2, tmp2, 1, MPFR_RNDU); /* 3Pi(2-x)+1 */
      mpfr_div_2ui (tmp2, tmp2, mpfr_get_prec (tmp), MPFR_RNDU);
      /* if tmp2<|tmp|, we get a lower bound */
      if (mpfr_cmp (tmp2, tmp) < 0)
        {
          mpfr_sub (tmp, tmp, tmp2, MPFR_RNDZ); /* low bnd on |sin(Pi*(2-x))| */
          mpfr_ui_div (tmp, 12, tmp, MPFR_RNDU); /* upper bound */
          mpfr_log2 (tmp, tmp, MPFR_RNDU);
          mpfr_add (xp, tmp, xp, MPFR_RNDU);
          /* The assert below checks that expo.saved_emin - 2 always
             fits in a long. FIXME if we want to allow mpfr_exp_t to
             be a long long, for instance. */
          MPFR_ASSERTN (MPFR_EMIN_MIN - 2 >= LONG_MIN);
          underflow = mpfr_cmp_si (xp, expo.saved_emin - 2) <= 0;
        }

      mpfr_clear (xp);
      mpfr_clear (tmp);
      mpfr_clear (tmp2);
      if (underflow) /* the sign is the opposite of that of sin(Pi*(2-x)) */
        {
          MPFR_SAVE_EXPO_FREE (expo);
          return mpfr_underflow (gamma, (rnd_mode == MPFR_RNDN) ? MPFR_RNDZ : rnd_mode, -sgn);
        }
    }

  realprec = MPFR_PREC (gamma);
  /* we want both 1-x and 2-x to be exact */
  {
    mpfr_prec_t w;
    w = mpfr_gamma_1_minus_x_exact (x);
    if (realprec < w)
      realprec = w;
    w = mpfr_gamma_2_minus_x_exact (x);
    if (realprec < w)
      realprec = w;
  }
  realprec = realprec + MPFR_INT_CEIL_LOG2 (realprec) + 20;
  MPFR_ASSERTD(realprec >= 5);

  MPFR_GROUP_INIT_4 (group, realprec + MPFR_INT_CEIL_LOG2 (realprec) + 20,
                     xp, tmp, tmp2, GammaTrial);
  mpz_init (fact);
  MPFR_ZIV_INIT (loop, realprec);
  for (;;)
    {
      mpfr_exp_t err_g;
      int ck;
      MPFR_GROUP_REPREC_4 (group, realprec, xp, tmp, tmp2, GammaTrial);

      /* reflection formula: gamma(x) = Pi*(x-1)/sin(Pi*(2-x))/gamma(2-x) */

      ck = mpfr_ui_sub (xp, 2, x, MPFR_RNDN); /* 2-x, exact */
      MPFR_ASSERTD(ck == 0);  (void) ck; /* use ck to avoid a warning */
      mpfr_gamma (tmp, xp, MPFR_RNDN);   /* gamma(2-x), error (1+u) */
      mpfr_const_pi (tmp2, MPFR_RNDN);   /* Pi, error (1+u) */
      mpfr_mul (GammaTrial, tmp2, xp, MPFR_RNDN); /* Pi*(2-x), error (1+u)^2 */
      err_g = MPFR_GET_EXP(GammaTrial);
      mpfr_sin (GammaTrial, GammaTrial, MPFR_RNDN); /* sin(Pi*(2-x)) */
      /* If tmp is +Inf, we compute exp(lngamma(x)). */
      if (mpfr_inf_p (tmp))
        {
          inex = mpfr_explgamma (gamma, x, &expo, tmp, tmp2, rnd_mode);
          if (inex)
            goto end;
          else
            goto ziv_next;
        }
      err_g = err_g + 1 - MPFR_GET_EXP(GammaTrial);
      /* let g0 the true value of Pi*(2-x), g the computed value.
         We have g = g0 + h with |h| <= |(1+u^2)-1|*g.
         Thus sin(g) = sin(g0) + h' with |h'| <= |(1+u^2)-1|*g.
         The relative error is thus bounded by |(1+u^2)-1|*g/sin(g)
         <= |(1+u^2)-1|*2^err_g. <= 2.25*u*2^err_g for |u|<=1/4.
         With the rounding error, this gives (0.5 + 2.25*2^err_g)*u. */
      ck = mpfr_sub_ui (xp, x, 1, MPFR_RNDN); /* x-1, exact */
      MPFR_ASSERTD(ck == 0);  (void) ck; /* use ck to avoid a warning */
      mpfr_mul (xp, tmp2, xp, MPFR_RNDN); /* Pi*(x-1), error (1+u)^2 */
      mpfr_mul (GammaTrial, GammaTrial, tmp, MPFR_RNDN);
      /* [1 + (0.5 + 2.25*2^err_g)*u]*(1+u)^2 = 1 + (2.5 + 2.25*2^err_g)*u
         + (0.5 + 2.25*2^err_g)*u*(2u+u^2) + u^2.
         For err_g <= realprec-2, we have (0.5 + 2.25*2^err_g)*u <=
         0.5*u + 2.25/4 <= 0.6875 and u^2 <= u/4, thus
         (0.5 + 2.25*2^err_g)*u*(2u+u^2) + u^2 <= 0.6875*(2u+u/4) + u/4
         <= 1.8*u, thus the rel. error is bounded by (4.5 + 2.25*2^err_g)*u. */
      mpfr_div (GammaTrial, xp, GammaTrial, MPFR_RNDN);
      /* the error is of the form (1+u)^3/[1 + (4.5 + 2.25*2^err_g)*u].
         For realprec >= 5 and err_g <= realprec-2, [(4.5 + 2.25*2^err_g)*u]^2
         <= 0.71, and for |y|<=0.71, 1/(1-y) can be written 1+a*y with a<=4.
         (1+u)^3 * (1+4*(4.5 + 2.25*2^err_g)*u)
         = 1 + (21 + 9*2^err_g)*u + (57+27*2^err_g)*u^2 + (55+27*2^err_g)*u^3
             + (18+9*2^err_g)*u^4
         <= 1 + (21 + 9*2^err_g)*u + (57+27*2^err_g)*u^2 + (56+28*2^err_g)*u^3
         <= 1 + (21 + 9*2^err_g)*u + (59+28*2^err_g)*u^2
         <= 1 + (23 + 10*2^err_g)*u.
         The final error is thus bounded by (23 + 10*2^err_g) ulps,
         which is <= 2^6 for err_g<=2, and <= 2^(err_g+4) for err_g >= 2. */
      err_g = (err_g <= 2) ? 6 : err_g + 4;

      if (MPFR_LIKELY (MPFR_CAN_ROUND (GammaTrial, realprec - err_g,
                                       MPFR_PREC(gamma), rnd_mode)))
        break;

    ziv_next:
      MPFR_ZIV_NEXT (loop, realprec);
    }

 end:
  MPFR_ZIV_FREE (loop);

  if (inex == 0)
    inex = mpfr_set (gamma, GammaTrial, rnd_mode);
  MPFR_GROUP_CLEAR (group);
  mpz_clear (fact);

  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (gamma, inex, rnd_mode);
}
コード例 #25
0
ファイル: tset_si.c プロジェクト: michalkonecny/haskell-mpfr
int
main (int argc, char *argv[])
{
  mpfr_t x;
  long k, z, d, N;
  unsigned long zl, dl;
  int inex;
  int r;
  mpfr_exp_t emin, emax;
  int flag;

  tests_start_mpfr ();

  mpfr_init2 (x, 100);

  N = (argc==1) ? 100000 : atol (argv[1]);

  for (k = 1; k <= N; k++)
    {
      z = (long) (randlimb () & LONG_MAX) + LONG_MIN / 2;
      inex = mpfr_set_si (x, z, MPFR_RNDZ);
      d = mpfr_get_si (x, MPFR_RNDZ);
      if (d != z)
        {
          printf ("Error in mpfr_set_si: expected %ld got %ld\n", z, d);
          exit (1);
        }
      if (inex)
        {
          printf ("Error in mpfr_set_si: inex value incorrect for %ld: %d\n",
                  z, inex);
          exit (1);
        }
    }

  for (k = 1; k <= N; k++)
    {
      zl = randlimb ();
      inex = mpfr_set_ui (x, zl, MPFR_RNDZ);
      dl = mpfr_get_ui (x, MPFR_RNDZ);
      if (dl != zl)
        {
          printf ("Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl);
          exit (1);
        }
      if (inex)
        {
          printf ("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, MPFR_RNDZ) >= 0)
    {
      printf ("Wrong inexact flag for x=5, rnd=MPFR_RNDZ\n");
      exit (1);
    }

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

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

  mpfr_set_prec (x, 2);
  inex = mpfr_set_si (x, 33096, MPFR_RNDU);
  if (mpfr_get_si (x, MPFR_RNDZ) != 49152 || inex <= 0)
    {
      printf ("Error in mpfr_set_si, exp. 49152, got %ld, inex %d\n",
              mpfr_get_si (x, MPFR_RNDZ), inex);
      exit (1);
    }
  inex = mpfr_set_ui (x, 33096, MPFR_RNDU);
  if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
    {
      printf ("Error in mpfr_set_ui, exp. 49152, got %ld, inex %d\n",
              mpfr_get_si (x, MPFR_RNDZ), inex);
      exit (1);
    }
  /* Also test the mpfr_set_ui function (instead of macro). */
  inex = (mpfr_set_ui) (x, 33096, MPFR_RNDU);
  if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
    {
      printf ("Error in mpfr_set_ui function, exp. 49152, got %ld, inex %d\n",
              mpfr_get_si (x, MPFR_RNDZ), inex);
      exit (1);
    }

  for (r = 0 ; r < MPFR_RND_MAX ; r++)
    {
      mpfr_set_si (x, -1, (mpfr_rnd_t) r);
      mpfr_set_ui (x, 0, (mpfr_rnd_t) r);
      if (MPFR_IS_NEG (x) || mpfr_get_ui (x, (mpfr_rnd_t) r) != 0)
        {
          printf ("mpfr_set_ui (x, 0) gives -0 for %s\n",
                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
          exit (1);
        }

      mpfr_set_si (x, -1, (mpfr_rnd_t) r);
      mpfr_set_si (x, 0, (mpfr_rnd_t) r);
      if (MPFR_IS_NEG (x) || mpfr_get_si (x, (mpfr_rnd_t) r) != 0)
        {
          printf ("mpfr_set_si (x, 0) gives -0 for %s\n",
                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
          exit (1);
        }
    }

  /* check potential bug in case mp_limb_t is unsigned */
  emax = mpfr_get_emax ();
  set_emax (0);
  mpfr_set_si (x, -1, MPFR_RNDN);
  if (mpfr_sgn (x) >= 0)
    {
      printf ("mpfr_set_si (x, -1) fails\n");
      exit (1);
    }
  set_emax (emax);

  emax = mpfr_get_emax ();
  set_emax (5);
  mpfr_set_prec (x, 2);
  mpfr_set_si (x, -31, MPFR_RNDN);
  if (mpfr_sgn (x) >= 0)
    {
      printf ("mpfr_set_si (x, -31) fails\n");
      exit (1);
    }
  set_emax (emax);

  /* test for get_ui */
  mpfr_set_ui (x, 0, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_get_ui (x, MPFR_RNDN) == 0);
  mpfr_set_ui (x, ULONG_MAX, MPFR_RNDU);
  mpfr_nextabove (x);
  mpfr_get_ui (x, MPFR_RNDU);

  /* another test for get_ui */
  mpfr_set_prec (x, 10);
  mpfr_set_str_binary (x, "10.101");
  dl = mpfr_get_ui (x, MPFR_RNDN);
  MPFR_ASSERTN (dl == 3);

  mpfr_set_str_binary (x, "-1.0");
  mpfr_get_ui (x, MPFR_RNDN);

  mpfr_set_str_binary (x, "0.1");
  dl = mpfr_get_ui (x, MPFR_RNDN);
  MPFR_ASSERTN (dl == 0);
  dl = mpfr_get_ui (x, MPFR_RNDZ);
  MPFR_ASSERTN (dl == 0);
  dl = mpfr_get_ui (x, MPFR_RNDD);
  MPFR_ASSERTN (dl == 0);
  dl = mpfr_get_ui (x, MPFR_RNDU);
  MPFR_ASSERTN (dl == 1);

  /* coverage tests */
  mpfr_set_prec (x, 2);
  mpfr_set_si (x, -7, MPFR_RNDD);
  MPFR_ASSERTN(mpfr_cmp_si (x, -8) == 0);
  mpfr_set_prec (x, 2);
  mpfr_set_ui (x, 7, MPFR_RNDU);
  MPFR_ASSERTN(mpfr_cmp_ui (x, 8) == 0);
  emax = mpfr_get_emax ();
  set_emax (3);
  mpfr_set_ui (x, 7, MPFR_RNDU);
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
  set_emax (1);
  MPFR_ASSERTN( mpfr_set_ui (x, 7, MPFR_RNDU) );
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
  set_emax (emax);
  mpfr_set_ui_2exp (x, 17, -50, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_get_ui (x, MPFR_RNDD) == 0);
  MPFR_ASSERTN (mpfr_get_si (x, MPFR_RNDD) == 0);

  /* Test for ERANGE flag + correct behaviour if overflow */
  mpfr_set_prec (x, 256);
  mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  dl = mpfr_get_ui (x, MPFR_RNDN);
  if (dl != ULONG_MAX || mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_ui + ERANGE + ULONG_MAX (1)\n");
      exit (1);
    }
  mpfr_add_ui (x, x, 1, MPFR_RNDN);
  dl = mpfr_get_ui (x, MPFR_RNDN);
  if (dl != ULONG_MAX || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_ui + ERANGE + ULONG_MAX (2)\n");
      exit (1);
    }
  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  dl = mpfr_get_ui (x, MPFR_RNDN);
  if (dl != 0 || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_ui + ERANGE + -1 \n");
      exit (1);
    }
  mpfr_set_si (x, LONG_MAX, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != LONG_MAX || mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + ERANGE + LONG_MAX (1): %ld\n", d);
      exit (1);
    }
  mpfr_add_ui (x, x, 1, MPFR_RNDN);
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != LONG_MAX || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + ERANGE + LONG_MAX (2)\n");
      exit (1);
    }
  mpfr_set_si (x, LONG_MIN, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != LONG_MIN || mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + ERANGE + LONG_MIN (1)\n");
      exit (1);
    }
  mpfr_sub_ui (x, x, 1, MPFR_RNDN);
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != LONG_MIN || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + ERANGE + LONG_MIN (2)\n");
      exit (1);
    }

  mpfr_set_nan (x);
  mpfr_clear_erangeflag ();
  d = mpfr_get_ui (x, MPFR_RNDN);
  if (d != 0 || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_ui + NaN\n");
      exit (1);
    }
  mpfr_clear_erangeflag ();
  d = mpfr_get_si (x, MPFR_RNDN);
  if (d != 0 || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_si + NaN\n");
      exit (1);
    }

  emin = mpfr_get_emin ();
  mpfr_set_prec (x, 2);

  mpfr_set_emin (4);
  mpfr_clear_flags ();
  mpfr_set_ui (x, 7, MPFR_RNDU);
  flag = mpfr_underflow_p ();
  mpfr_set_emin (emin);
  if (mpfr_cmp_ui (x, 8) != 0)
    {
      printf ("Error for mpfr_set_ui (x, 7, MPFR_RNDU), prec = 2, emin = 4\n");
      exit (1);
    }
  if (flag)
    {
      printf ("mpfr_set_ui (x, 7, MPFR_RNDU) should not underflow "
              "with prec = 2, emin = 4\n");
      exit (1);
    }

  mpfr_set_emin (4);
  mpfr_clear_flags ();
  mpfr_set_si (x, -7, MPFR_RNDD);
  flag = mpfr_underflow_p ();
  mpfr_set_emin (emin);
  if (mpfr_cmp_si (x, -8) != 0)
    {
      printf ("Error for mpfr_set_si (x, -7, MPFR_RNDD), prec = 2, emin = 4\n");
      exit (1);
    }
  if (flag)
    {
      printf ("mpfr_set_si (x, -7, MPFR_RNDD) should not underflow "
              "with prec = 2, emin = 4\n");
      exit (1);
    }

  mpfr_clear (x);

  test_2exp ();
  test_macros ();
  test_macros_keyword ();
  tests_end_mpfr ();
  return 0;
}
コード例 #26
0
ファイル: atanh.c プロジェクト: SESA/EbbRT-mpfr
int
mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
{
  int inexact;
  mpfr_t x, t, te;
  mpfr_prec_t Nx, Ny, Nt;
  mpfr_exp_t err;
  MPFR_ZIV_DECL (loop);
  MPFR_SAVE_EXPO_DECL (expo);

  MPFR_LOG_FUNC
    (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (xt), mpfr_log_prec, xt, rnd_mode),
    ("y[%Pu]=%.*Rg inexact=%d",
     mpfr_get_prec (y), mpfr_log_prec, y, inexact));

  /* Special cases */
  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (xt)))
    {
      /* atanh(NaN) = NaN, and atanh(+/-Inf) = NaN since tanh gives a result
         between -1 and 1 */
      if (MPFR_IS_NAN (xt) || MPFR_IS_INF (xt))
        {
          MPFR_SET_NAN (y);
          MPFR_RET_NAN;
        }
      else /* necessarily xt is 0 */
        {
          MPFR_ASSERTD (MPFR_IS_ZERO (xt));
          MPFR_SET_ZERO (y);   /* atanh(0) = 0 */
          MPFR_SET_SAME_SIGN (y,xt);
          MPFR_RET (0);
        }
    }

  /* atanh (x) = NaN as soon as |x| > 1, and arctanh(+/-1) = +/-Inf */
  if (MPFR_UNLIKELY (MPFR_GET_EXP (xt) > 0))
    {
      if (MPFR_GET_EXP (xt) == 1 && mpfr_powerof2_raw (xt))
        {
          MPFR_SET_INF (y);
          MPFR_SET_SAME_SIGN (y, xt);
          mpfr_set_divby0 ();
          MPFR_RET (0);
        }
      MPFR_SET_NAN (y);
      MPFR_RET_NAN;
    }

  /* atanh(x) = x + x^3/3 + ... so the error is < 2^(3*EXP(x)-1) */
  MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, xt, -2 * MPFR_GET_EXP (xt), 1, 1,
                                    rnd_mode, {});

  MPFR_SAVE_EXPO_MARK (expo);

  /* Compute initial precision */
  Nx = MPFR_PREC (xt);
  MPFR_TMP_INIT_ABS (x, xt);
  Ny = MPFR_PREC (y);
  Nt = MAX (Nx, Ny);
  /* the optimal number of bits : see algorithms.ps */
  Nt = Nt + MPFR_INT_CEIL_LOG2 (Nt) + 4;

  /* initialise of intermediary variable */
  mpfr_init2 (t, Nt);
  mpfr_init2 (te, Nt);

  /* First computation of cosh */
  MPFR_ZIV_INIT (loop, Nt);
  for (;;)
    {
      /* compute atanh */
      mpfr_ui_sub (te, 1, x, MPFR_RNDU);   /* (1-xt)*/
      mpfr_add_ui (t,  x, 1, MPFR_RNDD);   /* (xt+1)*/
      mpfr_div (t, t, te, MPFR_RNDN);      /* (1+xt)/(1-xt)*/
      mpfr_log (t, t, MPFR_RNDN);          /* ln((1+xt)/(1-xt))*/
      mpfr_div_2ui (t, t, 1, MPFR_RNDN);   /* (1/2)*ln((1+xt)/(1-xt))*/

      /* error estimate: see algorithms.tex */
      /* FIXME: this does not correspond to the value in algorithms.tex!!! */
      /* err=Nt-__gmpfr_ceil_log2(1+5*pow(2,1-MPFR_EXP(t)));*/
      err = Nt - (MAX (4 - MPFR_GET_EXP (t), 0) + 1);

      if (MPFR_LIKELY (MPFR_IS_ZERO (t)
                       || MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
        break;

      /* reactualisation of the precision */
      MPFR_ZIV_NEXT (loop, Nt);
      mpfr_set_prec (t, Nt);
      mpfr_set_prec (te, Nt);
    }
  MPFR_ZIV_FREE (loop);

  inexact = mpfr_set4 (y, t, rnd_mode, MPFR_SIGN (xt));

  mpfr_clear(t);
  mpfr_clear(te);

  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (y, inexact, rnd_mode);
}
コード例 #27
0
ファイル: tremquo.c プロジェクト: 119/aircam-openwrt
int
main (int argc, char *argv[])
{
  mpfr_t x, y, r;
  long q[1];

  if (argc == 3) /* usage: tremquo x y (rnd=MPFR_RNDN implicit) */
    {
      mpfr_init2 (x, GMP_NUMB_BITS);
      mpfr_init2 (y, GMP_NUMB_BITS);
      mpfr_init2 (r, GMP_NUMB_BITS);
      mpfr_set_str (x, argv[1], 10, MPFR_RNDN);
      mpfr_set_str (y, argv[2], 10, MPFR_RNDN);
      mpfr_remquo (r, q, x, y, MPFR_RNDN);
      printf ("r=");
      mpfr_out_str (stdout, 10, 0, r, MPFR_RNDN);
      printf (" q=%ld\n", q[0]);
      mpfr_clear (x);
      mpfr_clear (y);
      mpfr_clear (r);
      return 0;
    }

  tests_start_mpfr ();

  bug20090227 ();

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (r);

  /* special values */
  mpfr_set_nan (x);
  mpfr_set_ui (y, 1, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_nan_p (r));

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_set_nan (y);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_nan_p (r));

  mpfr_set_inf (x, 1); /* +Inf */
  mpfr_set_ui (y, 1, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_nan_p (r));

  mpfr_set_inf (x, 1); /* +Inf */
  mpfr_set_ui (y, 0, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_nan_p (r));

  mpfr_set_inf (x, 1); /* +Inf */
  mpfr_set_inf (y, 1);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_nan_p (r));

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_set_inf (y, 1);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_POS (r));
  MPFR_ASSERTN (q[0] == (long) 0);

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_neg (x, x, MPFR_RNDN); /* -0 */
  mpfr_set_inf (y, 1);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_NEG (r));
  MPFR_ASSERTN (q[0] == (long) 0);

  mpfr_set_ui (x, 17, MPFR_RNDN);
  mpfr_set_inf (y, 1);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp (r, x) == 0);
  MPFR_ASSERTN (q[0] == (long) 0);

  mpfr_set_ui (x, 17, MPFR_RNDN);
  mpfr_set_ui (y, 0, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_nan_p (r));

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_set_ui (y, 17, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_POS (r));
  MPFR_ASSERTN (q[0] == (long) 0);

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_neg (x, x, MPFR_RNDN);
  mpfr_set_ui (y, 17, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_NEG (r));
  MPFR_ASSERTN (q[0] == (long) 0);

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

  /* check four possible sign combinations */
  mpfr_set_ui (x, 42, MPFR_RNDN);
  mpfr_set_ui (y, 17, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_ui (r, 8) == 0);
  MPFR_ASSERTN (q[0] == (long) 2);
  mpfr_set_si (x, -42, MPFR_RNDN);
  mpfr_set_ui (y, 17, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_si (r, -8) == 0);
  MPFR_ASSERTN (q[0] == (long) -2);
  mpfr_set_si (x, -42, MPFR_RNDN);
  mpfr_set_si (y, -17, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_si (r, -8) == 0);
  MPFR_ASSERTN (q[0] == (long) 2);
  mpfr_set_ui (x, 42, MPFR_RNDN);
  mpfr_set_si (y, -17, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_ui (r, 8) == 0);
  MPFR_ASSERTN (q[0] == (long) -2);

  mpfr_set_prec (x, 100);
  mpfr_set_prec (y, 50);
  mpfr_set_ui (x, 42, MPFR_RNDN);
  mpfr_nextabove (x); /* 42 + 2^(-94) */
  mpfr_set_ui (y, 21, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -94) == 0);
  MPFR_ASSERTN (q[0] == (long) 2);

  mpfr_set_prec (x, 50);
  mpfr_set_prec (y, 100);
  mpfr_set_ui (x, 42, MPFR_RNDN);
  mpfr_nextabove (x); /* 42 + 2^(-44) */
  mpfr_set_ui (y, 21, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -44) == 0);
  MPFR_ASSERTN (q[0] == (long) 2);

  mpfr_set_prec (x, 100);
  mpfr_set_prec (y, 50);
  mpfr_set_ui (x, 42, MPFR_RNDN);
  mpfr_set_ui (y, 21, MPFR_RNDN);
  mpfr_nextabove (y); /* 21 + 2^(-45) */
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  /* r should be 42 - 2*(21 + 2^(-45)) = -2^(-44) */
  MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -44) == 0);
  MPFR_ASSERTN (q[0] == (long) 2);

  mpfr_set_prec (x, 50);
  mpfr_set_prec (y, 100);
  mpfr_set_ui (x, 42, MPFR_RNDN);
  mpfr_set_ui (y, 21, MPFR_RNDN);
  mpfr_nextabove (y); /* 21 + 2^(-95) */
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  /* r should be 42 - 2*(21 + 2^(-95)) = -2^(-94) */
  MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -94) == 0);
  MPFR_ASSERTN (q[0] == (long) 2);

  /* exercise large quotient */
  mpfr_set_ui_2exp (x, 1, 65, MPFR_RNDN);
  mpfr_set_ui (y, 1, MPFR_RNDN);
  /* quotient is 2^65 */
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_si (r, 0) == 0);
  MPFR_ASSERTN (q[0] % 1073741824L == 0L);

  /* another large quotient */
  mpfr_set_prec (x, 65);
  mpfr_set_prec (y, 65);
  mpfr_const_pi (x, MPFR_RNDN);
  mpfr_mul_2exp (x, x, 63, MPFR_RNDN);
  mpfr_const_log2 (y, MPFR_RNDN);
  mpfr_set_prec (r, 10);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  /* q should be 41803643793084085130, r should be 605/2048 */
  MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 605, -11) == 0);
  MPFR_ASSERTN ((q[0] > 0) && ((q[0] % 1073741824L) == 733836170L));

  /* check cases where quotient is 1.5 +/- eps */
  mpfr_set_prec (x, 65);
  mpfr_set_prec (y, 65);
  mpfr_set_prec (r, 63);
  mpfr_set_ui (x, 3, MPFR_RNDN);
  mpfr_set_ui (y, 2, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  /* x/y = 1.5, quotient should be 2 (even rule), remainder should be -1 */
  MPFR_ASSERTN (mpfr_cmp_si (r, -1) == 0);
  MPFR_ASSERTN (q[0] == 2L);
  mpfr_set_ui (x, 3, MPFR_RNDN);
  mpfr_nextabove (x); /* 3 + 2^(-63) */
  mpfr_set_ui (y, 2, MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  /* x/y = 1.5 + 2^(-64), quo should be 2, r should be -1 + 2^(-63) */
  MPFR_ASSERTN (mpfr_add_ui (r, r, 1, MPFR_RNDN) == 0);
  MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -63) == 0);
  MPFR_ASSERTN (q[0] == 2L);
  mpfr_set_ui (x, 3, MPFR_RNDN);
  mpfr_set_ui (y, 2, MPFR_RNDN);
  mpfr_nextabove (y); /* 2 + 2^(-63) */
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  /* x/y = 1.5 - eps, quo should be 1, r should be 1 - 2^(-63) */
  MPFR_ASSERTN (mpfr_sub_ui (r, r, 1, MPFR_RNDN) == 0);
  MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -63) == 0);
  MPFR_ASSERTN (q[0] == 1L);

  /* bug founds by Kaveh Ghazi, 3 May 2007 */
  mpfr_set_ui (x, 2, MPFR_RNDN);
  mpfr_set_ui (y, 3, MPFR_RNDN);
  mpfr_remainder (r, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_si (r, -1) == 0);

  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_set_ui (y, 1, MPFR_RNDN);
  mpfr_remainder (r, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_si (r, 0) == 0 && MPFR_SIGN (r) < 0);

  /* check argument reuse */
  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_set_ui (y, 1, MPFR_RNDN);
  mpfr_remainder (x, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp_si (x, 0) == 0 && MPFR_SIGN (x) < 0);

  mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
  mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN);
  mpfr_remquo (r, q, x, y, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_zero_p (r) && MPFR_SIGN (r) > 0);
  MPFR_ASSERTN (q[0] == 0);

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (r);

  tests_end_mpfr ();

  return 0;
}
コード例 #28
0
ファイル: tget_sj.c プロジェクト: BreakawayConsulting/mpfr
static void
check_erange (void)
{
  mpfr_t x;
  uintmax_t dl;
  intmax_t d;

  /* Test for ERANGE flag + correct behaviour if overflow */

  mpfr_init2 (x, 256);
  mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  dl = mpfr_get_uj (x, MPFR_RNDN);
  if (dl != MPFR_UINTMAX_MAX || mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (1)\n");
      exit (1);
    }
  mpfr_add_ui (x, x, 1, MPFR_RNDN);
  dl = mpfr_get_uj (x, MPFR_RNDN);
  if (dl != MPFR_UINTMAX_MAX || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (2)\n");
      exit (1);
    }
  mpfr_set_sj (x, -1, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  dl = mpfr_get_uj (x, MPFR_RNDN);
  if (dl != 0 || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_uj + ERANGE + -1 \n");
      exit (1);
    }
  mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  d = mpfr_get_sj (x, MPFR_RNDN);
  if (d != MPFR_INTMAX_MAX || mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (1)\n");
      exit (1);
    }
  mpfr_add_ui (x, x, 1, MPFR_RNDN);
  d = mpfr_get_sj (x, MPFR_RNDN);
  if (d != MPFR_INTMAX_MAX || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (2)\n");
      exit (1);
    }
  mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN);
  mpfr_clear_erangeflag ();
  d = mpfr_get_sj (x, MPFR_RNDN);
  if (d != MPFR_INTMAX_MIN || mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (1)\n");
      exit (1);
    }
  mpfr_sub_ui (x, x, 1, MPFR_RNDN);
  d = mpfr_get_sj (x, MPFR_RNDN);
  if (d != MPFR_INTMAX_MIN || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (2)\n");
      exit (1);
    }

  mpfr_set_nan (x);
  mpfr_clear_erangeflag ();
  d = mpfr_get_uj (x, MPFR_RNDN);
  if (d != 0 || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_uj + NaN\n");
      exit (1);
    }
  mpfr_clear_erangeflag ();
  d = mpfr_get_sj (x, MPFR_RNDN);
  if (d != 0 || !mpfr_erangeflag_p ())
    {
      printf ("ERROR for get_sj + NaN\n");
      exit (1);
    }

  mpfr_clear (x);
}
コード例 #29
0
/* hard test of rounding */
static void
check_rounding (void)
{
  mpfr_t a, b, c, res;
  mpfr_prec_t p;
  long k, l;
  int i;

#define MAXKL (2 * GMP_NUMB_BITS)
  for (p = MPFR_PREC_MIN; p <= GMP_NUMB_BITS; p++)
    {
      mpfr_init2 (a, p);
      mpfr_init2 (res, p);
      mpfr_init2 (b, p + 1 + MAXKL);
      mpfr_init2 (c, MPFR_PREC_MIN);

      /* b = 2^p + 1 + 2^(-k), c = 2^(-l) */
      for (k = 0; k <= MAXKL; k++)
        for (l = 0; l <= MAXKL; l++)
          {
            mpfr_set_ui_2exp (b, 1, p, MPFR_RNDN);
            mpfr_add_ui (b, b, 1, MPFR_RNDN);
            mpfr_mul_2ui (b, b, k, MPFR_RNDN);
            mpfr_add_ui (b, b, 1, MPFR_RNDN);
            mpfr_div_2ui (b, b, k, MPFR_RNDN);
            mpfr_set_ui_2exp (c, 1, -l, MPFR_RNDN);
            i = mpfr_sub (a, b, c, MPFR_RNDN);
            /* b - c = 2^p + 1 + 2^(-k) - 2^(-l), should be rounded to
               2^p for l <= k, and 2^p+2 for l < k */
            if (l <= k)
              {
                if (mpfr_cmp_ui_2exp (a, 1, p) != 0)
                  {
                    printf ("Wrong result in check_rounding\n");
                    printf ("p=%lu k=%ld l=%ld\n", p, k, l);
                    printf ("b="); mpfr_print_binary (b); puts ("");
                    printf ("c="); mpfr_print_binary (c); puts ("");
                    printf ("Expected 2^%lu\n", p);
                    printf ("Got      "); mpfr_print_binary (a); puts ("");
                    exit (1);
                  }
                if (i >= 0)
                  {
                    printf ("Wrong ternary value in check_rounding\n");
                    printf ("p=%lu k=%ld l=%ld\n", p, k, l);
                    printf ("b="); mpfr_print_binary (b); puts ("");
                    printf ("c="); mpfr_print_binary (c); puts ("");
                    printf ("a="); mpfr_print_binary (a); puts ("");
                    printf ("Expected < 0, got %d\n", i);
                    exit (1);
                  }
              }
            else /* l < k */
              {
                mpfr_set_ui_2exp (res, 1, p, MPFR_RNDN);
                mpfr_add_ui (res, res, 2, MPFR_RNDN);
                if (mpfr_cmp (a, res) != 0)
                  {
                    printf ("Wrong result in check_rounding\n");
                    printf ("b="); mpfr_print_binary (b); puts ("");
                    printf ("c="); mpfr_print_binary (c); puts ("");
                    printf ("Expected "); mpfr_print_binary (res); puts ("");
                    printf ("Got      "); mpfr_print_binary (a); puts ("");
                    exit (1);
                  }
                if (i <= 0)
                  {
                    printf ("Wrong ternary value in check_rounding\n");
                    printf ("b="); mpfr_print_binary (b); puts ("");
                    printf ("c="); mpfr_print_binary (c); puts ("");
                    printf ("Expected > 0, got %d\n", i);
                    exit (1);
                  }
              }
          }

      mpfr_clear (a);
      mpfr_clear (res);
      mpfr_clear (b);
      mpfr_clear (c);
    }
}
コード例 #30
0
ファイル: tlgamma.c プロジェクト: mmanley/Antares
static void
special (void)
{
  mpfr_t x, y;
  int inex;
  int sign;

  mpfr_init (x);
  mpfr_init (y);

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

  mpfr_set_inf (x, -1);
  mpfr_lgamma (y, &sign, x, GMP_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, GMP_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, GMP_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, GMP_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, GMP_RNDN);
  mpfr_neg (x, x, GMP_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, GMP_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, GMP_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, GMP_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, GMP_RNDN);
  mpfr_lgamma (y, &sign, x, GMP_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for lgamma(-1)\n");
      exit (1);
    }

  mpfr_set_ui (x, 2, GMP_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, GMP_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, GMP_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, GMP_RNDN);
  mpfr_set_str (x, CHECK_Y1, 10, GMP_RNDN);
  if (mpfr_equal_p (y, x) == 0 || sign != 1)
    {
      printf ("mpfr_lgamma("CHECK_X1") is wrong:\n"
              "expected ");
      mpfr_print_binary (x); putchar ('\n');
      printf ("got      ");
      mpfr_print_binary (y); putchar ('\n');
      exit (1);
    }

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

  mpfr_set_prec (x, 8);
  mpfr_set_prec (y, 175);
  mpfr_set_ui (x, 33, GMP_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, GMP_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, GMP_RNDN);
  sign = -17;
  mpfr_lgamma (x, &sign, y, GMP_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_print_binary (y); puts ("");
      printf ("Got      "); mpfr_print_binary (x); puts ("");
      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, GMP_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, GMP_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, GMP_RNDN);
  mpfr_add_ui (x, x, 1, GMP_RNDN);
  mpfr_div_2ui (x, x, 1, GMP_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, GMP_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, GMP_RNDN);
  mpfr_sub_ui (x, x, 1, GMP_RNDN);
  mpfr_div_2ui (x, x, 1, GMP_RNDN);
  sign = -17;
  mpfr_lgamma (y, &sign, x, GMP_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, GMP_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, GMP_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, GMP_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, GMP_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, GMP_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, GMP_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, GMP_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, GMP_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, GMP_RNDN);
  mpfr_set_str_binary (x, "100101.00111101101010000000101010111010001111001101111");
  MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));

  mpfr_clear (x);
  mpfr_clear (y);
}