Example #1
0
File: tget_d.c Project: Canar/mpfr
static int
check_denorms (void)
{
  mpfr_rnd_t rnd_mode;
  mpfr_t x;
  double d, d2, dd, f;
  int fail = 0, k, n;

  mpfr_init2 (x, GMP_NUMB_BITS);

  rnd_mode = MPFR_RNDN;
  for (k = -17; k <= 17; k += 2)
    {
      d = (double) k * DBL_MIN; /* k * 2^(-1022) */
      f = 1.0;
      mpfr_set_si (x, k, MPFR_RNDN);
      mpfr_div_2exp (x, x, 1022, MPFR_RNDN); /* k * 2^(-1022) */
      for (n = 0; n <= 58; n++)
        {
          d2 = d * f;
          dd = mpfr_get_d (x, rnd_mode);
          if (d2 != dd) /* should be k * 2^(-1022-n) for n < 53 */
            {
              printf ("Wrong result for %d * 2^(%d), rnd_mode %d\n",
                      k, -1022-n, rnd_mode);
              printf ("got %.20e instead of %.20e\n", dd, d2);
              fail = 1;
            }
          f *= 0.5;
          mpfr_div_2exp (x, x, 1, MPFR_RNDN);
        }
    }

  mpfr_set_str_binary (x, "1e-1074");
  dd = mpfr_get_d (x, MPFR_RNDA);
  d2 = DBL_MIN; /* 2^(-1022) */
  for (k = 0; k < 52; k++)
    d2 *= 0.5;  /* 2^(-1074) */
  /* we first check that d2 is not zero (it could happen on a platform with
     no subnormals) */
  if (d2 != 0.0 && dd != d2)
    {
      printf ("Error for x=1e-1074, RNDA\n");
      exit (1);
    }

  mpfr_set_str_binary (x, "1e-1075");
  dd = mpfr_get_d (x, MPFR_RNDA);
  if (d2 != 0.0 && dd != d2)
    {
      printf ("Error for x=1e-1075, RNDA\n");
      printf ("expected %.16e\n", d2);
      printf ("got      %.16e\n", dd);
      exit (1);
    }

  mpfr_clear (x);
  return fail;
}
Example #2
0
File: tadd.c Project: 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);
}
Example #3
0
File: tadd.c Project: 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);
}
Example #4
0
/* 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);
}
Example #5
0
int
check_denorms ()
{
  mp_rnd_t rnd_mode;
  mpfr_t x;
  double d, d2, dd, f;
  int fail = 0, k, n;

  mpfr_init2 (x, BITS_PER_MP_LIMB);

  for (rnd_mode = 0; rnd_mode <= 3; rnd_mode++)
    {
#ifdef MPFR_HAVE_FESETROUND
      mpfr_set_machine_rnd_mode (rnd_mode);
#else
      if (rnd_mode)
        break; /* second iteration */
      rnd_mode = GMP_RNDN;
#endif
      for (k = -17; k <= 17; k += 2)
        {
          d = k * DBL_MIN; /* k * 2^(-1022) */
          f = 1.0;
          mpfr_set_si (x, k, GMP_RNDN);
          mpfr_div_2exp (x, x, 1022, GMP_RNDN); /* k * 2^(-1022) */
          for (n = 0; n <= 58; n++)
            {
              d2 = d * f;
              dd = mpfr_get_d (x, rnd_mode);
              if (d2 != dd) /* should be k * 2^(-1022-n) for n < 53 */
                {
                  fprintf (stderr,
                           "Wrong result for %d * 2^(%d), rnd_mode %d\n",
                           k, -1022-n, rnd_mode);
                  fprintf (stderr, "got %.20e instead of %.20e\n", dd, d2);
                  fail = 1;
                }
              f *= 0.5;
              mpfr_div_2exp (x, x, 1, GMP_RNDN);
            }
        }
    }

  mpfr_clear (x);
  return fail;
}
Example #6
0
static void
check_one (mpz_ptr z)
{
  int    inex;
  int    sh, neg;
  mpfr_t f;
  mpz_t  got;

  mpfr_init2 (f, MAX( mpz_sizeinbase (z, 2), MPFR_PREC_MIN) );
  mpz_init (got);

  for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++)
    {
      for (neg = 0; neg <= 1; neg++)
        {
          mpz_neg (z, z);
          mpfr_set_z (f, z, MPFR_RNDN);

          if (sh < 0)
            {
              mpz_tdiv_q_2exp (z, z, -sh);
              mpfr_div_2exp (f, f, -sh, MPFR_RNDN);
            }
          else
            {
              mpz_mul_2exp (z, z, sh);
              mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
            }

          inex = mpfr_get_z (got, f, MPFR_RNDZ);

          if (mpz_cmp (got, z) != 0)
            {
              printf ("Wrong result for shift=%d\n", sh);
              printf ("     f "); mpfr_dump (f);
              printf ("   got "); mpz_dump (got);
              printf ("  want "); mpz_dump (z);
              exit (1);
            }
          if (! SAME_SIGN (inex, - mpfr_cmp_z (f, z)))
            {
              printf ("Wrong inexact value for shift=%d\n", sh);
              printf ("    f "); mpfr_dump (f);
              printf ("  got %+d\n", inex);
              printf (" want %+d\n", -mpfr_cmp_z (f, z));
              exit (1);
            }
        }
    }

  mpfr_clear (f);
  mpz_clear (got);
}
Example #7
0
static void
check_flags (void)
{
    mpfr_t x;
    mpfr_exp_t old_emin, old_emax;

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

    /* Check the functions not the macros ! */
    (mpfr_clear_flags)();
    mpfr_set_double_range ();

    mpfr_set_ui (x, 1, MPFR_RNDN);
    (mpfr_clear_overflow)();
    mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
    if (!(mpfr_overflow_p)())
        ERROR("ERROR: No overflow detected!\n");

    (mpfr_clear_underflow)();
    mpfr_set_ui (x, 1, MPFR_RNDN);
    mpfr_div_2exp (x, x, 1025, MPFR_RNDN);
    if (!(mpfr_underflow_p)())
        ERROR("ERROR: No underflow detected!\n");

    (mpfr_clear_nanflag)();
    MPFR_SET_NAN(x);
    mpfr_add (x, x, x, MPFR_RNDN);
    if (!(mpfr_nanflag_p)())
        ERROR("ERROR: No NaN flag!\n");

    (mpfr_clear_inexflag)();
    mpfr_set_ui(x, 2, MPFR_RNDN);
    mpfr_cos(x, x, MPFR_RNDN);
    if (!(mpfr_inexflag_p)())
        ERROR("ERROR: No inexact flag!\n");

    (mpfr_clear_erangeflag) ();
    mpfr_set_ui (x, 1, MPFR_RNDN);
    mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
    mpfr_get_ui (x, MPFR_RNDN);
    if (!(mpfr_erangeflag_p)())
        ERROR ("ERROR: No erange flag!\n");

    mpfr_clear (x);
    set_emin (old_emin);
    set_emax (old_emax);
}
Example #8
0
static void
check_one (mpz_ptr z)
{
  int    sh, neg;
  mpfr_t f;
  mpz_t  got;

  mpfr_init2 (f, MAX( mpz_sizeinbase (z, 2), MPFR_PREC_MIN) );
  mpz_init (got);

  for (sh = -2*BITS_PER_MP_LIMB ; sh < 2*BITS_PER_MP_LIMB ; sh++)
    {
      for (neg = 0; neg <= 1; neg++)
        {
          mpz_neg (z, z);
          mpfr_set_z (f, z, GMP_RNDN);

          if (sh < 0)
            {
              mpz_tdiv_q_2exp (z, z, -sh);
              mpfr_div_2exp (f, f, -sh, GMP_RNDN);
            }
          else
            {
              mpz_mul_2exp (z, z, sh);
              mpfr_mul_2exp (f, f, sh, GMP_RNDN);
            }

          mpfr_get_z (got, f, GMP_RNDZ);

          if (mpz_cmp (got, z) != 0)
            {
              printf ("Wrong result for shift=%d\n", sh);
              printf ("     f "); mpfr_dump (f);
              printf ("   got "); mpz_dump (got);
              printf ("  want "); mpz_dump (z);
              exit (1);
            }
        }
    }

  mpfr_clear (f);
  mpz_clear (got);
}
Example #9
0
File: zeta.c Project: 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;
}
Example #10
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 #11
0
static void
bug20090520 (void)
{
  mpfr_t x;
  long double d, e;
  int i;

  mpfr_init (x);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  d = 1.0;
  mpfr_div_2exp (x, x, 16383, MPFR_RNDN);
  for (i = 0; i < 16383; i++)
    d *= 0.5;
  e = mpfr_get_ld (x, MPFR_RNDN);
  if (e != d)
    {
      printf ("mpfr_get_ld(1e-16383) failed\n");
      printf ("expected %.20Le\n", d);
      printf ("got      %.20Le\n", e);
      exit (1);
    }
  mpfr_clear (x);
}
static void
special (void)
{
  mpfr_t x, y, z;
  int inexact;
  mpfr_prec_t p;

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

  mpfr_set_prec (x, 64);
  mpfr_set_str_binary (x, "1010000010100011011001010101010010001100001101011101110001011001E-1");
  mpfr_set_prec (y, 32);
  test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 2405743844UL))
    {
      printf ("Error for n^2+n+1/2 with n=2405743843\n");
      exit (1);
    }

  mpfr_set_prec (x, 65);
  mpfr_set_str_binary (x, "10100000101000110110010101010100100011000011010111011100010110001E-2");
  mpfr_set_prec (y, 32);
  test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 2405743844UL))
    {
      printf ("Error for n^2+n+1/4 with n=2405743843\n");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 66);
  mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100011E-3");
  mpfr_set_prec (y, 32);
  test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 2405743844UL))
    {
      printf ("Error for n^2+n+1/4+1/8 with n=2405743843\n");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 66);
  mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100001E-3");
  mpfr_set_prec (y, 32);
  test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 2405743843UL))
    {
      printf ("Error for n^2+n+1/8 with n=2405743843\n");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 27);
  mpfr_set_str_binary (x, "0.110100111010101000010001011");
  if ((inexact = test_sqrt (x, x, MPFR_RNDZ)) >= 0)
    {
      printf ("Wrong inexact flag: expected -1, got %d\n", inexact);
      exit (1);
    }

  mpfr_set_prec (x, 2);
  for (p=2; p<1000; p++)
    {
      mpfr_set_prec (z, p);
      mpfr_set_ui (z, 1, MPFR_RNDN);
      mpfr_nexttoinf (z);
      test_sqrt (x, z, MPFR_RNDU);
      if (mpfr_cmp_ui_2exp(x, 3, -1))
        {
          printf ("Error: sqrt(1+ulp(1), up) should give 1.5 (prec=%u)\n",
                  (unsigned int) p);
          printf ("got "); mpfr_print_binary (x); puts ("");
          exit (1);
        }
    }

  /* check inexact flag */
  mpfr_set_prec (x, 5);
  mpfr_set_str_binary (x, "1.1001E-2");
  if ((inexact = test_sqrt (x, x, MPFR_RNDN)))
    {
      printf ("Wrong inexact flag: expected 0, got %d\n", inexact);
      exit (1);
    }

  mpfr_set_prec (x, 2);
  mpfr_set_prec (z, 2);

  /* checks the sign is correctly set */
  mpfr_set_si (x, 1,  MPFR_RNDN);
  mpfr_set_si (z, -1, MPFR_RNDN);
  test_sqrt (z, x, MPFR_RNDN);
  if (mpfr_cmp_ui (z, 0) < 0)
    {
      printf ("Error: square root of 1 gives ");
      mpfr_print_binary(z);
      putchar('\n');
      exit (1);
    }

  mpfr_set_prec (x, 192);
  mpfr_set_prec (z, 160);
  mpfr_set_str_binary (z, "0.1011010100000100100100100110011001011100100100000011000111011001011101101101110000110100001000100001100001011000E1");
  mpfr_set_prec (x, 160);
  test_sqrt(x, z, MPFR_RNDN);
  test_sqrt(z, x, MPFR_RNDN);

  mpfr_set_prec (x, 53);
  mpfr_set_str (x, "8093416094703476.0", 10, MPFR_RNDN);
  mpfr_div_2exp (x, x, 1075, MPFR_RNDN);
  test_sqrt (x, x, MPFR_RNDN);
  mpfr_set_str (z, "1e55596835b5ef@-141", 16, MPFR_RNDN);
  if (mpfr_cmp (x, z))
    {
      printf ("Error: square root of 8093416094703476*2^(-1075)\n");
      printf ("expected "); mpfr_dump (z);
      printf ("got      "); mpfr_dump (x);
      exit (1);
    }

  mpfr_set_prec (x, 33);
  mpfr_set_str_binary (x, "0.111011011011110001100111111001000e-10");
  mpfr_set_prec (z, 157);
  inexact = test_sqrt (z, x, MPFR_RNDN);
  mpfr_set_prec (x, 157);
  mpfr_set_str_binary (x, "0.11110110101100101111001011100011100011100001101010111011010000100111011000111110100001001011110011111100101110010110010110011001011011010110010000011001101E-5");
  if (mpfr_cmp (x, z))
    {
      printf ("Error: square root (1)\n");
      exit (1);
    }
  if (inexact <= 0)
    {
      printf ("Error: wrong inexact flag (1)\n");
      exit (1);
    }

  /* case prec(result) << prec(input) */
  mpfr_set_prec (z, 2);
  for (p = 2; p < 1000; p++)
    {
      mpfr_set_prec (x, p);
      mpfr_set_ui (x, 1, MPFR_RNDN);
      mpfr_nextabove (x);
      /* 1.0 < x <= 1.5 thus 1 < sqrt(x) <= 1.23 */
      inexact = test_sqrt (z, x, MPFR_RNDN);
      MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
      inexact = test_sqrt (z, x, MPFR_RNDZ);
      MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
      inexact = test_sqrt (z, x, MPFR_RNDU);
      MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
      inexact = test_sqrt (z, x, MPFR_RNDD);
      MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
      inexact = test_sqrt (z, x, MPFR_RNDA);
      MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
    }

  /* corner case rw = 0 in rounding to nearest */
  mpfr_set_prec (z, GMP_NUMB_BITS - 1);
  mpfr_set_prec (y, GMP_NUMB_BITS - 1);
  mpfr_set_ui (y, 1, MPFR_RNDN);
  mpfr_mul_2exp (y, y, GMP_NUMB_BITS - 1, MPFR_RNDN);
  mpfr_nextabove (y);
  for (p = 2 * GMP_NUMB_BITS - 1; p <= 1000; p++)
    {
      mpfr_set_prec (x, p);
      mpfr_set_ui (x, 1, MPFR_RNDN);
      mpfr_set_exp (x, GMP_NUMB_BITS);
      mpfr_add_ui (x, x, 1, MPFR_RNDN);
      /* now x = 2^(GMP_NUMB_BITS - 1) + 1 (GMP_NUMB_BITS bits) */
      MPFR_ASSERTN (mpfr_mul (x, x, x, MPFR_RNDN) == 0); /* exact */
      inexact = test_sqrt (z, x, MPFR_RNDN);
      /* even rule: z should be 2^(GMP_NUMB_BITS - 1) */
      MPFR_ASSERTN (inexact < 0);
      MPFR_ASSERTN (mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0);
      mpfr_nextbelow (x);
      /* now x is just below [2^(GMP_NUMB_BITS - 1) + 1]^2 */
      inexact = test_sqrt (z, x, MPFR_RNDN);
      MPFR_ASSERTN(inexact < 0 &&
                   mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0);
      mpfr_nextabove (x);
      mpfr_nextabove (x);
      /* now x is just above [2^(GMP_NUMB_BITS - 1) + 1]^2 */
      inexact = test_sqrt (z, x, MPFR_RNDN);
      if (mpfr_cmp (z, y))
        {
          printf ("Error for sqrt(x) in rounding to nearest\n");
          printf ("x="); mpfr_dump (x);
          printf ("Expected "); mpfr_dump (y);
          printf ("Got      "); mpfr_dump (z);
          exit (1);
        }
      if (inexact <= 0)
        {
          printf ("Wrong inexact flag in corner case for p = %lu\n", (unsigned long) p);
          exit (1);
        }
    }

  mpfr_set_prec (x, 1000);
  mpfr_set_ui (x, 9, MPFR_RNDN);
  mpfr_set_prec (y, 10);
  inexact = test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 3) || inexact != 0)
    {
      printf ("Error in sqrt(9:1000) for prec=10\n");
      exit (1);
    }
  mpfr_set_prec (y, GMP_NUMB_BITS);
  mpfr_nextabove (x);
  inexact = test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 3) || inexact >= 0)
    {
      printf ("Error in sqrt(9:1000) for prec=%d\n", (int) GMP_NUMB_BITS);
      exit (1);
    }
  mpfr_set_prec (x, 2 * GMP_NUMB_BITS);
  mpfr_set_prec (y, GMP_NUMB_BITS);
  mpfr_set_ui (y, 1, MPFR_RNDN);
  mpfr_nextabove (y);
  mpfr_set (x, y, MPFR_RNDN);
  inexact = test_sqrt (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 1) || inexact >= 0)
    {
      printf ("Error in sqrt(1) for prec=%d\n", (int) GMP_NUMB_BITS);
      mpfr_dump (y);
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Example #13
0
static void
check_small (void)
{
  mpfr_t x;
  char *s;
  mpfr_exp_t e;
  mpfr_prec_t p;

  mpfr_init (x);

  mpfr_set_prec (x, 20);
  mpfr_set_ui (x, 2, MPFR_RNDN);
  mpfr_nexttozero (x);
  s = mpfr_get_str (NULL, &e, 4, 2, x, MPFR_RNDU);
  if (strcmp (s, "20") || (e != 1))
    {
      printf ("Error in mpfr_get_str: 2- rounded up with 2 digits"
              " in base 4\n");
      exit (1);
    }
  mpfr_free_str (s);

  /* check n_digits=0 */
  mpfr_set_prec (x, 5);
  mpfr_set_ui (x, 17, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 3, 0, x, MPFR_RNDN);
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 36, 0, x, MPFR_RNDN);
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 62, 0, x, MPFR_RNDN);
  mpfr_free_str (s);

  mpfr_set_prec (x, 64);
  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_div_2exp (x, x, 63, MPFR_RNDN); /* x = -2^(-63) */
  mpfr_add_ui (x, x, 1, MPFR_RNDN); /* x = 1 - 2^(-63) */
  mpfr_mul_2exp (x, x, 32, MPFR_RNDN); /* x = 2^32 - 2^(-31) */
  s = mpfr_get_str (NULL, &e, 3, 21, x, MPFR_RNDU);
  if (strcmp (s, "102002022201221111211") || (e != 21))
    {
      printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with"
              " 21 digits in base 3\n");
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 3, 20, x, MPFR_RNDU);
  if (strcmp (s, "10200202220122111122") || (e != 21))
    {
      printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with"
              " 20 digits in base 3\n");
      exit (1);
    }
  mpfr_free_str (s);

  /* check corner case ret!=0, j0!=0 in mpfr_get_str_aux */
  mpfr_set_prec (x, 100);
  mpfr_set_str_binary (x, "0.1001011111010001101110010101010101111001010111111101101101100110100011110110000101110110001011110000E-9");
  s = mpfr_get_str (NULL, &e, 3, 2, x, MPFR_RNDU);
  if (strcmp (s, "22") || (e != -6))
    {
      printf ("Error in mpfr_get_str: 100-bit number rounded up with"
              " 2 digits in base 3\n");
      exit (1);
    }
  mpfr_free_str (s);

  /* check corner case exact=0 in mpfr_get_str_aux */
  mpfr_set_prec (x, 100);
  mpfr_set_str_binary (x, "0.1001001111101101111000101000110111111010101100000110010001111111011001101011101100001100110000000000E8");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDZ);
  if (strcmp (s, "14") || (e != 3))
    {
      printf ("Error in mpfr_get_str: 100-bit number rounded to zero with"
              " 2 digits in base 10\n");
      exit (1);
    }
  mpfr_free_str (s);

  for (p=4; p<=200; p++)
    {
      mpfr_set_prec (x, p);
      mpfr_set_str (x, "6.5", 10, MPFR_RNDN);

      s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN);
      if (strcmp (s, "10") || (e != 2))
        {
          printf ("Error in mpfr_get_str: 6.5 rounded to nearest with"
                  " 2 digits in base 6\n");
          exit (1);
        }
      mpfr_free_str (s);

      mpfr_nexttoinf (x);
      s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN);
      if (strcmp (s, "11") || (e != 2))
        {
          printf ("Error in mpfr_get_str: 6.5+ rounded to nearest with"
                  " 2 digits in base 6\ngot %se%d instead of 11e2\n",
                  s, (int) e);
          exit (1);
        }
      mpfr_free_str (s);

      mpfr_set_str (x, "6.5", 10, MPFR_RNDN);
      mpfr_nexttozero (x);
      s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN);
      if (strcmp (s, "10") || (e != 2))
        {
          printf ("Error in mpfr_get_str: 6.5- rounded to nearest with"
                  " 2 digits in base 6\n");
          exit (1);
        }
      mpfr_free_str (s);
    }

  mpfr_set_prec (x, 3);
  mpfr_set_ui (x, 7, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 2, 2, x, MPFR_RNDU);
  if (strcmp (s, "10") || (e != 4))
    {
      printf ("Error in mpfr_get_str: 7 rounded up with 2 bits should"
              " give 0.10e3 instead of 0.%s*2^%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* problem found by Fabrice Rouillier */
  mpfr_set_prec (x, 63);
  mpfr_set_str (x, "5e14", 10, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU);
  mpfr_free_str (s);

  /* bug found by Johan Vervloet */
  mpfr_set_prec (x, 6);
  mpfr_set_str (x, "688.0", 10, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 2, 4, x, MPFR_RNDU);
  if (strcmp (s, "1011") || (e != 10))
    {
      printf ("Error in mpfr_get_str: 688 printed up to 4 bits should"
              " give 1.011e9\ninstead of ");
      mpfr_out_str (stdout, 2, 4, x, MPFR_RNDU);
      puts ("");
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 38);
  mpfr_set_str_binary (x, "1.0001110111110100011010100010010100110e-6");
  s = mpfr_get_str (NULL, &e, 8, 10, x, MPFR_RNDU);
  if (strcmp (s, "1073721522") || (e != -1))
    {
      printf ("Error in mpfr_get_str (3): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 53);
  mpfr_set_str_binary (x, "0.11010111011101100010000100010101110001000000010111001E454");
  s = mpfr_get_str (NULL, &e, 19, 12, x, MPFR_RNDU);
  if (strcmp (s, "b1cgfa4gha0h") || (e != 107))
    {
      printf ("Error in mpfr_get_str (4): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 145);
  mpfr_set_str_binary (x, "-0.1000110011000001011000010101101010110110101100101110100011111100011110011001001001010000100001000011000011000000010111011001000111101001110100110e6");
  s = mpfr_get_str (NULL, &e, 4, 53, x, MPFR_RNDU);
  if (strcmp (s, "-20303001120111222312230232203330132121021100201003003") || (e != 3))
    {
      printf ("Error in mpfr_get_str (5): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 45);
  mpfr_set_str_binary (x, "-0.00100111010110010001011001110111010001010010010");
  s = mpfr_get_str (NULL, &e, 32, 9, x, MPFR_RNDN);
  if (strcmp (s, "-4tchctq54") || (e != 0))
    {
      printf ("Error in mpfr_get_str (6): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* worst case found by Vincent Lefe`vre */
  mpfr_set_prec (x, 53);
  mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E164");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "13076622631878654") || (e != 66))
    {
      printf ("Error in mpfr_get_str (7): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10000001001001001100011101010011011011111000011000100E93");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
  if (strcmp (s, "46") || e != 44)
    {
       printf ("Error in mpfr_get_str (8): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10010001111100000111001111010101001010000010111010101E55");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN);
  if (strcmp (s, "19") || e != 33)
    {
       printf ("Error in mpfr_get_str (9): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11011001010010111110010101101100111110111000010110110E44");
  s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDN);
  if (strcmp (s, "135") || e != 30)
    {
       printf ("Error in mpfr_get_str (10): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11101111101000001011100001111000011111101111011001100E72");
  s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDN);
  if (strcmp (s, "3981") || e != 38)
    {
       printf ("Error in mpfr_get_str (11): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011001001100100010111100001101110101001001111110000E46");
  s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDN);
  if (strcmp (s, "37930") || e != 30)
    {
       printf ("Error in mpfr_get_str (12): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10001100110111001011011110011011011101100011010001011E-72");
  s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDN);
  if (strcmp (s, "104950") || e != -5)
    {
       printf ("Error in mpfr_get_str (13): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10100100001011001000011001101101000110100110000010111E89");
  s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDN);
  if (strcmp (s, "3575392") || e != 43)
    {
       printf ("Error in mpfr_get_str (14): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "11000011011110110010100110001010000001010011001011001E-73");
  s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDN);
  if (strcmp (s, "72822386") || e != -6)
    {
       printf ("Error in mpfr_get_str (15): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10101010001101000111001100001000100011100010010001010E78");
  s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDN);
  if (strcmp (s, "180992873") || e != 40)
    {
      printf ("Error in mpfr_get_str (16): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10110111001000100000001101111001100101101110011011101E91");
  s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDN);
  if (strcmp (s, "1595312255") || e != 44)
    {
      printf ("Error in mpfr_get_str (17): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E93");
  s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDN);
  if (strcmp (s, "54835744350") || e != 44)
    {
      printf ("Error in mpfr_get_str (18): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E92");
  s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDN);
  if (strcmp (s, "274178721752") || e != 44)
    {
      printf ("Error in mpfr_get_str (19): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E91");
  s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDN);
  if (strcmp (s, "1370893608762") || e != 44)
    {
      printf ("Error in mpfr_get_str (20): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10010011010110011100010010100101100011101000011111111E92");
  s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDN);
  if (strcmp (s, "25672105101864") || e != 44)
    {
      printf ("Error in mpfr_get_str (21): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "100110111110110001000101110100100101101000011111001E87");
  s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDN);
  if (strcmp (s, "212231308858721") || e != 42)
    {
      printf ("Error in mpfr_get_str (22): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10111010110000111000101100101111001011011100101001111E-128");
  s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDN);
  if (strcmp (s, "193109287087290") || e != -22)
    {
      printf ("Error in mpfr_get_str (22b): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "10001101101011010001111110000111010111010000110101010E80");
  s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDN);
  if (strcmp (s, "6026241735727920") || e != 40)
    {
      printf ("Error in mpfr_get_str (23): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "100010001011101001110101000110011001001000110001001E-81");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "49741483709103481") || e != -9)
    {
      printf ("Error in mpfr_get_str (24): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11000100001001001110111010011001111001001010110101111E-101");
  s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDN);
  if (strcmp (s, "2722049") || e != -14)
    {
      printf ("Error in mpfr_get_str (25): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-135");
  s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDN);
  if (strcmp (s, "20138772") || e != -24)
    {
      printf ("Error in mpfr_get_str (26): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-136");
  s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDN);
  if (strcmp (s, "100693858") || e != -24)
    {
      printf ("Error in mpfr_get_str (27): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
    mpfr_free_str (s);
  mpfr_set_str_binary (x, "10001000001110010110001011111011111011011010000110001E-110");
  s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDN);
  if (strcmp (s, "36923634350619") || e != -17)
    {
      printf ("Error in mpfr_get_str (28): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "11001100010111000111100010000110011101110001000101111E-87");
  s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDN);
  if (strcmp (s, "4646636036100804") || e != -10)
    {
      printf ("Error in mpfr_get_str (29): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "10011111001111110100001001010111111011010101111111000E-99");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "88399901882446712") || e != -14)
    {
      printf ("Error in mpfr_get_str (30): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 8116315218207718*2^(-293) ~ 0.5100000000000000000015*10^(-72) */
  mpfr_set_str_binary (x, "11100110101011011111011100101011101110110001111100110E-293");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
  if (strcmp (s, "52") || e != -72)
    {
      printf ("Error in mpfr_get_str (31u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDD);
  if (strcmp (s, "51") || e != -72)
    {
      printf ("Error in mpfr_get_str (31d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 6712731423444934*2^536 ~ .151000000000000000000067*10^178 */
  mpfr_set_str_binary (x, "10111110110010011000110010011111101111000111111000110E536");
  s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDU);
  if (strcmp (s, "152") || e != 178)
    {
      printf ("Error in mpfr_get_str (32u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDD);
  if (strcmp (s, "151") || e != 178)
    {
      printf ("Error in mpfr_get_str (32d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 3356365711722467*2^540 ~ .120800000000000000000054*10^179 */
  mpfr_set_str_binary (x, "1011111011001001100011001001111110111100011111100011E540");
  s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDU);
  if (strcmp (s, "1209") || e != 179)
    {
      printf ("Error in mpfr_get_str (33u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDD);
  if (strcmp (s, "1208") || e != 179)
    {
      printf ("Error in mpfr_get_str (33d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 6475049196144587*2^100 ~ .8208099999999999999999988*10^46 */
  mpfr_set_str_binary (x, "10111000000010000010111011111001111010100011111001011E100");
  s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDU);
  if (strcmp (s, "82081") || e != 46)
    {
      printf ("Error in mpfr_get_str (34u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDD);
  if (strcmp (s, "82080") || e != 46)
    {
      printf ("Error in mpfr_get_str (34d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 6722280709661868*2^364 ~ .25260100000000000000000012*10^126 */
  mpfr_set_str_binary (x, "10111111000011110000011110001110001111010010010101100E364");
  s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDU);
  if (strcmp (s, "252602") || e != 126)
    {
      printf ("Error in mpfr_get_str (35u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDD);
  if (strcmp (s, "252601") || e != 126)
    {
      printf ("Error in mpfr_get_str (35d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 5381065484265332*2^(-455) ~ .578389299999999999999999982*10^(-121) */
  mpfr_set_str_binary (x, "10011000111100000110011110000101100111110011101110100E-455");
  s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDU);
  if (strcmp (s, "5783893") || e != -121)
    {
      printf ("Error in mpfr_get_str (36u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDD);
  if (strcmp (s, "5783892") || e != -121)
    {
      printf ("Error in mpfr_get_str (36d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 8369123604277281*2^(-852) ~ .27869147000000000000000000056*10^(-240) */
  mpfr_set_str_binary (x, "11101101110111010110001101111100000111010100000100001E-852");
  s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDU);
  if (strcmp (s, "27869148") || e != -240)
    {
      printf ("Error in mpfr_get_str (37u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDD);
  if (strcmp (s, "27869147") || e != -240)
    {
      printf ("Error in mpfr_get_str (37d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 7976538478610756*2^377 ~ .245540326999999999999999999982*10^130 */
  mpfr_set_str_binary (x, "11100010101101001111010010110100011100000100101000100E377");
  s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDU);
  if (strcmp (s, "245540327") || e != 130)
    {
      printf ("Error in mpfr_get_str (38u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDD);
  if (strcmp (s, "245540326") || e != 130)
    {
      printf ("Error in mpfr_get_str (38d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 8942832835564782*2^(-382) ~ .9078555839000000000000000000038*10^(-99) */
  mpfr_set_str_binary (x, "11111110001010111010110000110011100110001010011101110E-382");
  s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDU);
  if (strcmp (s, "9078555840") || e != -99)
    {
      printf ("Error in mpfr_get_str (39u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDD);
  if (strcmp (s, "9078555839") || e != -99)
    {
      printf ("Error in mpfr_get_str (39d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 4471416417782391*2^(-380) ~ .18157111678000000000000000000077*10^(-98) */
  mpfr_set_str_binary (x, "1111111000101011101011000011001110011000101001110111E-380");
  s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDU);
  if (strcmp (s, "18157111679") || e != -98)
    {
      printf ("Error in mpfr_get_str (40u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDD);
  if (strcmp (s, "18157111678") || e != -98)
    {
      printf ("Error in mpfr_get_str (40d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 7225450889282194*2^711 ~ .778380362292999999999999999999971*10^230 */
  mpfr_set_str_binary (x, "11001101010111000001001100001100110010000001010010010E711");
  s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDU);
  if (strcmp (s, "778380362293") || e != 230)
    {
      printf ("Error in mpfr_get_str (41u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDD);
  if (strcmp (s, "778380362292") || e != 230)
    {
      printf ("Error in mpfr_get_str (41d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 3612725444641097*2^713 ~ .1556760724585999999999999999999942*10^231 */
  mpfr_set_str_binary (x, "1100110101011100000100110000110011001000000101001001E713");
  s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDU);
  if (strcmp (s, "1556760724586") || e != 231)
    {
      printf ("Error in mpfr_get_str (42u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDD);
  if (strcmp (s, "1556760724585") || e != 231)
    {
      printf ("Error in mpfr_get_str (42d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 6965949469487146*2^(-248) ~ .15400733123779000000000000000000016*10^(-58) */
  mpfr_set_str_binary (x, "11000101111110111111001111111101001101111000000101010E-248");
  s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDU);
  if (strcmp (s, "15400733123780") || e != -58)
    {
      printf ("Error in mpfr_get_str (43u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDD);
  if (strcmp (s, "15400733123779") || e != -58)
    {
      printf ("Error in mpfr_get_str (43d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 3482974734743573*2^(-244) ~ .12320586499023200000000000000000013*10^(-57) */
  mpfr_set_str_binary (x, "1100010111111011111100111111110100110111100000010101E-244");
  s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDU);
  if (strcmp (s, "123205864990233") || e != -57)
    {
      printf ("Error in mpfr_get_str (44u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDD);
  if (strcmp (s, "123205864990232") || e != -57)
    {
      printf ("Error in mpfr_get_str (44d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 7542952370752766*2^(-919) ~ .170206189963739699999999999999999974*10^(-260) */
  mpfr_set_str_binary (x, "11010110011000100011001110100100111011100110011111110E-919");
  s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDU);
  if (strcmp (s, "1702061899637397") || e != -260)
    {
      printf ("Error in mpfr_get_str (45u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDD);
  if (strcmp (s, "1702061899637396") || e != -260)
    {
      printf ("Error in mpfr_get_str (45d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  /* 5592117679628511*2^165 ~ .26153245263757307000000000000000000074*10^66 */
  mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E165");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDU);
  if (strcmp (s, "26153245263757308") || e != 66)
    {
      printf ("Error in mpfr_get_str (46u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDD);
  if (strcmp (s, "26153245263757307") || e != 66)
    {
      printf ("Error in mpfr_get_str (46d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "11010010110111100001011010000110010000100001011011101E1223");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "10716284017294180") || e != 385)
    {
      printf ("Error in mpfr_get_str (47n): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU);
  if (strcmp (s, "107162840172941805") || e != 385)
    {
      printf ("Error in mpfr_get_str (47u): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDD);
  if (strcmp (s, "107162840172941804") || e != 385)
    {
      printf ("Error in mpfr_get_str (47d): s=%s e=%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_str_binary (x, "11111101111011000001010100001101101000010010001111E122620");
  s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
  if (strcmp (s, "22183435284042374") || e != 36928)
    {
      printf ("Error in mpfr_get_str (48n): s=%s e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU);
  if (strcmp (s, "221834352840423736") || e != 36928)
    {
      printf ("Error in mpfr_get_str (48u): s=%s e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDD);
  if (strcmp (s, "221834352840423735") || e != 36928)
    {
      printf ("Error in mpfr_get_str (48d): s=%s e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 45);
  mpfr_set_str_binary (x, "1E45");
  s = mpfr_get_str (NULL, &e, 32, 9, x, MPFR_RNDN);
  mpfr_free_str (s);

  mpfr_set_prec (x, 7);
  mpfr_set_str_binary (x, "0.1010101E10");
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
  mpfr_free_str (s);

  /* checks rounding of negative numbers */
  mpfr_set_prec (x, 7);
  mpfr_set_str (x, "-11.5", 10, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDD);
  if (strcmp (s, "-12"))
    {
      printf ("Error in mpfr_get_str for x=-11.5 and rnd=MPFR_RNDD\n"
              "got %s instead of -12\n", s);
      exit (1);
  }
  mpfr_free_str (s);

  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
  if (strcmp (s, "-11"))
    {
      printf ("Error in mpfr_get_str for x=-11.5 and rnd=MPFR_RNDU\n");
      exit (1);
    }
  mpfr_free_str (s);

  /* bug found by Jean-Pierre Merlet, produced error in mpfr_get_str */
  mpfr_set_prec (x, 128);
  mpfr_set_str_binary (x, "0.10111001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011010E3");
  s = mpfr_get_str (NULL, &e, 10, 0, x, MPFR_RNDU);
  mpfr_free_str (s);

  mpfr_set_prec (x, 381);
  mpfr_set_str_binary (x, "0.111111111111111111111111111111111111111111111111111111111111111111101110110000100110011101101101001010111000101111000100100011110101010110101110100000010100001000110100000100011111001000010010000010001010111001011110000001110010111101100001111000101101100000010110000101100100000101010110010110001010100111001111100011100101100000100100111001100010010011110011011010110000001000010");
  s = mpfr_get_str (NULL, &e, 10, 0, x, MPFR_RNDD);
  if (e != 0)
    {
      printf ("Error in mpfr_get_str for x=0.999999..., exponent is %d"
              " instead of 0\n", (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 5);
  mpfr_set_str_binary (x, "1101.1"); /* 13.5, or (16)_7 + 1/2 */
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  /* we are in the tie case: both surrounding numbers are (16)_7 and
     (20)_7: since (16)_7 = 13 is odd and (20)_7 = 14 is even,
     we should have s = "20" and e = 2 */
  if (e != 2 || strcmp (s, "20"))
    {
      printf ("Error in mpfr_get_str for x=13.5, base 7\n");
      printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  /* try the same example, with input just below or above 13.5 */
  mpfr_set_prec (x, 1000);
  mpfr_set_str_binary (x, "1101.1");
  mpfr_nextabove (x);
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  if (e != 2 || strcmp (s, "20"))
    {
      printf ("Error in mpfr_get_str for x=13.5+tiny, base 7\n");
      printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "1101.1");
  mpfr_nextbelow (x);
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  if (e != 2 || strcmp (s, "16"))
    {
      printf ("Error in mpfr_get_str for x=13.5-tiny, base 7\n");
      printf ("Expected s=16, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_prec (x, 7);
  mpfr_set_str_binary (x, "110000.1"); /* 48.5, or (66)_7 + 1/2 */
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  /* we are in the tie case: both surrounding numbers are (66)_7 and
     (100)_7: since (66)_7 = 48 is even and (100)_7 is odd,
     we should hase s = "66" and e = 2 */
  if (e != 2 || strcmp (s, "66"))
    {
      printf ("Error in mpfr_get_str for x=48.5, base 7\n");
      printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  /* try the same example, with input just below or above 48.5 */
  mpfr_set_prec (x, 1000);
  mpfr_set_str_binary (x, "110000.1");
  mpfr_nextabove (x);
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  if (e != 3 || strcmp (s, "10"))
    {
      printf ("Error in mpfr_get_str for x=48.5+tiny, base 7\n");
      printf ("Expected s=10, e=3, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_set_str_binary (x, "110000.1");
  mpfr_nextbelow (x);
  s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
  if (e != 2 || strcmp (s, "66"))
    {
      printf ("Error in mpfr_get_str for x=48.5-tiny, base 7\n");
      printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, (long) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_clear (x);
}
Example #14
0
static void
special_overflow (void)
{
  mpfr_t x, y;
  mp_exp_t emin, emax;
  int inex;

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

  set_emin (-125);
  set_emax (128);

  mpfr_init2 (x, 24);
  mpfr_init2 (y, 24);
  mpfr_set_str_binary (x, "0.101100100000000000110100E7");
  mpfr_gamma (y, x, GMP_RNDN);
  if (!mpfr_inf_p (y))
    {
      printf ("Overflow error.\n");
      mpfr_dump (y);
      exit (1);
    }

  /* problem mentioned by Kenneth Wilder, 18 Aug 2005 */
  mpfr_set_prec (x, 29);
  mpfr_set_prec (y, 29);
  mpfr_set_str (x, "-200000000.5", 10, GMP_RNDN); /* exact */
  mpfr_gamma (y, x, GMP_RNDN);
  if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0))
    {
      printf ("Error for gamma(-200000000.5)\n");
      printf ("expected -0");
      printf ("got      ");
      mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);
  mpfr_set_str (x, "-200000000.1", 10, GMP_RNDN);
  mpfr_gamma (y, x, GMP_RNDN);
  if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0))
    {
      printf ("Error for gamma(-200000000.1), prec=53\n");
      printf ("expected -0");
      printf ("got      ");
      mpfr_dump (y);
      exit (1);
    }

  /* another problem mentioned by Kenneth Wilder, 29 Aug 2005 */
  mpfr_set_prec (x, 333);
  mpfr_set_prec (y, 14);
  mpfr_set_str (x, "-2.0000000000000000000000005", 10, GMP_RNDN);
  mpfr_gamma (y, x, GMP_RNDN);
  mpfr_set_prec (x, 14);
  mpfr_set_str_binary (x, "-11010011110001E66");
  if (mpfr_cmp (x, y))
    {
      printf ("Error for gamma(-2.0000000000000000000000005)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }

  /* another tests from Kenneth Wilder, 31 Aug 2005 */
  set_emax (200);
  set_emin (-200);
  mpfr_set_prec (x, 38);
  mpfr_set_prec (y, 54);
  mpfr_set_str_binary (x, "0.11101111011100111101001001010110101001E-166");
  mpfr_gamma (y, x, GMP_RNDN);
  mpfr_set_prec (x, 54);
  mpfr_set_str_binary (x, "0.100010001101100001110110001010111111010000100101011E167");
  if (mpfr_cmp (x, y))
    {
      printf ("Error for gamma (test 1)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }

  set_emax (1000);
  set_emin (-2000);
  mpfr_set_prec (x, 38);
  mpfr_set_prec (y, 71);
  mpfr_set_str_binary (x, "10101011011100001111111000010111110010E-1034");
  /* 184083777010*2^(-1034) */
  mpfr_gamma (y, x, GMP_RNDN);
  mpfr_set_prec (x, 71);
  mpfr_set_str_binary (x, "10111111001000011110010001000000000000110011110000000011101011111111100E926");
  /* 1762885132679550982140*2^926 */
  if (mpfr_cmp (x, y))
    {
      printf ("Error for gamma (test 2)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 38);
  mpfr_set_prec (y, 88);
  mpfr_set_str_binary (x, "10111100111001010000100001100100100101E-104");
  /* 202824096037*2^(-104) */
  mpfr_gamma (y, x, GMP_RNDN);
  mpfr_set_prec (x, 88);
  mpfr_set_str_binary (x, "1010110101111000111010111100010110101010100110111000001011000111000011101100001101110010E-21");
  /* 209715199999500283894743922*2^(-21) */
  if (mpfr_cmp (x, y))
    {
      printf ("Error for gamma (test 3)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }

  mpfr_set_prec (x, 171);
  mpfr_set_prec (y, 38);
  mpfr_set_str (x, "-2993155353253689176481146537402947624254601559176535", 10,
                GMP_RNDN);
  mpfr_div_2exp (x, x, 170, GMP_RNDN);
  mpfr_gamma (y, x, GMP_RNDN);
  mpfr_set_prec (x, 38);
  mpfr_set_str (x, "201948391737", 10, GMP_RNDN);
  mpfr_mul_2exp (x, x, 92, GMP_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Error for gamma (test 5)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }

  set_emin (-500000);
  mpfr_set_prec (x, 337);
  mpfr_set_prec (y, 38);
  mpfr_set_str (x, "-30000.000000000000000000000000000000000000000000001", 10,
                GMP_RNDN);
  mpfr_gamma (y, x, GMP_RNDN);
  mpfr_set_prec (x, 38);
  mpfr_set_str (x, "-3.623795987425E-121243", 10, GMP_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Error for gamma (test 7)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }

  /* was producing infinite loop */
  set_emin (emin);
  mpfr_set_prec (x, 71);
  mpfr_set_prec (y, 71);
  mpfr_set_str (x, "-200000000.1", 10, GMP_RNDN);
  mpfr_gamma (y, x, GMP_RNDN);
  if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0))
    {
      printf ("Error for gamma (test 8)\n");
      printf ("expected "); mpfr_dump (x);
      printf ("got      "); mpfr_dump (y);
      exit (1);
    }

  set_emax (1073741823);
  mpfr_set_prec (x, 29);
  mpfr_set_prec (y, 29);
  mpfr_set_str (x, "423786866", 10, GMP_RNDN);
  mpfr_gamma (y, x, GMP_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for gamma(423786866)\n");
      exit (1);
    }

  /* check exact result */
  mpfr_set_prec (x, 2);
  mpfr_set_ui (x, 3, GMP_RNDN);
  inex = mpfr_gamma (x, x, GMP_RNDN);
  if (inex != 0 || mpfr_cmp_ui (x, 2) != 0)
    {
      printf ("Error for gamma(3)\n");
      exit (1);
    }

  mpfr_set_emax (1024);
  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);
  mpfr_set_str_binary (x, "101010110100110011111010000110001000111100000110101E-43");
  mpfr_gamma (x, x, GMP_RNDU);
  mpfr_set_str_binary (y, "110000011110001000111110110101011110000100001111111E971");
  if (mpfr_cmp (x, y) != 0)
    {
      printf ("Error for gamma(4)\n");
      printf ("expected "); mpfr_dump (y);
      printf ("got      "); mpfr_dump (x);
      exit (1);
    }

  mpfr_clear (y);
  mpfr_clear (x);
  set_emin (emin);
  set_emax (emax);
}
Example #15
0
static void
special ()
{
    mpfr_t x, y, z, t;

    mpfr_init2 (x, 53);
    mpfr_init2 (y, 53);
    mpfr_init2 (z, 53);
    mpfr_init2 (t, 2);

    mpfr_set_ui (x, 2, GMP_RNDN);
    mpfr_pow_si (x, x, -2, GMP_RNDN);
    if (mpfr_cmp_ui_2exp (x, 1, -2))
    {
        printf ("Error in pow_si(x,x,-2) for x=2\n");
        exit (1);
    }
    mpfr_set_ui (x, 2, GMP_RNDN);
    mpfr_set_si (y, -2, GMP_RNDN);
    test_pow (x, x, y, GMP_RNDN);
    if (mpfr_cmp_ui_2exp (x, 1, -2))
    {
        printf ("Error in pow(x,x,y) for x=2, y=-2\n");
        exit (1);
    }

    mpfr_set_prec (x, 2);
    mpfr_set_str_binary (x, "1.0e-1");
    mpfr_set_prec (y, 53);
    mpfr_set_str_binary (y, "0.11010110011100101010110011001010100111000001000101110E-1");
    mpfr_set_prec (z, 2);
    test_pow (z, x, y, GMP_RNDZ);
    mpfr_set_str_binary (x, "1.0e-1");
    if (mpfr_cmp (x, z))
    {
        printf ("Error in mpfr_pow (1)\n");
        exit (1);
    }

    mpfr_set_prec (x, 64);
    mpfr_set_prec (y, 64);
    mpfr_set_prec (z, 64);
    mpfr_set_prec (t, 64);
    mpfr_set_str_binary (x, "0.111011000111100000111010000101010100110011010000011");
    mpfr_set_str_binary (y, "0.111110010100110000011101100011010111000010000100101");
    mpfr_set_str_binary (t, "0.1110110011110110001000110100100001001111010011111000010000011001");

    test_pow (z, x, y, GMP_RNDN);
    if (mpfr_cmp (z, t))
    {
        printf ("Error in mpfr_pow for prec=64, rnd=GMP_RNDN\n");
        exit (1);
    }

    mpfr_set_prec (x, 53);
    mpfr_set_prec (y, 53);
    mpfr_set_prec (z, 53);
    mpfr_set_str (x, "5.68824667828621954868e-01", 10, GMP_RNDN);
    mpfr_set_str (y, "9.03327850535952658895e-01", 10, GMP_RNDN);
    test_pow (z, x, y, GMP_RNDZ);
    if (mpfr_cmp_str1 (z, "0.60071044650456473235"))
    {
        printf ("Error in mpfr_pow for prec=53, rnd=GMP_RNDZ\n");
        exit (1);
    }

    mpfr_set_prec (t, 2);
    mpfr_set_prec (x, 30);
    mpfr_set_prec (y, 30);
    mpfr_set_prec (z, 30);
    mpfr_set_str (x, "1.00000000001010111110001111011e1", 2, GMP_RNDN);
    mpfr_set_str (t, "-0.5", 10, GMP_RNDN);
    test_pow (z, x, t, GMP_RNDN);
    mpfr_set_str (y, "1.01101001111010101110000101111e-1", 2, GMP_RNDN);
    if (mpfr_cmp (z, y))
    {
        printf ("Error in mpfr_pow for prec=30, rnd=GMP_RNDN\n");
        exit (1);
    }

    mpfr_set_prec (x, 21);
    mpfr_set_prec (y, 21);
    mpfr_set_prec (z, 21);
    mpfr_set_str (x, "1.11111100100001100101", 2, GMP_RNDN);
    test_pow (z, x, t, GMP_RNDZ);
    mpfr_set_str (y, "1.01101011010001100000e-1", 2, GMP_RNDN);
    if (mpfr_cmp (z, y))
    {
        printf ("Error in mpfr_pow for prec=21, rnd=GMP_RNDZ\n");
        printf ("Expected ");
        mpfr_out_str (stdout, 2, 0, y, GMP_RNDN);
        printf ("\nGot      ");
        mpfr_out_str (stdout, 2, 0, z, GMP_RNDN);
        printf ("\n");
        exit (1);
    }

    /* From http://www.terra.es/personal9/ismaeljc/hall.htm */
    mpfr_set_prec (x, 113);
    mpfr_set_prec (y, 2);
    mpfr_set_prec (z, 169);
    mpfr_set_str1 (x, "6078673043126084065007902175846955");
    mpfr_set_ui_2exp (y, 3, -1, GMP_RNDN);
    test_pow (z, x, y, GMP_RNDZ);
    if (mpfr_cmp_str1 (z, "473928882491000966028828671876527456070714790264144"))
    {
        printf ("Error in mpfr_pow for 6078673043126084065007902175846955");
        printf ("^(3/2), GMP_RNDZ\nExpected ");
        printf ("4.73928882491000966028828671876527456070714790264144e50");
        printf ("\nGot      ");
        mpfr_out_str (stdout, 10, 0, z, GMP_RNDN);
        printf ("\n");
        exit (1);
    }
    test_pow (z, x, y, GMP_RNDU);
    if (mpfr_cmp_str1 (z, "473928882491000966028828671876527456070714790264145"))
    {
        printf ("Error in mpfr_pow for 6078673043126084065007902175846955");
        printf ("^(3/2), GMP_RNDU\nExpected ");
        printf ("4.73928882491000966028828671876527456070714790264145e50");
        printf ("\nGot      ");
        mpfr_out_str (stdout, 10, 0, z, GMP_RNDN);
        printf ("\n");
        exit (1);
    }

    mpfr_set_inf (x, 1);
    mpfr_set_prec (y, 2);
    mpfr_set_str_binary (y, "1E10");
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
    mpfr_set_inf (x, -1);
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
    mpfr_set_prec (y, 10);
    mpfr_set_str_binary (y, "1.000000001E9");
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_NEG(z));
    mpfr_set_str_binary (y, "1.000000001E8");
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));

    mpfr_set_inf (x, -1);
    mpfr_set_prec (y, 2 * mp_bits_per_limb);
    mpfr_set_ui (y, 1, GMP_RNDN);
    mpfr_mul_2exp (y, y, mp_bits_per_limb - 1, GMP_RNDN);
    /* y = 2^(mp_bits_per_limb - 1) */
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
    mpfr_nextabove (y);
    test_pow (z, x, y, GMP_RNDN);
    /* y = 2^(mp_bits_per_limb - 1) + epsilon */
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
    mpfr_nextbelow (y);
    mpfr_div_2exp (y, y, 1, GMP_RNDN);
    mpfr_nextabove (y);
    test_pow (z, x, y, GMP_RNDN);
    /* y = 2^(mp_bits_per_limb - 2) + epsilon */
    MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));

    mpfr_set_si (x, -1, GMP_RNDN);
    mpfr_set_prec (y, 2);
    mpfr_set_str_binary (y, "1E10");
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN(mpfr_cmp_ui (z, 1) == 0);

    /* Check (-0)^(17.0001) */
    mpfr_set_prec (x, 6);
    mpfr_set_prec (y, 640);
    MPFR_SET_ZERO (x);
    MPFR_SET_NEG (x);
    mpfr_set_ui (y, 17, GMP_RNDN);
    mpfr_nextabove (y);
    test_pow (z, x, y, GMP_RNDN);
    MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));

    mpfr_clear (x);
    mpfr_clear (y);
    mpfr_clear (z);
    mpfr_clear (t);
}
Example #16
0
static void
special (void)
{
  mpfr_t x, y;

  mpfr_init (x);
  mpfr_init (y);

  MPFR_SET_INF(x);
  mpfr_set_ui (y, 1, GMP_RNDN);
  mpfr_acosh (x, y, GMP_RNDN);
  if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) )
    {
      printf ("Inf flag not clears in acosh!\n");
      exit (1);
    }
  if (mpfr_cmp_ui (x, 0))
    {
      printf ("Error: mpfr_acosh(1) <> 0\n");
      exit (1);
    }

  MPFR_SET_NAN(x);
  mpfr_acosh (x, y, GMP_RNDN);
  if (MPFR_IS_NAN(x) || MPFR_IS_INF(x) )
    {
      printf ("NAN flag not clears in acosh!\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, GMP_RNDN);
  mpfr_acosh (y, x, GMP_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error: mpfr_acosh(0) <> NaN\n");
      exit (1);
    }

  mpfr_set_si (x, -1, GMP_RNDN);
  mpfr_acosh (y, x, GMP_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error: mpfr_acosh(-1) <> NaN\n");
      exit (1);
    }

  MPFR_SET_NAN(x);
  mpfr_acosh (y, x, GMP_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error: mpfr_acosh(NaN) <> NaN\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_acosh (y, x, GMP_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error: mpfr_acosh(+Inf) <> +Inf\n");
      exit (1);
    }

  mpfr_set_inf (x, -1);
  mpfr_acosh (y, x, GMP_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error: mpfr_acosh(-Inf) <> NaN\n");
      exit (1);
    }

  mpfr_set_ui (x, 1, GMP_RNDN);
  mpfr_div_2exp (x, x, 1, GMP_RNDN);
  mpfr_acosh (y, x, GMP_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error: mpfr_acosh(1/2) <> NaN\n");
      exit (1);
    }

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 32);
  mpfr_set_str_binary (x, "1.000001101011101111001011");
  mpfr_acosh (y, x, GMP_RNDN);
  mpfr_set_str_binary (x, "0.111010100101101001010001101001E-2");
  if (mpfr_cmp (x, y))
    {
      printf ("Error: mpfr_acosh (1)\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
Example #17
0
File: tatan.c Project: Canar/mpfr
static void
special (void)
{
    mpfr_t x, y, z;
    int r;
    int i;

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

    mpfr_set_str_binary (x, "1.0000100110000001100111100011001110101110100111011101");
    mpfr_set_str_binary (y, "1.1001101101110100101100110011011101101000011010111110e-1");
    mpfr_atan (z, x, MPFR_RNDN);
    if (mpfr_cmp (y, z))
    {
        printf ("Error in mpfr_atan for prec=53, rnd=MPFR_RNDN\n");
        printf ("x=");
        mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
        printf ("\nexpected ");
        mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
        printf ("\ngot      ");
        mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
        printf ("\n");
        exit (1);
    }

    /* atan(+Inf) = Pi/2 */
    for (r = 0; r < MPFR_RND_MAX ; r++)
    {
        mpfr_set_inf (x, 1);
        mpfr_atan (y, x, (mpfr_rnd_t) r);
        mpfr_const_pi (x, (mpfr_rnd_t) r);
        mpfr_div_2exp (x, x, 1, (mpfr_rnd_t) r);
        if (mpfr_cmp (x, y))
        {
            printf ("Error: mpfr_atan(+Inf), rnd=%s\n",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) r));
            exit (1);
        }
    }

    /* atan(-Inf) = - Pi/2 */
    for (r = 0; r < MPFR_RND_MAX ; r++)
    {
        mpfr_set_inf (x, -1);
        mpfr_atan (y, x, (mpfr_rnd_t) r);
        mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r));
        mpfr_neg (x, x, (mpfr_rnd_t) r);
        mpfr_div_2exp (x, x, 1, (mpfr_rnd_t) r);
        if (mpfr_cmp (x, y))
        {
            printf ("Error: mpfr_atan(-Inf), rnd=%s\n",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) r));
            exit (1);
        }
    }

    /* atan(NaN) = NaN */
    mpfr_set_nan (x);
    mpfr_atan (y, x, MPFR_RNDN);
    if (!mpfr_nan_p (y))
    {
        printf ("Error: mpfr_atan(NaN) <> NaN\n");
        exit (1);
    }

    /* atan(+/-0) = +/-0 */
    mpfr_set_ui (x, 0, MPFR_RNDN);
    MPFR_SET_NEG (y);
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
    {
        printf ("Error: mpfr_atan (+0) <> +0\n");
        exit (1);
    }
    mpfr_atan (x, x, MPFR_RNDN);
    if (mpfr_cmp_ui (x, 0) || MPFR_IS_NEG (x))
    {
        printf ("Error: mpfr_atan (+0) <> +0 (in place)\n");
        exit (1);
    }
    mpfr_neg (x, x, MPFR_RNDN);
    MPFR_SET_POS (y);
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 0) || MPFR_IS_POS (y))
    {
        printf ("Error: mpfr_atan (-0) <> -0\n");
        exit (1);
    }
    mpfr_atan (x, x, MPFR_RNDN);
    if (mpfr_cmp_ui (x, 0) || MPFR_IS_POS (x))
    {
        printf ("Error: mpfr_atan (-0) <> -0 (in place)\n");
        exit (1);
    }

    mpfr_set_prec (x, 32);
    mpfr_set_prec (y, 32);

    /* test one random positive argument */
    mpfr_set_str_binary (x, "0.10000100001100101001001001011001");
    mpfr_atan (x, x, MPFR_RNDN);
    mpfr_set_str_binary (y, "0.1111010000001111001111000000011E-1");
    if (mpfr_cmp (x, y))
    {
        printf ("Error in mpfr_atan (1)\n");
        exit (1);
    }

    /* test one random negative argument */
    mpfr_set_str_binary (x, "-0.1100001110110000010101011001011");
    mpfr_atan (x, x, MPFR_RNDN);
    mpfr_set_str_binary (y, "-0.101001110001010010110001110001");
    if (mpfr_cmp (x, y))
    {
        printf ("Error in mpfr_atan (2)\n");
        mpfr_print_binary (x);
        printf ("\n");
        mpfr_print_binary (y);
        printf ("\n");
        exit (1);
    }

    mpfr_set_prec (x, 3);
    mpfr_set_prec (y, 192);
    mpfr_set_prec (z, 192);
    mpfr_set_str_binary (x, "-0.100e1");
    mpfr_atan (z, x, MPFR_RNDD);
    mpfr_set_str_binary (y, "-0.110010010000111111011010101000100010000101101000110000100011010011000100110001100110001010001011100000001101110000011100110100010010100100000010010011100000100010001010011001111100110001110101");
    if (mpfr_cmp (z, y))
    {
        printf ("Error in mpfr_atan (3)\n");
        printf ("Expected ");
        mpfr_print_binary (y);
        printf ("\n");
        printf ("Got      ");
        mpfr_print_binary (z);
        printf ("\n");
        exit (1);
    }

    /* Test regression */
    mpfr_set_prec (x, 51);
    mpfr_set_prec (y, 51);
    mpfr_set_str_binary (x,
                         "0.101100100000101111111010001111111000001000000000000E-11");
    i = mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_str (y,
                      "1.01100100000101111111001110011001010110100100000000e-12", 2, MPFR_RNDN)
            || i >= 0)
    {
        printf ("Wrong Regression test (%d)\n", i);
        mpfr_dump (y);
        exit (1);
    }

    mpfr_set_si (x, -1, MPFR_RNDN);
    mpfr_atan (x, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_NEG (x));

    /* Test regression */
    mpfr_set_prec (x, 48);
    mpfr_set_prec (y, 48);
    mpfr_set_str_binary (x, "1.11001110010000011111100000010000000000000000000e-19");
    mpfr_atan (y, x, MPFR_RNDD);
    if (mpfr_cmp_str (y, "0.111001110010000011111100000001111111110000010011E-18", 2, MPFR_RNDN))
    {
        printf ("Error in mpfr_atan (4)\n");
        printf ("Input    1.11001110010000011111100000010000000000000000000e-19 [prec=48]\n");
        printf ("Expected 0.111001110010000011111100000001111111110000010011E-18\n");
        printf ("Got      ");
        mpfr_dump (y);
        exit (1);
    }

    mpfr_clear (x);
    mpfr_clear (y);
    mpfr_clear (z);
}
Example #18
0
/* Put in z the value of x^y, rounded according to 'rnd'.
   Return the inexact flag in [0, 10]. */
int
mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd)
{
  int ret = -2, loop, x_real, y_real, z_real = 0, z_imag = 0;
  mpc_t t, u;
  mp_prec_t p, q, pr, pi, maxprec;
  long Q;

  x_real = mpfr_zero_p (MPC_IM(x));
  y_real = mpfr_zero_p (MPC_IM(y));

  if (y_real && mpfr_zero_p (MPC_RE(y))) /* case y zero */
    {
      if (x_real && mpfr_zero_p (MPC_RE(x))) /* 0^0 = NaN +i*NaN */
        {
          mpfr_set_nan (MPC_RE(z));
          mpfr_set_nan (MPC_IM(z));
          return 0;
        }
      else /* x^0 = 1 +/- i*0 even for x=NaN see algorithms.tex for the
              sign of zero */
        {
          mpfr_t n;
          int inex, cx1;
          int sign_zi;
          /* cx1 < 0 if |x| < 1
             cx1 = 0 if |x| = 1
             cx1 > 0 if |x| > 1
          */
          mpfr_init (n);
          inex = mpc_norm (n, x, GMP_RNDN);
          cx1 = mpfr_cmp_ui (n, 1);
          if (cx1 == 0 && inex != 0)
            cx1 = -inex;

          sign_zi = (cx1 < 0 && mpfr_signbit (MPC_IM (y)) == 0)
            || (cx1 == 0
                && mpfr_signbit (MPC_IM (x)) != mpfr_signbit (MPC_RE (y)))
            || (cx1 > 0 && mpfr_signbit (MPC_IM (y)));

          /* warning: mpc_set_ui_ui does not set Im(z) to -0 if Im(rnd)=RNDD */
          ret = mpc_set_ui_ui (z, 1, 0, rnd);

          if (MPC_RND_IM (rnd) == GMP_RNDD || sign_zi)
            mpc_conj (z, z, MPC_RNDNN);

          mpfr_clear (n);
          return ret;
        }
    }

  if (mpfr_nan_p (MPC_RE(x)) || mpfr_nan_p (MPC_IM(x)) ||
      mpfr_nan_p (MPC_RE(y)) || mpfr_nan_p (MPC_IM(y)) ||
      mpfr_inf_p (MPC_RE(x)) || mpfr_inf_p (MPC_IM(x)) ||
      mpfr_inf_p (MPC_RE(y)) || mpfr_inf_p (MPC_IM(y)))
    {
      /* special values: exp(y*log(x)) */
      mpc_init2 (u, 2);
      mpc_log (u, x, MPC_RNDNN);
      mpc_mul (u, u, y, MPC_RNDNN);
      ret = mpc_exp (z, u, rnd);
      mpc_clear (u);
      goto end;
    }

  if (x_real) /* case x real */
    {
      if (mpfr_zero_p (MPC_RE(x))) /* x is zero */
        {
          /* special values: exp(y*log(x)) */
          mpc_init2 (u, 2);
          mpc_log (u, x, MPC_RNDNN);
          mpc_mul (u, u, y, MPC_RNDNN);
          ret = mpc_exp (z, u, rnd);
          mpc_clear (u);
          goto end;
        }

      /* Special case 1^y = 1 */
      if (mpfr_cmp_ui (MPC_RE(x), 1) == 0)
        {
          int s1, s2;
          s1 = mpfr_signbit (MPC_RE (y));
          s2 = mpfr_signbit (MPC_IM (x));

          ret = mpc_set_ui (z, +1, rnd);
          /* the sign of the zero imaginary part is known in some cases (see
             algorithm.tex). In such cases we have
             (x +s*0i)^(y+/-0i) = x^y + s*sign(y)*0i
             where s = +/-1.  We extend here this rule to fix the sign of the
             zero part.

             Note that the sign must also be set explicitly when rnd=RNDD
             because mpfr_set_ui(z_i, 0, rnd) always sets z_i to +0.
          */
          if (MPC_RND_IM (rnd) == GMP_RNDD || s1 != s2)
            mpc_conj (z, z, MPC_RNDNN);
          goto end;
        }

      /* x^y is real when:
         (a) x is real and y is integer
         (b) x is real non-negative and y is real */
      if (y_real && (mpfr_integer_p (MPC_RE(y)) ||
                     mpfr_cmp_ui (MPC_RE(x), 0) >= 0))
        {
          int s1, s2;
          s1 = mpfr_signbit (MPC_RE (y));
          s2 = mpfr_signbit (MPC_IM (x));

          ret = mpfr_pow (MPC_RE(z), MPC_RE(x), MPC_RE(y), MPC_RND_RE(rnd));
          ret = MPC_INEX(ret, mpfr_set_ui (MPC_IM(z), 0, MPC_RND_IM(rnd)));

          /* the sign of the zero imaginary part is known in some cases
             (see algorithm.tex). In such cases we have (x +s*0i)^(y+/-0i)
             = x^y + s*sign(y)*0i where s = +/-1.
             We extend here this rule to fix the sign of the zero part.

             Note that the sign must also be set explicitly when rnd=RNDD
             because mpfr_set_ui(z_i, 0, rnd) always sets z_i to +0.
          */
          if (MPC_RND_IM(rnd) == GMP_RNDD || s1 != s2)
            mpfr_neg (MPC_IM(z), MPC_IM(z), MPC_RND_IM(rnd));
          goto end;
        }

      /* (-1)^(n+I*t) is real for n integer and t real */
      if (mpfr_cmp_si (MPC_RE(x), -1) == 0 && mpfr_integer_p (MPC_RE(y)))
        z_real = 1;

      /* for x real, x^y is imaginary when:
         (a) x is negative and y is half-an-integer
         (b) x = -1 and Re(y) is half-an-integer
      */
      if (mpfr_cmp_ui (MPC_RE(x), 0) < 0 && is_odd (MPC_RE(y), 1) &&
          (y_real || mpfr_cmp_si (MPC_RE(x), -1) == 0))
        z_imag = 1;
    }
  else /* x non real */
    /* I^(t*I) and (-I)^(t*I) are real for t real,
       I^(n+t*I) and (-I)^(n+t*I) are real for n even and t real, and
       I^(n+t*I) and (-I)^(n+t*I) are imaginary for n odd and t real
       (s*I)^n is real for n even and imaginary for n odd */
    if ((mpc_cmp_si_si (x, 0, 1) == 0 || mpc_cmp_si_si (x, 0, -1) == 0 ||
         (mpfr_cmp_ui (MPC_RE(x), 0) == 0 && y_real)) &&
        mpfr_integer_p (MPC_RE(y)))
      { /* x is I or -I, and Re(y) is an integer */
        if (is_odd (MPC_RE(y), 0))
          z_imag = 1; /* Re(y) odd: z is imaginary */
        else
          z_real = 1; /* Re(y) even: z is real */
      }
    else /* (t+/-t*I)^(2n) is imaginary for n odd and real for n even */
      if (mpfr_cmpabs (MPC_RE(x), MPC_IM(x)) == 0 && y_real &&
          mpfr_integer_p (MPC_RE(y)) && is_odd (MPC_RE(y), 0) == 0)
        {
          if (is_odd (MPC_RE(y), -1)) /* y/2 is odd */
            z_imag = 1;
          else
            z_real = 1;
        }

  /* first bound |Re(y log(x))|, |Im(y log(x)| < 2^q */
  mpc_init2 (t, 64);
  mpc_log (t, x, MPC_RNDNN);
  mpc_mul (t, t, y, MPC_RNDNN);

  /* the default maximum exponent for MPFR is emax=2^30-1, thus if
     t > log(2^emax) = emax*log(2), then exp(t) will overflow */
  if (mpfr_cmp_ui_2exp (MPC_RE(t), 372130558, 1) > 0)
    goto overflow;

  /* the default minimum exponent for MPFR is emin=-2^30+1, thus the
     smallest representable value is 2^(emin-1), and if
     t < log(2^(emin-1)) = (emin-1)*log(2), then exp(t) will underflow */
  if (mpfr_cmp_si_2exp (MPC_RE(t), -372130558, 1) < 0)
    goto underflow;

  q = mpfr_get_exp (MPC_RE(t)) > 0 ? mpfr_get_exp (MPC_RE(t)) : 0;
  if (mpfr_get_exp (MPC_IM(t)) > (mp_exp_t) q)
    q = mpfr_get_exp (MPC_IM(t));

  pr = mpfr_get_prec (MPC_RE(z));
  pi = mpfr_get_prec (MPC_IM(z));
  p = (pr > pi) ? pr : pi;
  p += 11; /* experimentally, seems to give less than 10% of failures in
              Ziv's strategy */
  mpc_init2 (u, p);
  pr += MPC_RND_RE(rnd) == GMP_RNDN;
  pi += MPC_RND_IM(rnd) == GMP_RNDN;
  maxprec = MPFR_PREC(MPC_RE(z));
  if (MPFR_PREC(MPC_IM(z)) > maxprec)
    maxprec = MPFR_PREC(MPC_IM(z));
  for (loop = 0;; loop++)
    {
      mp_exp_t dr, di;

      if (p + q > 64) /* otherwise we reuse the initial approximation
                         t of y*log(x), avoiding two computations */
        {
          mpc_set_prec (t, p + q);
          mpc_log (t, x, MPC_RNDNN);
          mpc_mul (t, t, y, MPC_RNDNN);
        }
      mpc_exp (u, t, MPC_RNDNN);
      /* Since the error bound is global, we have to take into account the
         exponent difference between the real and imaginary parts. We assume
         either the real or the imaginary part of u is not zero.
      */
      dr = mpfr_zero_p (MPC_RE(u)) ? mpfr_get_exp (MPC_IM(u))
        : mpfr_get_exp (MPC_RE(u));
      di = mpfr_zero_p (MPC_IM(u)) ? dr : mpfr_get_exp (MPC_IM(u));
      if (dr > di)
        {
          di = dr - di;
          dr = 0;
        }
      else
        {
          dr = di - dr;
          di = 0;
        }
      /* the term -3 takes into account the factor 4 in the complex error
         (see algorithms.tex) plus one due to the exponent difference: if
         z = a + I*b, where the relative error on z is at most 2^(-p), and
         EXP(a) = EXP(b) + k, the relative error on b is at most 2^(k-p) */
      if ((z_imag || mpfr_can_round (MPC_RE(u), p - 3 - dr, GMP_RNDN, GMP_RNDZ, pr)) &&
          (z_real || mpfr_can_round (MPC_IM(u), p - 3 - di, GMP_RNDN, GMP_RNDZ, pi)))
        break;

      /* if Re(u) is not known to be zero, assume it is a normal number, i.e.,
         neither zero, Inf or NaN, otherwise we might enter an infinite loop */
      MPC_ASSERT (z_imag || mpfr_number_p (MPC_RE(u)));
      /* idem for Im(u) */
      MPC_ASSERT (z_real || mpfr_number_p (MPC_IM(u)));

      if (ret == -2) /* we did not yet call mpc_pow_exact, or it aborted
                        because intermediate computations had > maxprec bits */
        {
          /* check exact cases (see algorithms.tex) */
          if (y_real)
            {
              maxprec *= 2;
              ret = mpc_pow_exact (z, x, MPC_RE(y), rnd, maxprec);
              if (ret != -1 && ret != -2)
                goto exact;
            }
          p += dr + di + 64;
        }
      else
        p += p / 2;
      mpc_set_prec (t, p + q);
      mpc_set_prec (u, p);
    }

  if (z_real)
    {
      /* When the result is real (see algorithm.tex for details),
         Im(x^y) =
         + sign(imag(y))*0i,               if |x| > 1
         + sign(imag(x))*sign(real(y))*0i, if |x| = 1
         - sign(imag(y))*0i,               if |x| < 1
      */
      mpfr_t n;
      int inex, cx1;
      int sign_zi;
      /* cx1 < 0 if |x| < 1
         cx1 = 0 if |x| = 1
         cx1 > 0 if |x| > 1
      */
      mpfr_init (n);
      inex = mpc_norm (n, x, GMP_RNDN);
      cx1 = mpfr_cmp_ui (n, 1);
      if (cx1 == 0 && inex != 0)
        cx1 = -inex;

      sign_zi = (cx1 < 0 && mpfr_signbit (MPC_IM (y)) == 0)
        || (cx1 == 0
            && mpfr_signbit (MPC_IM (x)) != mpfr_signbit (MPC_RE (y)))
        || (cx1 > 0 && mpfr_signbit (MPC_IM (y)));

      ret = mpfr_set (MPC_RE(z), MPC_RE(u), MPC_RND_RE(rnd));
      /* warning: mpfr_set_ui does not set Im(z) to -0 if Im(rnd) = RNDD */
      ret = MPC_INEX (ret, mpfr_set_ui (MPC_IM (z), 0, MPC_RND_IM (rnd)));

      if (MPC_RND_IM (rnd) == GMP_RNDD || sign_zi)
        mpc_conj (z, z, MPC_RNDNN);

      mpfr_clear (n);
    }
  else if (z_imag)
    {
      ret = mpfr_set (MPC_IM(z), MPC_IM(u), MPC_RND_IM(rnd));
      ret = MPC_INEX(mpfr_set_ui (MPC_RE(z), 0, MPC_RND_RE(rnd)), ret);
    }
  else
    ret = mpc_set (z, u, rnd);
 exact:
  mpc_clear (t);
  mpc_clear (u);

 end:
  return ret;

 underflow:
  /* If we have an underflow, we know that |z| is too small to be
     represented, but depending on arg(z), we should return +/-0 +/- I*0.
     We assume t is the approximation of y*log(x), thus we want
     exp(t) = exp(Re(t))+exp(I*Im(t)).
     FIXME: this part of code is not 100% rigorous, since we don't consider
     rounding errors.
  */
  mpc_init2 (u, 64);
  mpfr_const_pi (MPC_RE(u), GMP_RNDN);
  mpfr_div_2exp (MPC_RE(u), MPC_RE(u), 1, GMP_RNDN); /* Pi/2 */
  mpfr_remquo (MPC_RE(u), &Q, MPC_IM(t), MPC_RE(u), GMP_RNDN);
  if (mpfr_sgn (MPC_RE(u)) < 0)
    Q--; /* corresponds to positive remainder */
  mpfr_set_ui (MPC_RE(z), 0, GMP_RNDN);
  mpfr_set_ui (MPC_IM(z), 0, GMP_RNDN);
  switch (Q & 3)
    {
    case 0: /* first quadrant: round to (+0 +0) */
      ret = MPC_INEX(-1, -1);
      break;
    case 1: /* second quadrant: round to (-0 +0) */
      mpfr_neg (MPC_RE(z), MPC_RE(z), GMP_RNDN);
      ret = MPC_INEX(1, -1);
      break;
    case 2: /* third quadrant: round to (-0 -0) */
      mpfr_neg (MPC_RE(z), MPC_RE(z), GMP_RNDN);
      mpfr_neg (MPC_IM(z), MPC_IM(z), GMP_RNDN);
      ret = MPC_INEX(1, 1);
      break;
    case 3: /* fourth quadrant: round to (+0 -0) */
      mpfr_neg (MPC_IM(z), MPC_IM(z), GMP_RNDN);
      ret = MPC_INEX(-1, 1);
      break;
    }
  goto clear_t_and_u;

 overflow:
  /* If we have an overflow, we know that |z| is too large to be
     represented, but depending on arg(z), we should return +/-Inf +/- I*Inf.
     We assume t is the approximation of y*log(x), thus we want
     exp(t) = exp(Re(t))+exp(I*Im(t)).
     FIXME: this part of code is not 100% rigorous, since we don't consider
     rounding errors.
  */
  mpc_init2 (u, 64);
  mpfr_const_pi (MPC_RE(u), GMP_RNDN);
  mpfr_div_2exp (MPC_RE(u), MPC_RE(u), 1, GMP_RNDN); /* Pi/2 */
  /* the quotient is rounded to the nearest integer in mpfr_remquo */
  mpfr_remquo (MPC_RE(u), &Q, MPC_IM(t), MPC_RE(u), GMP_RNDN);
  if (mpfr_sgn (MPC_RE(u)) < 0)
    Q--; /* corresponds to positive remainder */
  switch (Q & 3)
    {
    case 0: /* first quadrant */
      mpfr_set_inf (MPC_RE(z), 1);
      mpfr_set_inf (MPC_IM(z), 1);
      ret = MPC_INEX(1, 1);
      break;
    case 1: /* second quadrant */
      mpfr_set_inf (MPC_RE(z), -1);
      mpfr_set_inf (MPC_IM(z), 1);
      ret = MPC_INEX(-1, 1);
      break;
    case 2: /* third quadrant */
      mpfr_set_inf (MPC_RE(z), -1);
      mpfr_set_inf (MPC_IM(z), -1);
      ret = MPC_INEX(-1, -1);
      break;
    case 3: /* fourth quadrant */
      mpfr_set_inf (MPC_RE(z), 1);
      mpfr_set_inf (MPC_IM(z), -1);
      ret = MPC_INEX(1, -1);
      break;
    }

 clear_t_and_u:
  mpc_clear (t);
  mpc_clear (u);
  return ret;
}
Example #19
0
int
mpfi_blow (mpfi_ptr y, mpfi_srcptr x, double fact)
/* if c = mid (x) and r = rad (x), y = [c - (1+fact)*r , c + (1+fact)*r] */
{
  mp_prec_t prec;
  mpfr_t radius, factor;
  mpfr_t centre;
  int inex_diam, inex_div, inex_conv, inex_factor, inex_rad;
  int inex_centre, inex_left, inex_right;
  int inexact = 0;

  if (MPFI_NAN_P (x)) {
    mpfr_set_nan (&(y->left));
    mpfr_set_nan (&(y->right));
    MPFR_RET_NAN;
  }

  prec = mpfi_get_prec (x);
  mpfr_init2 (radius, prec);
  mpfr_init2 (factor, prec);
  mpfr_init2 (centre, prec);

  inex_diam = mpfi_diam_abs (radius, x);
  if (mpfr_zero_p (radius)) {
    /* x is a singleton */
    return mpfi_set (y, x);
  }
  inex_div = mpfr_div_2exp (radius, radius, 1, MPFI_RNDU); /* either underflow
                                                             or exact*/

  /* factor must be greater than 1 + |fact|, so it is not possible to perform
     this addition directly in C with the double precision since the usual
     rouding mode is rounding to nearest. */
  inex_conv = mpfr_set_d (factor, fact < 0.0 ? -fact : fact, MPFI_RNDU);
  inex_factor = mpfr_add_ui (factor, factor, 1, MPFI_RNDU);

  inex_rad = mpfr_mul (radius, radius, factor, MPFI_RNDU);
  inex_centre = mpfi_mid (centre, x);
  inex_left = mpfr_sub (&(y->left), centre, radius, MPFI_RNDD);
  inex_right = mpfr_add (&(y->right), centre, radius, MPFI_RNDU);

  mpfr_clear (radius);
  mpfr_clear (factor);
  mpfr_clear (centre);

  if ( MPFI_NAN_P (y) )
    MPFR_RET_NAN;

  /* do not allow -0 as lower bound */
  if (mpfr_zero_p (&(y->left)) && mpfr_signbit (&(y->left))) {
    mpfr_neg (&(y->left), &(y->left), MPFI_RNDU);
  }
  /* do not allow +0 as upper bound */
  if (mpfr_zero_p (&(y->right)) && !mpfr_signbit (&(y->right))) {
    mpfr_neg (&(y->right), &(y->right), MPFI_RNDD);
  }

  if (inex_diam || inex_div || inex_conv || inex_factor || inex_rad
      || inex_centre || inex_left)
    inexact += 1;
  if (inex_diam || inex_div || inex_conv || inex_factor || inex_rad
      || inex_centre || inex_right)
    inexact += 2;

  return inexact;
}
Example #20
0
static void
check_nan (void)
{
  mpfr_t  a, d, q;
  mp_exp_t emax, emin;

  mpfr_init2 (a, 100L);
  mpfr_init2 (d, 100L);
  mpfr_init2 (q, 100L);

  /* 1/nan == nan */
  mpfr_set_ui (a, 1L, GMP_RNDN);
  MPFR_SET_NAN (d);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_nan_p (q));

  /* nan/1 == nan */
  MPFR_SET_NAN (a);
  mpfr_set_ui (d, 1L, GMP_RNDN);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_nan_p (q));

  /* +inf/1 == +inf */
  MPFR_CLEAR_FLAGS (a);
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  mpfr_set_ui (d, 1L, GMP_RNDN);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) > 0);

  /* 1/+inf == 0 */
  mpfr_set_ui (a, 1L, GMP_RNDN);
  MPFR_CLEAR_FLAGS (d);
  MPFR_SET_INF (d);
  MPFR_SET_POS (d);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_number_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) == 0);

  /* 0/0 == nan */
  mpfr_set_ui (a, 0L, GMP_RNDN);
  mpfr_set_ui (d, 0L, GMP_RNDN);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_nan_p (q));

  /* +inf/+inf == nan */
  MPFR_CLEAR_FLAGS (a);
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  MPFR_CLEAR_FLAGS (d);
  MPFR_SET_INF (d);
  MPFR_SET_POS (d);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_nan_p (q));

  /* 1/+0 = +Inf */
  mpfr_set_ui (a, 1, GMP_RNDZ);
  mpfr_set_ui (d, 0, GMP_RNDZ);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);

  /* 1/-0 = -Inf */
  mpfr_set_ui (a, 1, GMP_RNDZ);
  mpfr_set_ui (d, 0, GMP_RNDZ);
  mpfr_neg (d, d, GMP_RNDZ);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);

  /* -1/+0 = -Inf */
  mpfr_set_si (a, -1, GMP_RNDZ);
  mpfr_set_ui (d, 0, GMP_RNDZ);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);

  /* -1/-0 = +Inf */
  mpfr_set_si (a, -1, GMP_RNDZ);
  mpfr_set_ui (d, 0, GMP_RNDZ);
  mpfr_neg (d, d, GMP_RNDZ);
  MPFR_ASSERTN (test_div (q, a, d, GMP_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);

  /* check overflow */
  emax = mpfr_get_emax ();
  set_emax (1);
  mpfr_set_ui (a, 1, GMP_RNDZ);
  mpfr_set_ui (d, 1, GMP_RNDZ);
  mpfr_div_2exp (d, d, 1, GMP_RNDZ);
  test_div (q, a, d, GMP_RNDU); /* 1 / 0.5 = 2 -> overflow */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  set_emax (emax);

  /* check underflow */
  emin = mpfr_get_emin ();
  set_emin (-1);
  mpfr_set_ui (a, 1, GMP_RNDZ);
  mpfr_div_2exp (a, a, 2, GMP_RNDZ);
  mpfr_set_ui (d, 2, GMP_RNDZ);
  test_div (q, a, d, GMP_RNDZ); /* 0.5*2^(-2) -> underflow */
  MPFR_ASSERTN (mpfr_cmp_ui (q, 0) == 0 && MPFR_IS_POS (q));
  test_div (q, a, d, GMP_RNDN); /* 0.5*2^(-2) -> underflow */
  MPFR_ASSERTN (mpfr_cmp_ui (q, 0) == 0 && MPFR_IS_POS (q));
  set_emin (emin);

  mpfr_clear (a);
  mpfr_clear (d);
  mpfr_clear (q);
}
Example #21
0
/* Test that there is no lost of accuracy when converting a mpfr_t number
   into a mpf_t number (test with various precisions and exponents). */
static void
prec_test (void)
{
  int px, py;

  for (py = 3; py <= 136; py++)
    {
      mpfr_t y1, y2, y3;

      mpfr_init2 (y1, py);
      mpfr_init2 (y2, py);
      mpfr_init2 (y3, py);

      for (px = 32; px <= 160; px += 32)
        {
          mpf_t x1, x2, x3;
          int e;

          mpf_init (x1);
          mpf_init (x2);
          mpf_init (x3);
          mpfr_set_ui_2exp (y1, 1, py - 1, MPFR_RNDN);
          mpfr_get_f (x1, y1, MPFR_RNDN);  /* exact (power of 2) */
          mpf_set (x2, x1);
          mpfr_set (y2, y1, MPFR_RNDN);

          for (e = py - 2; e >= 0; e--)
            {
              int inex;
              mpf_div_2exp (x2, x2, 1);
              mpf_add (x1, x1, x2);
              mpfr_div_2exp (y2, y2, 1, MPFR_RNDN);
              inex = mpfr_add (y1, y1, y2, MPFR_RNDN);
              MPFR_ASSERTN (inex == 0);
              mpfr_set_f (y3, x1, MPFR_RNDN);
              if (! mpfr_equal_p (y1, y3))
                break;
              inex = mpfr_get_f (x3, y3, MPFR_RNDN);
              if (mpf_cmp (x1, x3) != 0)
                {
                  printf ("Error in prec_test (px = %d, py = %d, e = %d)\n",
                          px, py, e);
                  printf ("x1 = ");
                  mpf_out_str (stdout, 16, 0, x1);
                  printf ("\nx2 = ");
                  mpf_out_str (stdout, 16, 0, x2);
                  printf ("\n");
                  exit (1);
                }
              if (inex != 0)
                {
                  printf ("Error in prec_test (px = %d, py = %d, e = %d)\n",
                          px, py, e);
                  printf ("wrong ternary value got: %+d, expected: 0\n",
                          inex);
                  exit (1);
                }
            }

          mpf_clear (x1);
          mpf_clear (x2);
          mpf_clear (x3);
        }

      mpfr_clear (y1);
      mpfr_clear (y2);
      mpfr_clear (y3);
    }
}
Example #22
0
int
main (void)
{
  mpf_t x;
  mpfr_t y, z;
  unsigned long i;
  mpfr_exp_t e;
  int inex;

  tests_start_mpfr ();

  mpfr_init (y);
  mpfr_init (z);
  mpf_init (x);

  i = 1;
  while (i)
    {
      mpfr_set_ui (y, i, MPFR_RNDN);
      if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_ui (x, i))
        {
          printf ("Error: mpfr_get_f(%lu) fails\n", i);
          exit (1);
        }
      if (i <= - (unsigned long) LONG_MIN)
        {
          long j = i < - (unsigned long) LONG_MIN ? - (long) i : LONG_MIN;
          mpfr_set_si (y, j, MPFR_RNDN);
          if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_si (x, j))
            {
              printf ("Error: mpfr_get_f(-%lu) fails\n", i);
              exit (1);
            }
        }
      i *= 2;
    }

  /* same tests, but with a larger precision for y, which requires to
     round it */
  mpfr_set_prec (y, 100);
  i = 1;
  while (i)
    {
      mpfr_set_ui (y, i, MPFR_RNDN);
      inex = mpfr_get_f (x, y, MPFR_RNDN);
      if (! SAME_SIGN (inex, - mpfr_cmp_f (y, x)) || mpf_cmp_ui (x, i))
        {
          printf ("Error: mpfr_get_f(%lu) fails\n", i);
          exit (1);
        }
      mpfr_set_si (y, (signed long) -i, MPFR_RNDN);
      inex = mpfr_get_f (x, y, MPFR_RNDN);
      if (! SAME_SIGN (inex, - mpfr_cmp_f (y, x))
          || mpf_cmp_si (x, (signed long) -i))
        {
          printf ("Error: mpfr_get_f(-%lu) fails\n", i);
          exit (1);
        }
      i *= 2;
    }

  /* bug reported by Jim White */
  for (e = 0; e <= 2 * GMP_NUMB_BITS; e++)
    {
      /* test with 2^(-e) */
      mpfr_set_ui (y, 1, MPFR_RNDN);
      mpfr_div_2exp (y, y, e, MPFR_RNDN);
      inex = mpfr_get_f (x, y, MPFR_RNDN);
      mpf_mul_2exp (x, x, e);
      if (inex != 0 || mpf_cmp_ui (x, 1) != 0)
        {
          printf ("Error: mpfr_get_f(x,y,MPFR_RNDN) fails\n");
          printf ("y=");
          mpfr_dump (y);
          printf ("x=");
          mpf_div_2exp (x, x, e);
          mpf_out_str (stdout, 2, 0, x);
          exit (1);
        }

      /* test with 2^(e) */
      mpfr_set_ui (y, 1, MPFR_RNDN);
      mpfr_mul_2exp (y, y, e, MPFR_RNDN);
      inex = mpfr_get_f (x, y, MPFR_RNDN);
      mpf_div_2exp (x, x, e);
      if (inex != 0 || mpf_cmp_ui (x, 1) != 0)
        {
          printf ("Error: mpfr_get_f(x,y,MPFR_RNDN) fails\n");
          printf ("y=");
          mpfr_dump (y);
          printf ("x=");
          mpf_mul_2exp (x, x, e);
          mpf_out_str (stdout, 2, 0, x);
          exit (1);
        }
    }

  /* Bug reported by Yury Lukach on 2006-04-05 */
  mpfr_set_prec (y, 32);
  mpfr_set_prec (z, 32);
  mpf_set_prec (x, 32);
  mpfr_set_ui_2exp (y, 0xc1234567, -30, MPFR_RNDN);
  mpfr_get_f (x, y, MPFR_RNDN);
  inex = mpfr_set_f (z, x, MPFR_RNDN);
  if (inex != 0 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in mpfr_get_f:\n  inex = %d, y = ", inex);
      mpfr_dump (z);
      printf ("Expected:\n  inex = 0, y = ");
      mpfr_dump (y);
      exit (1);
    }

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

  special_test ();
  prec_test ();
  ternary_test ();

  tests_end_mpfr ();
  return 0;
}
static void
check_inexact (void)
{
  mpfr_t x, y, z, u;
  mpfr_prec_t px, py, pu, pz;
  int inexact, cmp;
  mpfr_rnd_t rnd;

  mpfr_init (x);
  mpfr_init (y);
  mpfr_init (z);
  mpfr_init (u);

  mpfr_set_prec (x, 2);
  mpfr_set_ui (x, 6, MPFR_RNDN);
  mpfr_div_2exp (x, x, 4, MPFR_RNDN); /* x = 6/16 */
  mpfr_set_prec (y, 2);
  mpfr_set_si (y, -1, MPFR_RNDN);
  mpfr_div_2exp (y, y, 4, MPFR_RNDN); /* y = -1/16 */
  inexact = test_sub (y, y, x, MPFR_RNDN); /* y = round(-7/16) = -1/2 */
  if (inexact >= 0)
    {
      printf ("Error: wrong inexact flag for -1/16 - (6/16)\n");
      exit (1);
    }

  for (px=2; px<MAX_PREC; px++)
    {
      mpfr_set_prec (x, px);
      do
        {
          mpfr_urandomb (x, RANDS);
        }
      while (mpfr_cmp_ui (x, 0) == 0);
      for (pu=2; pu<MAX_PREC; pu++)
        {
          mpfr_set_prec (u, pu);
          do
            {
              mpfr_urandomb (u, RANDS);
            }
          while (mpfr_cmp_ui (u, 0) == 0);
          {
              py = 2 + (randlimb () % (MAX_PREC - 2));
              mpfr_set_prec (y, py);
              /* warning: MPFR_EXP is undefined for 0 */
              pz =  (mpfr_cmpabs (x, u) >= 0) ? MPFR_EXP(x) - MPFR_EXP(u)
                : MPFR_EXP(u) - MPFR_EXP(x);
              pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u));
              mpfr_set_prec (z, pz);
              rnd = RND_RAND ();
              if (test_sub (z, x, u, rnd))
                {
                  printf ("z <- x - u should be exact\n");
                  exit (1);
                }
                {
                  rnd = RND_RAND ();
                  inexact = test_sub (y, x, u, rnd);
                  cmp = mpfr_cmp (y, z);
                  if (((inexact == 0) && (cmp != 0)) ||
                      ((inexact > 0) && (cmp <= 0)) ||
                      ((inexact < 0) && (cmp >= 0)))
                    {
                      printf ("Wrong inexact flag for rnd=%s\n",
                              mpfr_print_rnd_mode(rnd));
                      printf ("expected %d, got %d\n", cmp, inexact);
                      printf ("x="); mpfr_print_binary (x); puts ("");
                      printf ("u="); mpfr_print_binary (u); puts ("");
                      printf ("y=  "); mpfr_print_binary (y); puts ("");
                      printf ("x-u="); mpfr_print_binary (z); puts ("");
                      exit (1);
                    }
                }
            }
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (u);
}
Example #24
0
/* bugs found by Alain Delplanque */
static void
check_large (void)
{
  mpfr_t x;
  char *s, s1[7];
  const char xm[] = { '1', '1', '9', '1', '3', '2', '9', '3', '7', '3',
                      '5', '8', '4', '4', '5', '4', '9', '0', '2', '9',
                      '6', '3', '4', '4', '6', '9', '9', '1', '9', '5',
                      '5', '7', '2', '0', '1', '7', '5', '2', '8', '6',
                      '1', '2', '5', '2', '5', '2', '7', '4', '0', '2',
                      '7', '9', '1', '1', '7', '4', '5', '6', '7', '5',
                      '9', '3', '1', '4', '2', '5', '5', '6', '6', '6',
                      '1', '6', '4', '3', '8', '1', '2', '8', '7', '6',
                      '2', '9', '2', '0', '8', '8', '9', '4', '3', '9',
                      '6', '2', '8', '4', '1', '1', '8', '1', '0', '6',
                      '2', '3', '7', '6', '3', '8', '1', '5', '1', '7',
                      '3', '4', '6', '1', '2', '4', '0', '1', '3', '0',
                      '8', '4', '1', '3', '9', '3', '2', '0', '1', '6',
                      '3', '6', '7', '1', '5', '1', '7', '5', '0', '1',
                      '9', '8', '4', '0', '8', '2', '7', '9', '1', '3',
                      '2', '2', '8', '3', '4', '1', '6', '2', '3', '9',
                      '6', '2', '0', '7', '3', '5', '5', '5', '3', '4',
                      '2', '1', '7', '0', '9', '7', '6', '2', '1', '0',
                      '3', '3', '5', '4', '7', '6', '0', '9', '7', '6',
                      '9', '3', '5', '1', '7', '8', '6', '8', '8', '2',
                      '8', '1', '4', '3', '7', '4', '3', '3', '2', '4',
                      '1', '5', '4', '7', '8', '1', '1', '4', '2', '1',
                      '2', '4', '2', '7', '6', '5', '9', '5', '4', '5',
                      '2', '6', '7', '3', '0', '3', '4', '0', '6', '9',
                      '1', '8', '9', '9', '9', '8', '0', '5', '7', '0',
                      '9', '3', '8', '7', '6', '2', '4', '6', '1', '6',
                      '7', '2', '0', '3', '5', '9', '3', '5', '8', '8',
                      '9', '7', '7', '9', '2', '7', '0', '8', '1', '6',
                      '8', '7', '4', '8', '5', '3', '0', '8', '4', '3',
                      '5', '6', '5', '1', '6', '6', '0', '9', '7', '9',
                      '8', '9', '2', '7', '2', '6', '8', '5', '9', '4',
                      '5', '8', '1', '3', '7', '2', '9', '3', '8', '3',
                      '7', '9', '1', '7', '9', '9', '7', '7', '2', '8',
                      '4', '6', '5', '5', '7', '3', '3', '8', '3', '6',
                      '6', '9', '7', '1', '4', '3', '3', '7', '1', '4',
                      '9', '4', '1', '2', '4', '9', '5', '1', '4', '7',
                      '2', '6', '4', '4', '8', '0', '6', '2', '6', '0',
                      '6', '9', '8', '1', '1', '7', '9', '9', '3', '9',
                      '3', '8', '4', '7', '3', '1', '9', '0', '2', '3',
                      '5', '3', '5', '4', '2', '1', '1', '7', '6', '7',
                      '4', '3', '2', '2', '0', '6', '5', '9', '9', '3',
                      '2', '6', '7', '1', '2', '0', '0', '3', '7', '3',
                      '8', '7', '4', '3', '3', '3', '3', '3', '2', '3',
                      '8', '2', '8', '6', '3', '1', '5', '5', '2', '2',
                      '5', '9', '3', '3', '7', '0', '6', '2', '8', '1',
                      '0', '3', '6', '7', '6', '9', '6', '5', '9', '0',
                      '6', '6', '6', '3', '6', '9', '9', '3', '8', '7',
                      '6', '5', '4', '5', '3', '5', '9', '4', '0', '0',
                      '7', '5', '8', '5', '4', '1', '4', '3', '1', '5',
                      '7', '6', '6', '3', '4', '4', '5', '0', '8', '7',
                      '5', '7', '5', '0', '1', '0', '1', '8', '4', '7',
                      '3', '1', '9', '9', '2', '7', '1', '1', '1', '2',
                      '3', '9', '9', '6', '5', '9', '2', '3', '2', '8',
                      '1', '5', '5', '1', '2', '6', '4', '9', '6', '6',
                      '4', '5', '1', '1', '6', '0', '0', '3', '2', '8',
                      '4', '8', '7', '1', '4', '9', '6', '8', '1', '6',
                      '5', '9', '8', '3', '4', '2', '9', '7', '0', '1',
                      '9', '2', '6', '6', '9', '1', '3', '5', '9', '3',
                      '2', '9', '6', '2', '3', '0', '6', '0', '1', '1',
                      '6', '5', '1', '7', '9', '0', '7', '5', '8', '6',
                      '8', '4', '2', '1', '0', '3', '8', '6', '6', '4',
                      '4', '9', '9', '7', '5', '8', '1', '7', '5', '7',
                      '9', '6', '6', '8', '8', '5', '8', '6', '7', '4',
                      '0', '7', '2', '0', '2', '9', '9', '4', '4', '1',
                      '9', '5', '8', '6', '5', '0', '6', '7', '4', '2',
                      '7', '3', '2', '3', '2', '7', '0', '2', '1', '3',
                      '0', '5', '9', '0', '3', '9', '1', '4', '5', '3',
                      '7', '2', '7', '0', '8', '5', '5', '4', '6', '1',
                      '1', '0', '0', '9', '2', '0', '4', '1', '6', '6',
                      '4', '6', '9', '1', '3', '2', '8', '5', '0', '3',
                      '3', '8', '9', '8', '7', '8', '5', '9', '5', '5',
                      '9', '1', '9', '3', '6', '5', '4', '1', '7', '4',
                      '0', '2', '4', '7', '2', '9', '7', '1', '2', '4',
                      '5', '8', '1', '4', '4', '6', '1', '8', '5', '8',
                      '7', '6', '9', '7', '2', '1', '2', '0', '8', '9',
                      '5', '9', '5', '5', '3', '8', '1', '2', '5', '4',
                      '3', '0', '7', '6', '5', '1', '7', '8', '2', '0',
                      '0', '7', '6', '7', '4', '8', '1', '0', '6', '3',
                      '2', '3', '0', '5', '2', '5', '0', '1', '1', '4',
                      '3', '8', '4', '5', '2', '3', '9', '5', '0', '9',
                      '8', '2', '6', '4', '7', '4', '8', '0', '1', '1',
                      '7', '1', '5', '4', '9', '0', '9', '2', '2', '3',
                      '8', '1', '6', '9', '0', '4', '6', '4', '5', '4',
                      '6', '3', '8', '7', '3', '6', '1', '7', '2', '3',
                      '4', '5', '5', '2', '0', '2', '5', '8', '1', '4',
                      '9', '3', '0', '7', '4', '1', '6', '8', '7', '8',
                      '2', '6', '2', '5', '1', '0', '7', '4', '7', '3',
                      '6', '6', '4', '5', '6', '6', '6', '6', '8', '5',
                      '1', '3', '5', '7', '1', '6', '2', '0', '9', '2',
                      '3', '2', '6', '0', '7', '9', '8', '1', '6', '2',
                      '0', '3', '8', '8', '0', '2', '8', '7', '7', '5',
                      '9', '3', '1', '0', '6', '7', '5', '7', '3', '1',
                      '2', '7', '7', '2', '0', '0', '4', '1', '2', '8',
                      '2', '0', '8', '4', '0', '5', '0', '5', '0', '1',
                      '9', '3', '3', '6', '3', '6', '9', '6', '2', '8',
                      '2', '9', '7', '5', '3', '8', '8', '9', '1', '1',
                      '4', '5', '7', '7', '5', '6', '0', '2', '7', '9',
                      '7', '2', '1', '7', '4', '3', '0', '3', '6', '7',
                      '3', '7', '2', '2', '7', '5', '6', '2', '3', '1',
                      '2', '1', '3', '1', '4', '2', '6', '9', '2', '3',
                      '\0' };
  mpfr_exp_t e;

  mpfr_init2 (x, 3322);
  mpfr_set_str (x, xm, 10, MPFR_RNDN);
  mpfr_div_2exp (x, x, 4343, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN);
  if (s[999] != '1') /* s must be 5.04383...689071e-309 */
    {
      printf ("Error in check_large: expected '689071', got '%s'\n",
              s + 994);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_mul_2exp (x, x, 4343, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN);
  if (strcmp (s, "12") || (e != 1000))
    {
      printf ("Error in check_large: expected 0.12e1000\n");
      printf ("got %se%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_set_nan (x);
  mpfr_clear_flags ();
  s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN);
  if (strcmp (s, "@NaN@"))
    {
      printf ("Error for NaN (incorrect string)\n");
      exit (1);
    }
  if (__gmpfr_flags != MPFR_FLAGS_NAN)
    {
      printf ("Error for NaN (incorrect flags)\n");
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_get_str (s1, &e, 10, 1000, x, MPFR_RNDN);

  mpfr_set_inf (x, 1);
  s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN);
  if (strcmp (s, "@Inf@"))
    {
      printf ("Error for Inf\n");
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_get_str (s1, &e, 10, 1000, x, MPFR_RNDN);

  mpfr_set_inf (x, -1);
  s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN);
  if (strcmp (s, "-@Inf@"))
    {
      printf ("Error for -Inf\n");
      exit (1);
    }
  mpfr_free_str (s);

  mpfr_get_str (s1, &e, 10, 1000, x, MPFR_RNDN);

  mpfr_set_ui (x, 0, MPFR_RNDN);
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN);
  if (e != 0 || strcmp (s, "00"))
    {
      printf ("Error for 0.0\n");
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_get_str (s1, &e, 10, 2, x, MPFR_RNDN);

  mpfr_neg (x, x, MPFR_RNDN); /* -0.0 */
  s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN);
  if (e != 0 || strcmp (s, "-00"))
    {
      printf ("Error for -0.0\ngot %se%d\n", s, (int) e);
      exit (1);
    }
  mpfr_free_str (s);
  mpfr_get_str (s1, &e, 10, 2, x, MPFR_RNDN);

  mpfr_clear (x);
}
static void
check_diverse (void)
{
  mpfr_t x, y, z;
  int inexact;

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

  /* check corner case cancel=0, but add_exp=1 */
  mpfr_set_prec (x, 2);
  mpfr_set_prec (y, 4);
  mpfr_set_prec (z, 2);
  mpfr_setmax (y, __gmpfr_emax);
  mpfr_set_str_binary (z, "0.1E-10"); /* tiny */
  test_sub (x, y, z, MPFR_RNDN); /* should round to 2^emax, i.e. overflow */
  if (!mpfr_inf_p (x) || mpfr_sgn (x) < 0)
    {
      printf ("Error in mpfr_sub(a,b,c,RNDN) for b=maxfloat, prec(a)<prec(b), c tiny\n");
      exit (1);
    }

  /* other coverage test */
  mpfr_set_prec (x, 2);
  mpfr_set_prec (y, 2);
  mpfr_set_prec (z, 2);
  mpfr_set_ui (y, 1, MPFR_RNDN);
  mpfr_set_si (z, -2, MPFR_RNDN);
  test_sub (x, y, z, MPFR_RNDD);
  if (mpfr_cmp_ui (x, 3))
    {
      printf ("Error in mpfr_sub(1,-2,RNDD)\n");
      exit (1);
    }

  mpfr_set_prec (x, 288);
  mpfr_set_prec (y, 288);
  mpfr_set_prec (z, 288);
  mpfr_set_str_binary (y, "0.111000110011000001000111101010111011110011101001101111111110000011100101000001001010110010101010011001010100000001110011110001010101101010001011101110100100001011110100110000101101100011010001001011011010101010000010001101001000110010010111111011110001111101001000101101001100101100101000E80");
  mpfr_set_str_binary (z, "0.100001111111101001011010001100110010100111001110000110011101001011010100001000000100111011010110110010000000000010101101011000010000110001110010100001100101011100100100001011000100011110000001010101000100011101001000010111100000111000111011001000100100011000100000010010111000000100100111E-258");
  inexact = test_sub (x, y, z, MPFR_RNDN);
  if (inexact <= 0)
    {
      printf ("Wrong inexact flag for prec=288\n");
      exit (1);
    }

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 63);
  mpfr_set_prec (z, 63);
  mpfr_set_str_binary (x, "0.101101111011011100100100100111E31");
  mpfr_set_str_binary (y, "0.111110010010100100110101101010001001100101110001000101110111111E-1");
  test_sub (z, x, y, MPFR_RNDN);
  mpfr_set_str_binary (y, "0.1011011110110111001001001001101100000110110101101100101001011E31");
  if (mpfr_cmp (z, y))
    {
      printf ("Error in mpfr_sub (5)\n");
      printf ("expected "); mpfr_print_binary (y); puts ("");
      printf ("got      "); mpfr_print_binary (z); puts ("");
      exit (1);
    }

  mpfr_set_prec (y, 63);
  mpfr_set_prec (z, 63);
  mpfr_set_str_binary (y, "0.1011011110110111001001001001101100000110110101101100101001011E31");
  mpfr_sub_ui (z, y, 1541116494, MPFR_RNDN);
  mpfr_set_str_binary (y, "-0.11111001001010010011010110101E-1");
  if (mpfr_cmp (z, y))
    {
      printf ("Error in mpfr_sub (7)\n");
      printf ("expected "); mpfr_print_binary (y); puts ("");
      printf ("got      "); mpfr_print_binary (z); puts ("");
      exit (1);
    }

  mpfr_set_prec (y, 63);
  mpfr_set_prec (z, 63);
  mpfr_set_str_binary (y, "0.1011011110110111001001001001101100000110110101101100101001011E31");
  mpfr_sub_ui (z, y, 1541116494, MPFR_RNDN);
  mpfr_set_str_binary (y, "-0.11111001001010010011010110101E-1");
  if (mpfr_cmp (z, y))
    {
      printf ("Error in mpfr_sub (6)\n");
      printf ("expected "); mpfr_print_binary (y); puts ("");
      printf ("got      "); mpfr_print_binary (z); puts ("");
      exit (1);
    }

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 32);
  mpfr_set_str_binary (x, "0.10110111101001110100100101111000E0");
  mpfr_set_str_binary (y, "0.10001100100101000100110111000100E0");
  if ((inexact = test_sub (x, x, y, MPFR_RNDN)))
    {
      printf ("Wrong inexact flag (2): got %d instead of 0\n", inexact);
      exit (1);
    }

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 32);
  mpfr_set_str_binary (x, "0.11111000110111011000100111011010E0");
  mpfr_set_str_binary (y, "0.10011111101111000100001000000000E-3");
  if ((inexact = test_sub (x, x, y, MPFR_RNDN)))
    {
      printf ("Wrong inexact flag (1): got %d instead of 0\n", inexact);
      exit (1);
    }

  mpfr_set_prec (x, 33);
  mpfr_set_prec (y, 33);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_set_str_binary (y, "-0.1E-32");
  mpfr_add (x, x, y, MPFR_RNDN);
  mpfr_set_str_binary (y, "0.111111111111111111111111111111111E0");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_sub (1 - 1E-33) with prec=33\n");
      printf ("Expected "); mpfr_print_binary (y); puts ("");
      printf ("got      "); mpfr_print_binary (x); puts ("");
      exit (1);
    }

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 33);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_set_str_binary (y, "-0.1E-32");
  mpfr_add (x, x, y, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error in mpfr_sub (1 - 1E-33) with prec=32\n");
      printf ("Expected 1.0, got "); mpfr_print_binary (x); puts ("");
      exit (1);
    }

  mpfr_set_prec (x, 65);
  mpfr_set_prec (y, 65);
  mpfr_set_prec (z, 64);
  mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
  mpfr_set_str_binary (y, "0.1110111011110001110111011111111111101000011001011100101100101100");
  test_sub (z, x, y, MPFR_RNDZ);
  if (mpfr_cmp_ui (z, 1))
    {
      printf ("Error in mpfr_sub (1)\n");
      exit (1);
    }
  test_sub (z, x, y, MPFR_RNDU);
  mpfr_set_str_binary (x, "1.000000000000000000000000000000000000000000000000000000000000001");
  if (mpfr_cmp (z, x))
    {
      printf ("Error in mpfr_sub (2)\n");
      printf ("Expected "); mpfr_print_binary (x); puts ("");
      printf ("Got      "); mpfr_print_binary (z); puts ("");
      exit (1);
    }
  mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
  test_sub (z, x, y, MPFR_RNDN);
  if (mpfr_cmp_ui (z, 1))
    {
      printf ("Error in mpfr_sub (3)\n");
      exit (1);
    }
  inexact = test_sub (z, x, y, MPFR_RNDA);
  mpfr_set_str_binary (x, "1.000000000000000000000000000000000000000000000000000000000000001");
  if (mpfr_cmp (z, x) || inexact <= 0)
    {
      printf ("Error in mpfr_sub (4)\n");
      exit (1);
    }
  mpfr_set_prec (x, 66);
  mpfr_set_str_binary (x, "1.11101110111100011101110111111111111010000110010111001011001010111");
  test_sub (z, x, y, MPFR_RNDN);
  if (mpfr_cmp_ui (z, 1))
    {
      printf ("Error in mpfr_sub (5)\n");
      exit (1);
    }

  /* check in-place operations */
  mpfr_set_ui (x, 1, MPFR_RNDN);
  test_sub (x, x, x, MPFR_RNDN);
  if (mpfr_cmp_ui(x, 0))
    {
      printf ("Error for mpfr_sub (x, x, x, MPFR_RNDN) with x=1.0\n");
      exit (1);
    }

  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);
  mpfr_set_prec (z, 53);
  mpfr_set_str1 (x, "1.229318102e+09");
  mpfr_set_str1 (y, "2.32221184180698677665e+05");
  test_sub (z, x, y, MPFR_RNDN);
  if (mpfr_cmp_str1 (z, "1229085880.815819263458251953125"))
    {
      printf ("Error in mpfr_sub (1.22e9 - 2.32e5)\n");
      printf ("expected 1229085880.815819263458251953125, got ");
      mpfr_out_str(stdout, 10, 0, z, MPFR_RNDN);
      putchar('\n');
      exit (1);
    }

  mpfr_set_prec (x, 112);
  mpfr_set_prec (y, 98);
  mpfr_set_prec (z, 54);
  mpfr_set_str_binary (x, "0.11111100100000000011000011100000101101010001000111E-401");
  mpfr_set_str_binary (y, "0.10110000100100000101101100011111111011101000111000101E-464");
  test_sub (z, x, y, MPFR_RNDN);
  if (mpfr_cmp (z, x)) {
    printf ("mpfr_sub(z, x, y) failed for prec(x)=112, prec(y)=98\n");
    printf ("expected "); mpfr_print_binary (x); puts ("");
    printf ("got      "); mpfr_print_binary (z); puts ("");
    exit (1);
  }

  mpfr_set_prec (x, 33);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_div_2exp (x, x, 32, MPFR_RNDN);
  mpfr_sub_ui (x, x, 1, MPFR_RNDN);

  mpfr_set_prec (x, 5);
  mpfr_set_prec (y, 5);
  mpfr_set_str_binary (x, "1e-12");
  mpfr_set_ui (y, 1, MPFR_RNDN);
  test_sub (x, y, x, MPFR_RNDD);
  mpfr_set_str_binary (y, "0.11111");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_sub (x, y, x, MPFR_RNDD) for x=2^(-12), y=1\n");
      exit (1);
    }

  mpfr_set_prec (x, 24);
  mpfr_set_prec (y, 24);
  mpfr_set_str_binary (x, "-0.100010000000000000000000E19");
  mpfr_set_str_binary (y, "0.100000000000000000000100E15");
  mpfr_add (x, x, y, MPFR_RNDD);
  mpfr_set_str_binary (y, "-0.1E19");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_add (2)\n");
      exit (1);
    }

  mpfr_set_prec (x, 2);
  mpfr_set_prec (y, 10);
  mpfr_set_prec (z, 10);
  mpfr_set_ui (y, 0, MPFR_RNDN);
  mpfr_set_str_binary (z, "0.10001");
  if (test_sub (x, y, z, MPFR_RNDN) <= 0)
    {
      printf ("Wrong inexact flag in x=mpfr_sub(0,z) for prec(z)>prec(x)\n");
      exit (1);
    }
  if (test_sub (x, z, y, MPFR_RNDN) >= 0)
    {
      printf ("Wrong inexact flag in x=mpfr_sub(z,0) for prec(z)>prec(x)\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
}
Example #26
0
/* Use the reflection formula Digamma(1-x) = Digamma(x) + Pi * cot(Pi*x),
   i.e., Digamma(x) = Digamma(1-x) - Pi * cot(Pi*x).
   Assume x < 1/2. */
static int
mpfr_digamma_reflection (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  mpfr_prec_t p = MPFR_PREC(y) + 10, q;
  mpfr_t t, u, v;
  mpfr_exp_t e1, expv;
  int inex;
  MPFR_ZIV_DECL (loop);

  /* we want that 1-x is exact with precision q: if 0 < x < 1/2, then
     q = PREC(x)-EXP(x) is ok, otherwise if -1 <= x < 0, q = PREC(x)-EXP(x)
     is ok, otherwise for x < -1, PREC(x) is ok if EXP(x) <= PREC(x),
     otherwise we need EXP(x) */
  if (MPFR_EXP(x) < 0)
    q = MPFR_PREC(x) + 1 - MPFR_EXP(x);
  else if (MPFR_EXP(x) <= MPFR_PREC(x))
    q = MPFR_PREC(x) + 1;
  else
    q = MPFR_EXP(x);
  mpfr_init2 (u, q);
  MPFR_DBGRES(inex = mpfr_ui_sub (u, 1, x, MPFR_RNDN));
  MPFR_ASSERTN(inex == 0);

  /* if x is half an integer, cot(Pi*x) = 0, thus Digamma(x) = Digamma(1-x) */
  mpfr_mul_2exp (u, u, 1, MPFR_RNDN);
  inex = mpfr_integer_p (u);
  mpfr_div_2exp (u, u, 1, MPFR_RNDN);
  if (inex)
    {
      inex = mpfr_digamma (y, u, rnd_mode);
      goto end;
    }

  mpfr_init2 (t, p);
  mpfr_init2 (v, p);

  MPFR_ZIV_INIT (loop, p);
  for (;;)
    {
      mpfr_const_pi (v, MPFR_RNDN);  /* v = Pi*(1+theta) for |theta|<=2^(-p) */
      mpfr_mul (t, v, x, MPFR_RNDN); /* (1+theta)^2 */
      e1 = MPFR_EXP(t) - (mpfr_exp_t) p + 1; /* bound for t: err(t) <= 2^e1 */
      mpfr_cot (t, t, MPFR_RNDN);
      /* cot(t * (1+h)) = cot(t) - theta * (1 + cot(t)^2) with |theta|<=t*h */
      if (MPFR_EXP(t) > 0)
        e1 = e1 + 2 * MPFR_EXP(t) + 1;
      else
        e1 = e1 + 1;
      /* now theta * (1 + cot(t)^2) <= 2^e1 */
      e1 += (mpfr_exp_t) p - MPFR_EXP(t); /* error is now 2^e1 ulps */
      mpfr_mul (t, t, v, MPFR_RNDN);
      e1 ++;
      mpfr_digamma (v, u, MPFR_RNDN);   /* error <= 1/2 ulp */
      expv = MPFR_EXP(v);
      mpfr_sub (v, v, t, MPFR_RNDN);
      if (MPFR_EXP(v) < MPFR_EXP(t))
        e1 += MPFR_EXP(t) - MPFR_EXP(v); /* scale error for t wrt new v */
      /* now take into account the 1/2 ulp error for v */
      if (expv - MPFR_EXP(v) - 1 > e1)
        e1 = expv - MPFR_EXP(v) - 1;
      else
        e1 ++;
      e1 ++; /* rounding error for mpfr_sub */
      if (MPFR_CAN_ROUND (v, p - e1, MPFR_PREC(y), rnd_mode))
        break;
      MPFR_ZIV_NEXT (loop, p);
      mpfr_set_prec (t, p);
      mpfr_set_prec (v, p);
    }
  MPFR_ZIV_FREE (loop);

  inex = mpfr_set (y, v, rnd_mode);

  mpfr_clear (t);
  mpfr_clear (v);
 end:
  mpfr_clear (u);

  return inex;
}
Example #27
0
static void
check_special (void)
{
  mpfr_t  a, d, q;
  mpfr_exp_t emax, emin;
  int i;

  mpfr_init2 (a, 100L);
  mpfr_init2 (d, 100L);
  mpfr_init2 (q, 100L);

  /* 1/nan == nan */
  mpfr_set_ui (a, 1L, MPFR_RNDN);
  MPFR_SET_NAN (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);

  /* nan/1 == nan */
  MPFR_SET_NAN (a);
  mpfr_set_ui (d, 1L, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);

  /* +inf/1 == +inf */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  mpfr_set_ui (d, 1L, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* +inf/-1 == -inf */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  mpfr_set_si (d, -1, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -inf/1 == -inf */
  MPFR_SET_INF (a);
  MPFR_SET_NEG (a);
  mpfr_set_ui (d, 1L, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -inf/-1 == +inf */
  MPFR_SET_INF (a);
  MPFR_SET_NEG (a);
  mpfr_set_si (d, -1, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* 1/+inf == +0 */
  mpfr_set_ui (a, 1L, MPFR_RNDN);
  MPFR_SET_INF (d);
  MPFR_SET_POS (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_number_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) == 0);
  MPFR_ASSERTN (MPFR_IS_POS (q));
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* 1/-inf == -0 */
  mpfr_set_ui (a, 1L, MPFR_RNDN);
  MPFR_SET_INF (d);
  MPFR_SET_NEG (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_number_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) == 0);
  MPFR_ASSERTN (MPFR_IS_NEG (q));
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -1/+inf == -0 */
  mpfr_set_si (a, -1, MPFR_RNDN);
  MPFR_SET_INF (d);
  MPFR_SET_POS (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_number_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) == 0);
  MPFR_ASSERTN (MPFR_IS_NEG (q));
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -1/-inf == +0 */
  mpfr_set_si (a, -1, MPFR_RNDN);
  MPFR_SET_INF (d);
  MPFR_SET_NEG (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_number_p (q));
  MPFR_ASSERTN (mpfr_sgn (q) == 0);
  MPFR_ASSERTN (MPFR_IS_POS (q));
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* 0/0 == nan */
  mpfr_set_ui (a, 0L, MPFR_RNDN);
  mpfr_set_ui (d, 0L, MPFR_RNDN);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);

  /* +inf/+inf == nan */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  MPFR_SET_INF (d);
  MPFR_SET_POS (d);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);

  /* 1/+0 = +inf */
  mpfr_set_ui (a, 1, MPFR_RNDZ);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);

  /* 1/-0 = -inf */
  mpfr_set_ui (a, 1, MPFR_RNDZ);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_neg (d, d, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);

  /* -1/+0 = -inf */
  mpfr_set_si (a, -1, MPFR_RNDZ);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);

  /* -1/-0 = +inf */
  mpfr_set_si (a, -1, MPFR_RNDZ);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_neg (d, d, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);

  /* +inf/+0 = +inf */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* +inf/-0 = -inf */
  MPFR_SET_INF (a);
  MPFR_SET_POS (a);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_neg (d, d, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -inf/+0 = -inf */
  MPFR_SET_INF (a);
  MPFR_SET_NEG (a);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* -inf/-0 = +inf */
  MPFR_SET_INF (a);
  MPFR_SET_NEG (a);
  mpfr_set_ui (d, 0, MPFR_RNDZ);
  mpfr_neg (d, d, MPFR_RNDZ);
  mpfr_clear_flags ();
  MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);

  /* check overflow */
  emax = mpfr_get_emax ();
  set_emax (1);
  mpfr_set_ui (a, 1, MPFR_RNDZ);
  mpfr_set_ui (d, 1, MPFR_RNDZ);
  mpfr_div_2exp (d, d, 1, MPFR_RNDZ);
  mpfr_clear_flags ();
  test_div (q, a, d, MPFR_RNDU); /* 1 / 0.5 = 2 -> overflow */
  MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
  MPFR_ASSERTN (__gmpfr_flags == (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT));
  set_emax (emax);

  /* check underflow */
  emin = mpfr_get_emin ();
  set_emin (-1);
  mpfr_set_ui (a, 1, MPFR_RNDZ);
  mpfr_div_2exp (a, a, 2, MPFR_RNDZ);
  mpfr_set_prec (d, mpfr_get_prec (q) + 8);
  for (i = -1; i <= 1; i++)
    {
      int sign;

      /* Test 2^(-2) / (+/- (2 + eps)), with eps < 0, eps = 0, eps > 0.
         -> underflow.
         With div.c r5513, this test fails for eps > 0 in MPFR_RNDN. */
      mpfr_set_ui (d, 2, MPFR_RNDZ);
      if (i < 0)
        mpfr_nextbelow (d);
      if (i > 0)
        mpfr_nextabove (d);
      for (sign = 0; sign <= 1; sign++)
        {
          mpfr_clear_flags ();
          test_div (q, a, d, MPFR_RNDZ); /* result = 0 */
          MPFR_ASSERTN (__gmpfr_flags ==
                        (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT));
          MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q));
          MPFR_ASSERTN (MPFR_IS_ZERO (q));
          mpfr_clear_flags ();
          test_div (q, a, d, MPFR_RNDN); /* result = 0 iff eps >= 0 */
          MPFR_ASSERTN (__gmpfr_flags ==
                        (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT));
          MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q));
          if (i < 0)
            mpfr_nexttozero (q);
          MPFR_ASSERTN (MPFR_IS_ZERO (q));
          mpfr_neg (d, d, MPFR_RNDN);
        }
    }
  set_emin (emin);

  mpfr_clear (a);
  mpfr_clear (d);
  mpfr_clear (q);
}
Example #28
0
/* Put in s an approximation of digamma(x).
   Assumes x >= 2.
   Assumes s does not overlap with x.
   Returns an integer e such that the error is bounded by 2^e ulps
   of the result s.
*/
static mpfr_exp_t
mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
{
  mpfr_prec_t p = MPFR_PREC (s);
  mpfr_t t, u, invxx;
  mpfr_exp_t e, exps, f, expu;
  mpz_t *INITIALIZED(B);  /* variable B declared as initialized */
  unsigned long n0, n; /* number of allocated B[] */

  MPFR_ASSERTN(MPFR_IS_POS(x) && (MPFR_EXP(x) >= 2));

  mpfr_init2 (t, p);
  mpfr_init2 (u, p);
  mpfr_init2 (invxx, p);

  mpfr_log (s, x, MPFR_RNDN);         /* error <= 1/2 ulp */
  mpfr_ui_div (t, 1, x, MPFR_RNDN);   /* error <= 1/2 ulp */
  mpfr_div_2exp (t, t, 1, MPFR_RNDN); /* exact */
  mpfr_sub (s, s, t, MPFR_RNDN);
  /* error <= 1/2 + 1/2*2^(EXP(olds)-EXP(s)) + 1/2*2^(EXP(t)-EXP(s)).
     For x >= 2, log(x) >= 2*(1/(2x)), thus olds >= 2t, and olds - t >= olds/2,
     thus 0 <= EXP(olds)-EXP(s) <= 1, and EXP(t)-EXP(s) <= 0, thus
     error <= 1/2 + 1/2*2 + 1/2 <= 2 ulps. */
  e = 2; /* initial error */
  mpfr_mul (invxx, x, x, MPFR_RNDZ);     /* invxx = x^2 * (1 + theta)
                                            for |theta| <= 2^(-p) */
  mpfr_ui_div (invxx, 1, invxx, MPFR_RNDU); /* invxx = 1/x^2 * (1 + theta)^2 */

  /* in the following we note err=xxx when the ratio between the approximation
     and the exact result can be written (1 + theta)^xxx for |theta| <= 2^(-p),
     following Higham's method */
  B = mpfr_bernoulli_internal ((mpz_t *) 0, 0);
  mpfr_set_ui (t, 1, MPFR_RNDN); /* err = 0 */
  for (n = 1;; n++)
    {
      /* compute next Bernoulli number */
      B = mpfr_bernoulli_internal (B, n);
      /* The main term is Bernoulli[2n]/(2n)/x^(2n) = B[n]/(2n+1)!(2n)/x^(2n)
         = B[n]*t[n]/(2n) where t[n]/t[n-1] = 1/(2n)/(2n+1)/x^2. */
      mpfr_mul (t, t, invxx, MPFR_RNDU);        /* err = err + 3 */
      mpfr_div_ui (t, t, 2 * n, MPFR_RNDU);     /* err = err + 1 */
      mpfr_div_ui (t, t, 2 * n + 1, MPFR_RNDU); /* err = err + 1 */
      /* we thus have err = 5n here */
      mpfr_div_ui (u, t, 2 * n, MPFR_RNDU);     /* err = 5n+1 */
      mpfr_mul_z (u, u, B[n], MPFR_RNDU);       /* err = 5n+2, and the
                                                   absolute error is bounded
                                                   by 10n+4 ulp(u) [Rule 11] */
      /* if the terms 'u' are decreasing by a factor two at least,
         then the error coming from those is bounded by
         sum((10n+4)/2^n, n=1..infinity) = 24 */
      exps = mpfr_get_exp (s);
      expu = mpfr_get_exp (u);
      if (expu < exps - (mpfr_exp_t) p)
        break;
      mpfr_sub (s, s, u, MPFR_RNDN); /* error <= 24 + n/2 */
      if (mpfr_get_exp (s) < exps)
        e <<= exps - mpfr_get_exp (s);
      e ++; /* error in mpfr_sub */
      f = 10 * n + 4;
      while (expu < exps)
        {
          f = (1 + f) / 2;
          expu ++;
        }
      e += f; /* total rouding error coming from 'u' term */
    }

  n0 = ++n;
  while (n--)
    mpz_clear (B[n]);
  (*__gmp_free_func) (B, n0 * sizeof (mpz_t));

  mpfr_clear (t);
  mpfr_clear (u);
  mpfr_clear (invxx);

  f = 0;
  while (e > 1)
    {
      f++;
      e = (e + 1) / 2;
      /* Invariant: 2^f * e does not decrease */
    }
  return f;
}
Example #29
0
int
main (int argc, char *argv[])
{
    mpfr_t x, y;
    mpfr_exp_t emin, emax;

    tests_start_mpfr ();

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

    mpfr_init (x);
    mpfr_init (y);

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

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

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

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

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

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

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

    mpfr_clear (x);
    mpfr_clear (y);

    set_emin (emin);
    set_emax (emax);

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

    tests_end_mpfr ();
    return 0;
}
Example #30
0
static void
check_one (mpz_ptr z)
{
  int    inex, ex_inex, same;
  int    sh, neg;
  mpfr_t f;
  mpz_t  got, ex;

  mpfr_init2 (f, MAX (mpz_sizeinbase (z, 2), MPFR_PREC_MIN));
  mpz_init (got);
  mpz_init (ex);

  for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++)
    {
      inex = mpfr_set_z (f, z, MPFR_RNDN);  /* exact */
      MPFR_ASSERTN (inex == 0);

      if (sh < 0)
        {
          mpz_tdiv_q_2exp (ex, z, -sh);
          inex = mpfr_div_2exp (f, f, -sh, MPFR_RNDN);
        }
      else
        {
          mpz_mul_2exp (ex, z, sh);
          inex = mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
        }
      MPFR_ASSERTN (inex == 0);

      for (neg = 0; neg <= 1; neg++)
        {
          /* Test (-1)^neg * z * 2^sh */
          int fi;
          mpfr_flags_t flags[3] = { 0, MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE,
                                    MPFR_FLAGS_ALL }, ex_flags, gt_flags;

          for (fi = 0; fi < numberof (flags); fi++)
            {
              ex_inex = - mpfr_cmp_z (f, ex);
              ex_flags = __gmpfr_flags = flags[fi];
              if (ex_inex != 0)
                ex_flags |= MPFR_FLAGS_INEXACT;
              inex = mpfr_get_z (got, f, MPFR_RNDZ);
              gt_flags = __gmpfr_flags;
              same = SAME_SIGN (inex, ex_inex);

              if (mpz_cmp (got, ex) != 0 || !same || gt_flags != ex_flags)
                {
                  printf ("Error in check_one for sh=%d, fi=%d\n", sh, fi);
                  printf ("     f = "); mpfr_dump (f);
                  printf ("expected "); mpz_dump (ex);
                  printf ("     got "); mpz_dump (got);
                  printf ("Expected inex ~ %d, got %d (%s)\n",
                          inex, ex_inex, same ? "OK" : "wrong");
                  printf ("Flags:\n");
                  printf ("      in"); flags_out (gt_flags);
                  printf ("expected"); flags_out (ex_flags);
                  printf ("     got"); flags_out (gt_flags);
                  exit (1);
                }
            }

          mpz_neg (ex, ex);
          mpfr_neg (f, f, MPFR_RNDN);
        }
    }

  mpfr_clear (f);
  mpz_clear (got);
  mpz_clear (ex);
}