Example #1
0
static void
mpfr_const_log10 (mpfr_ptr log10)
{
   mpfr_set_ui (log10, 10, MPFR_RNDN); /* exact since prec >= 4 */
   mpfr_log (log10, log10, MPFR_RNDN); /* error <= 1/2 ulp */
}
Example #2
0
File: tadd.c Project: qsnake/mpfr
static void
check64 (void)
{
    mpfr_t x, t, u;

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

    mpfr_set_prec (x, 29);
    mpfr_set_str_binary (x, "1.1101001000101111011010010110e-3");
    mpfr_set_prec (t, 58);
    mpfr_set_str_binary (t, "0.11100010011111001001100110010111110110011000000100101E-1");
    mpfr_set_prec (u, 29);
    test_add (u, x, t, MPFR_RNDD);
    mpfr_set_str_binary (t, "1.0101011100001000011100111110e-1");
    if (mpfr_cmp (u, t))
    {
        printf ("mpfr_add(u, x, t) failed for prec(x)=29, prec(t)=58\n");
        printf ("expected ");
        mpfr_out_str (stdout, 2, 29, t, MPFR_RNDN);
        puts ("");
        printf ("got      ");
        mpfr_out_str (stdout, 2, 29, u, MPFR_RNDN);
        puts ("");
        exit(1);
    }

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

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

    mpfr_set_prec (x, 112);
    mpfr_set_prec (t, 98);
    mpfr_set_prec (u, 54);
    mpfr_set_str_binary (x, "-0.11111100100000000011000011100000101101010001000111E-401");
    mpfr_set_str_binary (t, "0.10110000100100000101101100011111111011101000111000101E-464");
    test_add (u, x, t, MPFR_RNDN);
    if (mpfr_cmp (u, x))
    {
        printf ("mpfr_add(u, x, t) failed for prec(x)=112, prec(t)=98\n");
        exit (1);
    }

    mpfr_set_prec (x, 92);
    mpfr_set_prec (t, 86);
    mpfr_set_prec (u, 53);
    mpfr_set_str (x, "-5.03525136761487735093e-74", 10, MPFR_RNDN);
    mpfr_set_str (t, "8.51539046314262304109e-91", 10, MPFR_RNDN);
    test_add (u, x, t, MPFR_RNDN);
    if (mpfr_cmp_str1 (u, "-5.0352513676148773509283672e-74") )
    {
        printf ("mpfr_add(u, x, t) failed for prec(x)=92, prec(t)=86\n");
        exit (1);
    }

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

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

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

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

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

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

    /* bug found by Fabrice Rouillier, 27 Mar 2001 */
    mpfr_set_prec (x, 107);
    mpfr_set_prec (t, 107);
    mpfr_set_prec (u, 107);
    mpfr_set_str_binary (x, "0.10111001001111010010001000000010111111011011011101000001001000101000000000000000000000000000000000000000000E315");
    mpfr_set_str_binary (t, "0.10000000000000000000000000000000000101110100100101110110000001100101011111001000011101111100100100111011000E350");
    mpfr_sub (u, x, t, MPFR_RNDU);
    if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] &
            ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0)
    {
        printf ("Error in mpfr_sub: result is not msb-normalized (4)\n");
        exit (1);
    }

    /* checks that NaN flag is correctly reset */
    mpfr_set_ui (t, 1, MPFR_RNDN);
    mpfr_set_ui (u, 1, MPFR_RNDN);
    mpfr_set_nan (x);
    test_add (x, t, u, MPFR_RNDN);
    if (mpfr_cmp_ui (x, 2))
    {
        printf ("Error in mpfr_add: 1+1 gives ");
        mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
        exit (1);
    }

    mpfr_clear(x);
    mpfr_clear(t);
    mpfr_clear(u);
}
Example #3
0
File: tadd.c Project: qsnake/mpfr
static void
check_1minuseps (void)
{
    static mpfr_prec_t prec_a[] = {
        MPFR_PREC_MIN, 30, 31, 32, 33, 62, 63, 64, 65, 126, 127, 128, 129
    };
    static int supp_b[] = {
        0, 1, 2, 3, 4, 29, 30, 31, 32, 33, 34, 35, 61, 62, 63, 64, 65, 66, 67
    };
    mpfr_t a, b, c;
    unsigned int ia, ib, ic;

    mpfr_init2 (c, MPFR_PREC_MIN);

    for (ia = 0; ia < numberof (prec_a); ia++)
        for (ib = 0; ib < numberof(supp_b); ib++)
        {
            mpfr_prec_t prec_b;
            int rnd_mode;

            prec_b = prec_a[ia] + supp_b[ib];

            mpfr_init2 (a, prec_a[ia]);
            mpfr_init2 (b, prec_b);

            mpfr_set_ui (c, 1, MPFR_RNDN);
            mpfr_div_ui (b, c, prec_a[ia], MPFR_RNDN);
            mpfr_sub (b, c, b, MPFR_RNDN);  /* b = 1 - 2^(-prec_a) */

            for (ic = 0; ic < numberof(supp_b); ic++)
                for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++)
                {
                    mpfr_t s;
                    int inex_a, inex_s;

                    mpfr_set_ui (c, 1, MPFR_RNDN);
                    mpfr_div_ui (c, c, prec_a[ia] + supp_b[ic], MPFR_RNDN);
                    inex_a = test_add (a, b, c, (mpfr_rnd_t) rnd_mode);
                    mpfr_init2 (s, 256);
                    inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */
                    if (inex_s)
                    {
                        printf ("check_1minuseps: result should have been exact "
                                "(ia = %u, ib = %u, ic = %u)\n", ia, ib, ic);
                        exit (1);
                    }
                    inex_s = mpfr_prec_round (s, prec_a[ia], (mpfr_rnd_t) rnd_mode);
                    if ((inex_a < 0 && inex_s >= 0) ||
                            (inex_a == 0 && inex_s != 0) ||
                            (inex_a > 0 && inex_s <= 0) ||
                            !mpfr_equal_p (a, s))
                    {
                        printf ("check_1minuseps: results are different.\n");
                        printf ("ia = %u, ib = %u, ic = %u\n", ia, ib, ic);
                        exit (1);
                    }
                    mpfr_clear (s);
                }

            mpfr_clear (a);
            mpfr_clear (b);
        }

    mpfr_clear (c);
}
Example #4
0
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) */
      inexact = mpfr_mul (x, x, x, MPFR_RNDN);
      MPFR_ASSERTN (inexact == 0); /* exact */
      inexact = test_sqrt (z, x, MPFR_RNDN);
      /* even rule: z should be 2^(GMP_NUMB_BITS - 1) */
      MPFR_ASSERTN (inexact < 0);
      inexact = mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1);
      MPFR_ASSERTN (inexact == 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 #5
0
/* Put in y an approximation of erfc(x) for large x, using formulae 7.1.23 and
   7.1.24 from Abramowitz and Stegun.
   Returns e such that the error is bounded by 2^e ulp(y),
   or returns 0 in case of underflow.
*/
static mpfr_exp_t
mpfr_erfc_asympt (mpfr_ptr y, mpfr_srcptr x)
{
  mpfr_t t, xx, err;
  unsigned long k;
  mpfr_prec_t prec = MPFR_PREC(y);
  mpfr_exp_t exp_err;

  mpfr_init2 (t, prec);
  mpfr_init2 (xx, prec);
  mpfr_init2 (err, 31);
  /* let u = 2^(1-p), and let us represent the error as (1+u)^err
     with a bound for err */
  mpfr_mul (xx, x, x, MPFR_RNDD); /* err <= 1 */
  mpfr_ui_div (xx, 1, xx, MPFR_RNDU); /* upper bound for 1/(2x^2), err <= 2 */
  mpfr_div_2ui (xx, xx, 1, MPFR_RNDU); /* exact */
  mpfr_set_ui (t, 1, MPFR_RNDN); /* current term, exact */
  mpfr_set (y, t, MPFR_RNDN);    /* current sum  */
  mpfr_set_ui (err, 0, MPFR_RNDN);
  for (k = 1; ; k++)
    {
      mpfr_mul_ui (t, t, 2 * k - 1, MPFR_RNDU); /* err <= 4k-3 */
      mpfr_mul (t, t, xx, MPFR_RNDU);           /* err <= 4k */
      /* for -1 < x < 1, and |nx| < 1, we have |(1+x)^n| <= 1+7/4|nx|.
         Indeed, for x>=0: log((1+x)^n) = n*log(1+x) <= n*x. Let y=n*x < 1,
         then exp(y) <= 1+7/4*y.
         For x<=0, let x=-x, we can prove by induction that (1-x)^n >= 1-n*x.*/
      mpfr_mul_2si (err, err, MPFR_GET_EXP (y) - MPFR_GET_EXP (t), MPFR_RNDU);
      mpfr_add_ui (err, err, 14 * k, MPFR_RNDU); /* 2^(1-p) * t <= 2 ulp(t) */
      mpfr_div_2si (err, err, MPFR_GET_EXP (y) - MPFR_GET_EXP (t), MPFR_RNDU);
      if (MPFR_GET_EXP (t) + (mpfr_exp_t) prec <= MPFR_GET_EXP (y))
        {
          /* the truncation error is bounded by |t| < ulp(y) */
          mpfr_add_ui (err, err, 1, MPFR_RNDU);
          break;
        }
      if (k & 1)
        mpfr_sub (y, y, t, MPFR_RNDN);
      else
        mpfr_add (y, y, t, MPFR_RNDN);
    }
  /* the error on y is bounded by err*ulp(y) */
  mpfr_mul (t, x, x, MPFR_RNDU); /* rel. err <= 2^(1-p) */
  mpfr_div_2ui (err, err, 3, MPFR_RNDU);  /* err/8 */
  mpfr_add (err, err, t, MPFR_RNDU);      /* err/8 + xx */
  mpfr_mul_2ui (err, err, 3, MPFR_RNDU);  /* err + 8*xx */
  mpfr_exp (t, t, MPFR_RNDU); /* err <= 1/2*ulp(t) + err(x*x)*t
                                <= 1/2*ulp(t)+2*|x*x|*ulp(t)
                                <= (2*|x*x|+1/2)*ulp(t) */
  mpfr_mul (t, t, x, MPFR_RNDN); /* err <= 1/2*ulp(t) + (4*|x*x|+1)*ulp(t)
                                   <= (4*|x*x|+3/2)*ulp(t) */
  mpfr_const_pi (xx, MPFR_RNDZ); /* err <= ulp(Pi) */
  mpfr_sqrt (xx, xx, MPFR_RNDN); /* err <= 1/2*ulp(xx) + ulp(Pi)/2/sqrt(Pi)
                                   <= 3/2*ulp(xx) */
  mpfr_mul (t, t, xx, MPFR_RNDN); /* err <= (8 |xx| + 13/2) * ulp(t) */
  mpfr_div (y, y, t, MPFR_RNDN); /* the relative error on input y is bounded
                                   by (1+u)^err with u = 2^(1-p), that on
                                   t is bounded by (1+u)^(8 |xx| + 13/2),
                                   thus that on output y is bounded by
                                   8 |xx| + 7 + err. */

  if (MPFR_IS_ZERO(y))
    {
      /* If y is zero, most probably we have underflow. We check it directly
         using the fact that erfc(x) <= exp(-x^2)/sqrt(Pi)/x for x >= 0.
         We compute an upper approximation of exp(-x^2)/sqrt(Pi)/x.
      */
      mpfr_mul (t, x, x, MPFR_RNDD); /* t <= x^2 */
      mpfr_neg (t, t, MPFR_RNDU);    /* -x^2 <= t */
      mpfr_exp (t, t, MPFR_RNDU);    /* exp(-x^2) <= t */
      mpfr_const_pi (xx, MPFR_RNDD); /* xx <= sqrt(Pi), cached */
      mpfr_mul (xx, xx, x, MPFR_RNDD); /* xx <= sqrt(Pi)*x */
      mpfr_div (y, t, xx, MPFR_RNDN); /* if y is zero, this means that the upper
                                        approximation of exp(-x^2)/sqrt(Pi)/x
                                        is nearer from 0 than from 2^(-emin-1),
                                        thus we have underflow. */
      exp_err = 0;
    }
  else
    {
      mpfr_add_ui (err, err, 7, MPFR_RNDU);
      exp_err = MPFR_GET_EXP (err);
    }

  mpfr_clear (t);
  mpfr_clear (xx);
  mpfr_clear (err);
  return exp_err;
}
Example #6
0
/* The computation of z = pow(x,y) is done by
   z = exp(y * log(x)) = x^y
   For the special cases, see Section F.9.4.4 of the C standard:
     _ pow(±0, y) = ±inf for y an odd integer < 0.
     _ pow(±0, y) = +inf for y < 0 and not an odd integer.
     _ pow(±0, y) = ±0 for y an odd integer > 0.
     _ pow(±0, y) = +0 for y > 0 and not an odd integer.
     _ pow(-1, ±inf) = 1.
     _ pow(+1, y) = 1 for any y, even a NaN.
     _ pow(x, ±0) = 1 for any x, even a NaN.
     _ pow(x, y) = NaN for finite x < 0 and finite non-integer y.
     _ pow(x, -inf) = +inf for |x| < 1.
     _ pow(x, -inf) = +0 for |x| > 1.
     _ pow(x, +inf) = +0 for |x| < 1.
     _ pow(x, +inf) = +inf for |x| > 1.
     _ pow(-inf, y) = -0 for y an odd integer < 0.
     _ pow(-inf, y) = +0 for y < 0 and not an odd integer.
     _ pow(-inf, y) = -inf for y an odd integer > 0.
     _ pow(-inf, y) = +inf for y > 0 and not an odd integer.
     _ pow(+inf, y) = +0 for y < 0.
     _ pow(+inf, y) = +inf for y > 0. */
int
mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
{
  int inexact;
  int cmp_x_1;
  int y_is_integer;
  MPFR_SAVE_EXPO_DECL (expo);

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

  if (MPFR_ARE_SINGULAR (x, y))
    {
      /* pow(x, 0) returns 1 for any x, even a NaN. */
      if (MPFR_UNLIKELY (MPFR_IS_ZERO (y)))
        return mpfr_set_ui (z, 1, rnd_mode);
      else if (MPFR_IS_NAN (x))
        {
          MPFR_SET_NAN (z);
          MPFR_RET_NAN;
        }
      else if (MPFR_IS_NAN (y))
        {
          /* pow(+1, NaN) returns 1. */
          if (mpfr_cmp_ui (x, 1) == 0)
            return mpfr_set_ui (z, 1, rnd_mode);
          MPFR_SET_NAN (z);
          MPFR_RET_NAN;
        }
      else if (MPFR_IS_INF (y))
        {
          if (MPFR_IS_INF (x))
            {
              if (MPFR_IS_POS (y))
                MPFR_SET_INF (z);
              else
                MPFR_SET_ZERO (z);
              MPFR_SET_POS (z);
              MPFR_RET (0);
            }
          else
            {
              int cmp;
              cmp = mpfr_cmpabs (x, __gmpfr_one) * MPFR_INT_SIGN (y);
              MPFR_SET_POS (z);
              if (cmp > 0)
                {
                  /* Return +inf. */
                  MPFR_SET_INF (z);
                  MPFR_RET (0);
                }
              else if (cmp < 0)
                {
                  /* Return +0. */
                  MPFR_SET_ZERO (z);
                  MPFR_RET (0);
                }
              else
                {
                  /* Return 1. */
                  return mpfr_set_ui (z, 1, rnd_mode);
                }
            }
        }
      else if (MPFR_IS_INF (x))
        {
          int negative;
          /* Determine the sign now, in case y and z are the same object */
          negative = MPFR_IS_NEG (x) && is_odd (y);
          if (MPFR_IS_POS (y))
            MPFR_SET_INF (z);
          else
            MPFR_SET_ZERO (z);
          if (negative)
            MPFR_SET_NEG (z);
          else
            MPFR_SET_POS (z);
          MPFR_RET (0);
        }
      else
        {
          int negative;
          MPFR_ASSERTD (MPFR_IS_ZERO (x));
          /* Determine the sign now, in case y and z are the same object */
          negative = MPFR_IS_NEG(x) && is_odd (y);
          if (MPFR_IS_NEG (y))
            {
              MPFR_ASSERTD (! MPFR_IS_INF (y));
              MPFR_SET_INF (z);
              mpfr_set_divby0 ();
            }
          else
            MPFR_SET_ZERO (z);
          if (negative)
            MPFR_SET_NEG (z);
          else
            MPFR_SET_POS (z);
          MPFR_RET (0);
        }
    }

  /* x^y for x < 0 and y not an integer is not defined */
  y_is_integer = mpfr_integer_p (y);
  if (MPFR_IS_NEG (x) && ! y_is_integer)
    {
      MPFR_SET_NAN (z);
      MPFR_RET_NAN;
    }

  /* now the result cannot be NaN:
     (1) either x > 0
     (2) or x < 0 and y is an integer */

  cmp_x_1 = mpfr_cmpabs (x, __gmpfr_one);
  if (cmp_x_1 == 0)
    return mpfr_set_si (z, MPFR_IS_NEG (x) && is_odd (y) ? -1 : 1, rnd_mode);

  /* now we have:
     (1) either x > 0
     (2) or x < 0 and y is an integer
     and in addition |x| <> 1.
  */

  /* detect overflow: an overflow is possible if
     (a) |x| > 1 and y > 0
     (b) |x| < 1 and y < 0.
     FIXME: this assumes 1 is always representable.

     FIXME2: maybe we can test overflow and underflow simultaneously.
     The idea is the following: first compute an approximation to
     y * log2|x|, using rounding to nearest. If |x| is not too near from 1,
     this approximation should be accurate enough, and in most cases enable
     one to prove that there is no underflow nor overflow.
     Otherwise, it should enable one to check only underflow or overflow,
     instead of both cases as in the present case.
  */
  if (cmp_x_1 * MPFR_SIGN (y) > 0)
    {
      mpfr_t t;
      int negative, overflow;

      MPFR_SAVE_EXPO_MARK (expo);
      mpfr_init2 (t, 53);
      /* we want a lower bound on y*log2|x|:
         (i) if x > 0, it suffices to round log2(x) toward zero, and
             to round y*o(log2(x)) toward zero too;
         (ii) if x < 0, we first compute t = o(-x), with rounding toward 1,
              and then follow as in case (1). */
      if (MPFR_SIGN (x) > 0)
        mpfr_log2 (t, x, MPFR_RNDZ);
      else
        {
          mpfr_neg (t, x, (cmp_x_1 > 0) ? MPFR_RNDZ : MPFR_RNDU);
          mpfr_log2 (t, t, MPFR_RNDZ);
        }
      mpfr_mul (t, t, y, MPFR_RNDZ);
      overflow = mpfr_cmp_si (t, __gmpfr_emax) > 0;
      mpfr_clear (t);
      MPFR_SAVE_EXPO_FREE (expo);
      if (overflow)
        {
          MPFR_LOG_MSG (("early overflow detection\n", 0));
          negative = MPFR_SIGN(x) < 0 && is_odd (y);
          return mpfr_overflow (z, rnd_mode, negative ? -1 : 1);
        }
    }

  /* Basic underflow checking. One has:
   *   - if y > 0, |x^y| < 2^(EXP(x) * y);
   *   - if y < 0, |x^y| <= 2^((EXP(x) - 1) * y);
   * so that one can compute a value ebound such that |x^y| < 2^ebound.
   * If we have ebound <= emin - 2 (emin - 1 in directed rounding modes),
   * then there is an underflow and we can decide the return value.
   */
  if (MPFR_IS_NEG (y) ? (MPFR_GET_EXP (x) > 1) : (MPFR_GET_EXP (x) < 0))
    {
      mpfr_t tmp;
      mpfr_eexp_t ebound;
      int inex2;

      /* We must restore the flags. */
      MPFR_SAVE_EXPO_MARK (expo);
      mpfr_init2 (tmp, sizeof (mpfr_exp_t) * CHAR_BIT);
      inex2 = mpfr_set_exp_t (tmp, MPFR_GET_EXP (x), MPFR_RNDN);
      MPFR_ASSERTN (inex2 == 0);
      if (MPFR_IS_NEG (y))
        {
          inex2 = mpfr_sub_ui (tmp, tmp, 1, MPFR_RNDN);
          MPFR_ASSERTN (inex2 == 0);
        }
      mpfr_mul (tmp, tmp, y, MPFR_RNDU);
      if (MPFR_IS_NEG (y))
        mpfr_nextabove (tmp);
      /* tmp doesn't necessarily fit in ebound, but that doesn't matter
         since we get the minimum value in such a case. */
      ebound = mpfr_get_exp_t (tmp, MPFR_RNDU);
      mpfr_clear (tmp);
      MPFR_SAVE_EXPO_FREE (expo);
      if (MPFR_UNLIKELY (ebound <=
                         __gmpfr_emin - (rnd_mode == MPFR_RNDN ? 2 : 1)))
        {
          /* warning: mpfr_underflow rounds away from 0 for MPFR_RNDN */
          MPFR_LOG_MSG (("early underflow detection\n", 0));
          return mpfr_underflow (z,
                                 rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
                                 MPFR_SIGN (x) < 0 && is_odd (y) ? -1 : 1);
        }
    }

  /* If y is an integer, we can use mpfr_pow_z (based on multiplications),
     but if y is very large (I'm not sure about the best threshold -- VL),
     we shouldn't use it, as it can be very slow and take a lot of memory
     (and even crash or make other programs crash, as several hundred of
     MBs may be necessary). Note that in such a case, either x = +/-2^b
     (this case is handled below) or x^y cannot be represented exactly in
     any precision supported by MPFR (the general case uses this property).
  */
  if (y_is_integer && (MPFR_GET_EXP (y) <= 256))
    {
      mpz_t zi;

      MPFR_LOG_MSG (("special code for y not too large integer\n", 0));
      mpz_init (zi);
      mpfr_get_z (zi, y, MPFR_RNDN);
      inexact = mpfr_pow_z (z, x, zi, rnd_mode);
      mpz_clear (zi);
      return inexact;
    }

  /* Special case (+/-2^b)^Y which could be exact. If x is negative, then
     necessarily y is a large integer. */
  {
    mpfr_exp_t b = MPFR_GET_EXP (x) - 1;

    MPFR_ASSERTN (b >= LONG_MIN && b <= LONG_MAX);  /* FIXME... */
    if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), b) == 0)
      {
        mpfr_t tmp;
        int sgnx = MPFR_SIGN (x);

        MPFR_LOG_MSG (("special case (+/-2^b)^Y\n", 0));
        /* now x = +/-2^b, so x^y = (+/-1)^y*2^(b*y) is exact whenever b*y is
           an integer */
        MPFR_SAVE_EXPO_MARK (expo);
        mpfr_init2 (tmp, MPFR_PREC (y) + sizeof (long) * CHAR_BIT);
        inexact = mpfr_mul_si (tmp, y, b, MPFR_RNDN); /* exact */
        MPFR_ASSERTN (inexact == 0);
        /* Note: as the exponent range has been extended, an overflow is not
           possible (due to basic overflow and underflow checking above, as
           the result is ~ 2^tmp), and an underflow is not possible either
           because b is an integer (thus either 0 or >= 1). */
        MPFR_CLEAR_FLAGS ();
        inexact = mpfr_exp2 (z, tmp, rnd_mode);
        mpfr_clear (tmp);
        if (sgnx < 0 && is_odd (y))
          {
            mpfr_neg (z, z, rnd_mode);
            inexact = -inexact;
          }
        /* Without the following, the overflows3 test in tpow.c fails. */
        MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
        MPFR_SAVE_EXPO_FREE (expo);
        return mpfr_check_range (z, inexact, rnd_mode);
      }
  }

  MPFR_SAVE_EXPO_MARK (expo);

  /* Case where |y * log(x)| is very small. Warning: x can be negative, in
     that case y is a large integer. */
  {
    mpfr_t t;
    mpfr_exp_t err;

    /* We need an upper bound on the exponent of y * log(x). */
    mpfr_init2 (t, 16);
    if (MPFR_IS_POS(x))
      mpfr_log (t, x, cmp_x_1 < 0 ? MPFR_RNDD : MPFR_RNDU); /* away from 0 */
    else
      {
        /* if x < -1, round to +Inf, else round to zero */
        mpfr_neg (t, x, (mpfr_cmp_si (x, -1) < 0) ? MPFR_RNDU : MPFR_RNDD);
        mpfr_log (t, t, (mpfr_cmp_ui (t, 1) < 0) ? MPFR_RNDD : MPFR_RNDU);
      }
    MPFR_ASSERTN (MPFR_IS_PURE_FP (t));
    err = MPFR_GET_EXP (y) + MPFR_GET_EXP (t);
    mpfr_clear (t);
    MPFR_CLEAR_FLAGS ();
    MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (z, __gmpfr_one, - err, 0,
                                      (MPFR_SIGN (y) > 0) ^ (cmp_x_1 < 0),
                                      rnd_mode, expo, {});
  }

  /* General case */
  inexact = mpfr_pow_general (z, x, y, rnd_mode, y_is_integer, &expo);

  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (z, inexact, rnd_mode);
}
Example #7
0
int
main (void)
{
  mpfr_t x;
  mpfr_exp_t emin;

  tests_start_mpfr ();
  emin = mpfr_get_emin ();

  mpfr_init2 (x, IEEE_DBL_MANT_DIG);

  mpfr_set_d (x, 2.34763465, MPFR_RNDN);
  if (mpfr_cmp_d (x, 2.34763465) != 0)
    {
      printf ("Error in mpfr_cmp_d 2.34763465 and ");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
      exit (1);
    }
  if (mpfr_cmp_d (x, 2.345) <= 0)
    {
      printf ("Error in mpfr_cmp_d 2.345 and ");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
      exit (1);
    }
  if (mpfr_cmp_d (x, 2.4) >= 0)
    {
      printf ("Error in mpfr_cmp_d 2.4 and ");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDZ);
  mpfr_neg (x, x, MPFR_RNDZ);
  if (mpfr_cmp_d (x, 0.0))
    {
      printf ("Error in mpfr_cmp_d 0.0 and ");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_ui_div (x, 1, x, MPFR_RNDU);
  if (mpfr_cmp_d (x, 0.0) == 0)
    {
      printf ("Error in mpfr_cmp_d (Inf, 0)\n");
      exit (1);
    }

  /* Test in reduced exponent range. */
  set_emin (1);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  if (mpfr_cmp_d (x, 0.9) <= 0)
    {
      printf ("Error in reduced exponent range.\n");
      exit (1);
    }
  set_emin (emin);

#if !defined(MPFR_ERRDIVZERO)
  /* Check NAN */
  {
    int c;

    mpfr_clear_flags ();
    c = mpfr_cmp_d (x, DBL_NAN);
    if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
      {
        printf ("ERROR for NAN (1)\n");
        printf ("Expected 0, got %d\n", c);
        printf ("Expected flags:");
        flags_out (MPFR_FLAGS_ERANGE);
        printf ("Got flags:     ");
        flags_out (__gmpfr_flags);
#ifdef MPFR_NANISNAN
        printf ("The reason is that NAN == NAN. Please look at the configure "
                "output\nand Section \"In case of problem\" of the INSTALL "
                "file.\n");
#endif
        exit (1);
      }

    mpfr_set_nan (x);
    mpfr_clear_flags ();
    c = mpfr_cmp_d (x, 2.0);
    if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
      {
        printf ("ERROR for NAN (2)\n");
        printf ("Expected 0, got %d\n", c);
        printf ("Expected flags:");
        flags_out (MPFR_FLAGS_ERANGE);
        printf ("Got flags:     ");
        flags_out (__gmpfr_flags);
#ifdef MPFR_NANISNAN
        printf ("The reason is that NAN == NAN. Please look at the configure "
                "output\nand Section \"In case of problem\" of the INSTALL "
                "file.\n");
#endif
        exit (1);
      }
  }
#endif  /* MPFR_ERRDIVZERO */

  mpfr_clear (x);

  tests_end_mpfr ();
  return 0;
}
static void
special_overflow (void)
{
  mpfr_t x, y;
  mpfr_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, MPFR_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, MPFR_RNDN); /* exact */
  mpfr_gamma (y, x, MPFR_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, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_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, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_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, MPFR_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, MPFR_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, MPFR_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,
                MPFR_RNDN);
  mpfr_div_2exp (x, x, 170, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDN);
  mpfr_set_prec (x, 38);
  mpfr_set_str (x, "201948391737", 10, MPFR_RNDN);
  mpfr_mul_2exp (x, x, 92, MPFR_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,
                MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDN);
  mpfr_set_prec (x, 38);
  mpfr_set_str (x, "-3.623795987425E-121243", 10, MPFR_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, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_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, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_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, MPFR_RNDN);
  inex = mpfr_gamma (x, x, MPFR_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, MPFR_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);
    }

  set_emin (emin);
  set_emax (emax);

  /* bug found by Kevin Rauch, 26 Oct 2007 */
  mpfr_set_str (x, "1e19", 10, MPFR_RNDN);
  inex = mpfr_gamma (x, x, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_inf_p (x) && inex > 0);

  mpfr_clear (y);
  mpfr_clear (x);
}
static void
special (void)
{
  mpfr_t x, y;
  int inex;

  mpfr_init (x);
  mpfr_init (y);

  mpfr_set_nan (x);
  mpfr_gamma (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for gamma(NaN)\n");
      exit (1);
    }

  mpfr_set_inf (x, -1);
  mpfr_gamma (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for gamma(-Inf)\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_gamma (y, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for gamma(+Inf)\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for gamma(+0)\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_neg (x, x, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0)
    {
      printf ("Error for gamma(-0)\n");
      exit (1);
    }

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 1))
    {
      printf ("Error for gamma(1)\n");
      exit (1);
    }

  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for gamma(-1)\n");
      exit (1);
    }

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

#define CHECK_X1 "1.0762904832837976166"
#define CHECK_Y1 "0.96134843256452096050"

  mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDN);
  mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN);
  if (mpfr_cmp (y, x))
    {
      printf ("mpfr_lngamma("CHECK_X1") is wrong:\n"
              "expected ");
      mpfr_print_binary (x); putchar ('\n');
      printf ("got      ");
      mpfr_print_binary (y); putchar ('\n');
      exit (1);
    }

#define CHECK_X2 "9.23709516716202383435e-01"
#define CHECK_Y2 "1.0502315560291053398"
  mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDN);
  mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN);
  if (mpfr_cmp (y, x))
    {
      printf ("mpfr_lngamma("CHECK_X2") is wrong:\n"
              "expected ");
      mpfr_print_binary (x); putchar ('\n');
      printf ("got      ");
      mpfr_print_binary (y); putchar ('\n');
      exit (1);
    }

  mpfr_set_prec (x, 8);
  mpfr_set_prec (y, 175);
  mpfr_set_ui (x, 33, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDU);
  mpfr_set_prec (x, 175);
  mpfr_set_str_binary (x, "0.110010101011010101101000010101010111000110011101001000101011000001100010111001101001011E118");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_gamma (1)\n");
      exit (1);
    }

  mpfr_set_prec (x, 21);
  mpfr_set_prec (y, 8);
  mpfr_set_ui (y, 120, MPFR_RNDN);
  mpfr_gamma (x, y, MPFR_RNDZ);
  mpfr_set_prec (y, 21);
  mpfr_set_str_binary (y, "0.101111101110100110110E654");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_gamma (120)\n");
      printf ("Expected "); mpfr_print_binary (y); puts ("");
      printf ("Got      "); mpfr_print_binary (x); puts ("");
      exit (1);
    }

  mpfr_set_prec (x, 3);
  mpfr_set_prec (y, 206);
  mpfr_set_str_binary (x, "0.110e10");
  inex = mpfr_gamma (y, x, MPFR_RNDN);
  mpfr_set_prec (x, 206);
  mpfr_set_str_binary (x, "0.110111100001000001101010010001000111000100000100111000010011100011011111001100011110101000111101101100110001001100110100001001111110000101010000100100011100010011101110000001000010001100010000101001111E6250");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_gamma (768)\n");
      exit (1);
    }
  if (inex <= 0)
    {
      printf ("Wrong flag for mpfr_gamma (768)\n");
      exit (1);
    }

  /* worst case to exercise retry */
  mpfr_set_prec (x, 1000);
  mpfr_set_prec (y, 869);
  mpfr_const_pi (x, MPFR_RNDN);
  mpfr_gamma (y, x, MPFR_RNDN);

  mpfr_set_prec (x, 4);
  mpfr_set_prec (y, 4);
  mpfr_set_str_binary (x, "-0.1100E-66");
  mpfr_gamma (y, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "-0.1011E67");
  if (mpfr_cmp (x, y))
    {
      printf ("Error for gamma(-0.1100E-66)\n");
      exit (1);
    }

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

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

  mpfr_set_ui (x, 21, MPFR_RNDN);
  mpfr_set_ui (y, 28, MPFR_RNDN);
  mpfr_set_ui (z, 35, MPFR_RNDN);

  mpfr_mul_2ui (x, x, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
  mpfr_mul_2ui (y, y, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
  mpfr_mul_2ui (z, z, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);

  mpfr_hypot (t, x, y, MPFR_RNDN);
  if (mpfr_cmp (z, t))
    {
      printf ("Error in test_large: got\n");
      mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
      printf ("\ninstead of\n");
      mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_prec (x, 53);
  mpfr_set_prec (t, 53);
  mpfr_set_prec (y, 53);
  mpfr_set_str_binary (x, "0.11101100011110000011101000010101010011001101000001100E-1021");
  mpfr_set_str_binary (y, "0.11111001010011000001110110001101011100001000010010100E-1021");
  mpfr_hypot (t, x, y, MPFR_RNDN);
  mpfr_set_str_binary (z, "0.101010111100110111101110111110100110010011001010111E-1020");
  if (mpfr_cmp (z, t))
    {
      printf ("Error in test_large: got\n");
      mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
      printf ("\ninstead of\n");
      mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_prec (x, 240);
  mpfr_set_prec (y, 22);
  mpfr_set_prec (z, 2);
  mpfr_set_prec (t, 2);
  mpfr_set_str_binary (x, "0.100111011010010010110100000100000001100010011100110101101111111101011110111011011101010110100101111000111100010100110000100101011110111011100110100110100101110101101100011000001100000001111101110100100100011011011010110111100110010101000111e-7");
  mpfr_set_str_binary (y, "0.1111000010000011000111E-10");
  mpfr_hypot (t, x, y, MPFR_RNDN);
  mpfr_set_str_binary (z, "0.11E-7");
  if (mpfr_cmp (z, t))
    {
      printf ("Error in test_large: got\n");
      mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
      printf ("\ninstead of\n");
      mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);
  mpfr_clear (t);
}
Example #11
0
int
mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
{
  if (n > 0)
    return mpfr_pow_ui(y, x, n, rnd_mode);
  else
    {
      int inexact = 0;

      if (MPFR_IS_NAN(x))
        {
          MPFR_SET_NAN(y);
          MPFR_RET_NAN;
        }

      MPFR_CLEAR_NAN(y);

      if (n == 0)
        return mpfr_set_ui(y, 1, GMP_RNDN);

      if (MPFR_IS_INF(x))
        {
          MPFR_SET_ZERO(y);
          if (MPFR_SIGN(x) > 0 || ((unsigned) n & 1) == 0)
            MPFR_SET_POS(y);
          else
            MPFR_SET_NEG(y);
          MPFR_RET(0);
        }

      if (MPFR_IS_ZERO(x))
        {
          MPFR_SET_INF(y);
          if (MPFR_SIGN(x) > 0 || ((unsigned) n & 1) == 0)
            MPFR_SET_POS(y);
          else
            MPFR_SET_NEG(y);
          MPFR_RET(0);
        }

      MPFR_CLEAR_INF(y);

      n = -n;

      /* General case */
      {
        /* Declaration of the intermediary variable */
        mpfr_t t, ti;

        /* Declaration of the size variable */
        mp_prec_t Nx = MPFR_PREC(x);   /* Precision of input variable */
        mp_prec_t Ny = MPFR_PREC(y);   /* Precision of input variable */

        mp_prec_t Nt;   /* Precision of the intermediary variable */
        long int err;  /* Precision of error */
                
        /* compute the precision of intermediary variable */
        Nt=MAX(Nx,Ny);
        /* the optimal number of bits : see algorithms.ps */
        Nt=Nt+3+_mpfr_ceil_log2(Nt);

        /* initialise of intermediary	variable */
        mpfr_init(t);
        mpfr_init(ti);

        do {

          /* reactualisation of the precision */
          mpfr_set_prec(t,Nt);                    
          mpfr_set_prec(ti,Nt);             

          /* compute 1/(x^n) n>0*/
          mpfr_pow_ui(ti,x,(unsigned long int)(n),GMP_RNDN);
          mpfr_ui_div(t,1,ti,GMP_RNDN);

          /* estimation of the error -- see pow function in algorithms.ps*/
          err = Nt - 3;

          /* actualisation of the precision */
          Nt += 10;

        } while (err<0 || !mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny));
 
        inexact = mpfr_set(y,t,rnd_mode);
        mpfr_clear(t);
        mpfr_clear(ti);
      }
      return inexact;
    }
}
static void
underflow (mpfr_exp_t e)
{
  mpfr_t x, y, z1, z2;
  mpfr_exp_t emin;
  int i, k;
  int prec;
  int rnd;
  int div;
  int inex1, inex2;
  unsigned int flags1, flags2;

  /* Test mul_2si(x, e - k), div_2si(x, k - e) and div_2ui(x, k - e)
   * with emin = e, x = 1 + i/16, i in { -1, 0, 1 }, and k = 1 to 4,
   * by comparing the result with the one of a simple division.
   */
  emin = mpfr_get_emin ();
  set_emin (e);
  mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
  for (i = 15; i <= 17; i++)
    {
      inex1 = mpfr_set_ui_2exp (x, i, -4, MPFR_RNDN);
      MPFR_ASSERTN (inex1 == 0);
      for (prec = 6; prec >= 3; prec -= 3)
        {
          mpfr_inits2 (prec, z1, z2, (mpfr_ptr) 0);
          RND_LOOP (rnd)
            for (k = 1; k <= 4; k++)
              {
                /* The following one is assumed to be correct. */
                inex1 = mpfr_mul_2si (y, x, e, MPFR_RNDN);
                MPFR_ASSERTN (inex1 == 0);
                inex1 = mpfr_set_ui (z1, 1 << k, MPFR_RNDN);
                MPFR_ASSERTN (inex1 == 0);
                mpfr_clear_flags ();
                /* Do not use mpfr_div_ui to avoid the optimization
                   by mpfr_div_2si. */
                inex1 = mpfr_div (z1, y, z1, (mpfr_rnd_t) rnd);
                flags1 = __gmpfr_flags;

              for (div = 0; div <= 2; div++)
                {
                  mpfr_clear_flags ();
                  inex2 = div == 0 ?
                    mpfr_mul_2si (z2, x, e - k, (mpfr_rnd_t) rnd) : div == 1 ?
                    mpfr_div_2si (z2, x, k - e, (mpfr_rnd_t) rnd) :
                    mpfr_div_2ui (z2, x, k - e, (mpfr_rnd_t) rnd);
                  flags2 = __gmpfr_flags;
                  if (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
                      mpfr_equal_p (z1, z2))
                    continue;
                  printf ("Error in underflow(");
                  if (e == MPFR_EMIN_MIN)
                    printf ("MPFR_EMIN_MIN");
                  else if (e == emin)
                    printf ("default emin");
                  else
                    printf ("%ld", e);
                  printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d, "
                          "%s\n", div == 0 ? "mul_2si" : div == 1 ?
                          "div_2si" : "div_2ui", i, prec, k,
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  printf ("Expected ");
                  mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN);
                  printf (", inex = %d, flags = %u\n", SIGN (inex1), flags1);
                  printf ("Got      ");
                  mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN);
                  printf (", inex = %d, flags = %u\n", SIGN (inex2), flags2);
                  exit (1);
                }  /* div */
              }  /* k */
          mpfr_clears (z1, z2, (mpfr_ptr) 0);
        }  /* prec */
    }  /* i */
  mpfr_clears (x, y, (mpfr_ptr) 0);
  set_emin (emin);
}
int
main (int argc, char *argv[])
{
  mpfr_t w,z;
  unsigned long k;
  int i;

  tests_start_mpfr ();

  mpfr_inits2 (53, w, z, (mpfr_ptr) 0);

  for (i = 0; i < 3; i++)
    {
      mpfr_set_inf (w, 1);
      test_mul (i, 0, w, w, 10, MPFR_RNDZ);
      if (!MPFR_IS_INF(w))
        {
          printf ("Result is not Inf (i = %d)\n", i);
          exit (1);
        }

      mpfr_set_nan (w);
      test_mul (i, 0, w, w, 10, MPFR_RNDZ);
      if (!MPFR_IS_NAN(w))
        {
          printf ("Result is not NaN (i = %d)\n", i);
          exit (1);
        }

      for (k = 0 ; k < numberof(val) ; k+=3)
        {
          mpfr_set_str (w, val[k], 16, MPFR_RNDN);
          test_mul (i, 0, z, w, 10, MPFR_RNDZ);
          if (mpfr_cmp_str (z, val[k+1], 16, MPFR_RNDN))
            {
              printf ("ERROR for x * 2^n (i = %d) for %s\n", i, val[k]);
              printf ("Expected: %s\n"
                      "Got     : ", val[k+1]);
              mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
              putchar ('\n');
              exit (1);
            }
          test_mul (i, 1, z, w, 10, MPFR_RNDZ);
          if (mpfr_cmp_str (z, val[k+2], 16, MPFR_RNDN))
            {
              printf ("ERROR for x / 2^n (i = %d) for %s\n", i, val[k]);
              printf ("Expected: %s\n"
                      "Got     : ", val[k+2]);
              mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
              putchar ('\n');
              exit (1);
            }
        }

      mpfr_set_inf (w, 1);
      mpfr_nextbelow (w);
      test_mul (i, 0, w, w, 1, MPFR_RNDN);
      if (!mpfr_inf_p (w))
        {
          printf ("Overflow error (i = %d)!\n", i);
          exit (1);
        }
      mpfr_set_ui (w, 0, MPFR_RNDN);
      mpfr_nextabove (w);
      test_mul (i, 1, w, w, 1, MPFR_RNDN);
      if (mpfr_cmp_ui (w, 0))
        {
          printf ("Underflow error (i = %d)!\n", i);
          exit (1);
        }
    }

  if (MPFR_EXP_MAX >= LONG_MAX/2 && MPFR_EXP_MIN <= LONG_MAX/2-LONG_MAX-1)
    {
      unsigned long lmp1 = (unsigned long) LONG_MAX + 1;

      mpfr_set_ui (w, 1, MPFR_RNDN);
      mpfr_mul_2ui (w, w, LONG_MAX/2, MPFR_RNDZ);
      mpfr_div_2ui (w, w, lmp1, MPFR_RNDZ);
      mpfr_mul_2ui (w, w, lmp1 - LONG_MAX/2, MPFR_RNDZ);
      if (!mpfr_cmp_ui (w, 1))
        {
          printf ("Underflow LONG_MAX error!\n");
          exit (1);
        }
    }

  mpfr_clears (w, z, (mpfr_ptr) 0);

  underflow0 ();
  large0 ();

  tests_end_mpfr ();
  return 0;
}
Example #14
0
int
mpfr_fac_ui (mpfr_ptr y, unsigned long int x, mp_rnd_t rnd_mode)
{
  mpfr_t t;       /* Variable of Intermediary Calculation*/
  unsigned long i;
  int round, inexact;

  mp_prec_t Ny;   /* Precision of output variable */
  mp_prec_t Nt;   /* Precision of Intermediary Calculation variable */
  mp_prec_t err;  /* Precision of error */

  mp_rnd_t rnd;
  MPFR_SAVE_EXPO_DECL (expo);
  MPFR_ZIV_DECL (loop);

  /***** test x = 0  and x == 1******/
  if (MPFR_UNLIKELY (x <= 1))
    return mpfr_set_ui (y, 1, rnd_mode); /* 0! = 1 and 1! = 1 */

  MPFR_SAVE_EXPO_MARK (expo);

  /* Initialisation of the Precision */
  Ny = MPFR_PREC (y);

  /* compute the size of intermediary variable */
  Nt = Ny + 2 * MPFR_INT_CEIL_LOG2 (x) + 7;

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

  rnd = GMP_RNDZ;
  MPFR_ZIV_INIT (loop, Nt);
  for (;;)
    {
      /* compute factorial */
      inexact = mpfr_set_ui (t, 1, rnd);
      for (i = 2 ; i <= x ; i++)
        {
          round = mpfr_mul_ui (t, t, i, rnd);
          /* assume the first inexact product gives the sign
             of difference: is that always correct? */
          if (inexact == 0)
            inexact = round;
        }

      err = Nt - 1 - MPFR_INT_CEIL_LOG2 (Nt);

      round = !inexact || mpfr_can_round (t, err, rnd, GMP_RNDZ,
                                          Ny + (rnd_mode == GMP_RNDN));

      if (MPFR_LIKELY (round))
        {
          /* If inexact = 0, then t is exactly x!, so round is the
             correct inexact flag.
             Otherwise, t != x! since we rounded to zero or away. */
          round = mpfr_set (y, t, rnd_mode);
          if (inexact == 0)
            {
              inexact = round;
              break;
            }
          else if ((inexact < 0 && round <= 0)
                   || (inexact > 0 && round >= 0))
            break;
          else /* inexact and round have opposite signs: we cannot
                  compute the inexact flag. Restart using the
                  symmetric rounding. */
            rnd = (rnd == GMP_RNDZ) ? GMP_RNDU : GMP_RNDZ;
        }
      MPFR_ZIV_NEXT (loop, Nt);
      mpfr_set_prec (t, Nt);
    }
  MPFR_ZIV_FREE (loop);

  mpfr_clear (t);
  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (y, inexact, rnd_mode);
}
Example #15
0
static void
check_specials (void)
{
  mpfr_t  x, y;

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

  mpfr_set_nan (x);
  mpfr_csch (y, x, MPFR_RNDN);
  if (! mpfr_nan_p (y))
    {
      printf ("Error: csch(NaN) != NaN\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_csch (y, x, MPFR_RNDN);
  if (! (mpfr_zero_p (y) && MPFR_SIGN (y) >0))
    {
      printf ("Error: csch(+Inf) != +0\n");
      exit (1);
    }

  mpfr_set_inf (x, -1);
  mpfr_csch (y, x, MPFR_RNDN);
  if (! (mpfr_zero_p (y) && MPFR_SIGN (y) <0))
    {
      printf ("Error: csch(-0) != -0\n");
      exit (1);
    }

  /* csc(+/-0) = +/-Inf */
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_csch (y, x, MPFR_RNDN);
  if (! (mpfr_inf_p (y) && mpfr_sgn (y) > 0))
    {
      printf ("Error: csch(+0) != +Inf\n");
      exit (1);
    }
  mpfr_neg (x, x, MPFR_RNDN);
  mpfr_csch (y, x, MPFR_RNDN);
  if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0))
    {
      printf ("Error: csch(-0) != -Inf\n");
      exit (1);
    }

  /* check huge x */
  mpfr_set_str (x, "8e8", 10, MPFR_RNDN);
  mpfr_csch (y, x, MPFR_RNDN);
  if (! (mpfr_zero_p (y) && MPFR_SIGN (y) > 0))
    {
      printf ("Error: csch(8e8) != +0\n");
      exit (1);
    }
  mpfr_set_str (x, "-8e8", 10, MPFR_RNDN);
  mpfr_csch (y, x, MPFR_RNDN);
  if (! (mpfr_zero_p (y) && MPFR_SIGN (y) < 0))
    {
      printf ("Error: csch(-8e8) != -0\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
static void
exprange (void)
{
  mpfr_exp_t emin, emax;
  mpfr_t x, y, z;
  int inex1, inex2;
  unsigned int flags1, flags2;

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

  mpfr_init2 (x, 16);
  mpfr_inits2 (8, y, z, (mpfr_ptr) 0);

  mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN);
  mpfr_clear_flags ();
  inex1 = mpfr_gamma (y, x, MPFR_RNDN);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emin (0);
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDN);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emin (emin);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test1)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_set_ui_2exp (x, 32769, -60, MPFR_RNDN);
  mpfr_clear_flags ();
  inex1 = mpfr_gamma (y, x, MPFR_RNDD);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (45);
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (emax);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test2)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_set_emax (44);
  mpfr_clear_flags ();
  inex1 = mpfr_check_range (y, inex1, MPFR_RNDD);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (emax);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test3)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_set_ui_2exp (x, 1, -60, MPFR_RNDN);
  mpfr_clear_flags ();
  inex1 = mpfr_gamma (y, x, MPFR_RNDD);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (60);
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (emax);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test4)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  MPFR_ASSERTN (MPFR_EMIN_MIN == - MPFR_EMAX_MAX);
  mpfr_set_emin (MPFR_EMIN_MIN);
  mpfr_set_emax (MPFR_EMAX_MAX);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_nextabove (x);  /* x = 2^(emin - 1) */
  mpfr_set_inf (y, 1);
  inex1 = 1;
  flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
  mpfr_clear_flags ();
  /* MPFR_RNDU: overflow, infinity since 1/x = 2^(emax + 1) */
  inex2 = mpfr_gamma (z, x, MPFR_RNDU);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test5)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_clear_flags ();
  /* MPFR_RNDN: overflow, infinity since 1/x = 2^(emax + 1) */
  inex2 = mpfr_gamma (z, x, MPFR_RNDN);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test6)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_nextbelow (y);
  inex1 = -1;
  mpfr_clear_flags ();
  /* MPFR_RNDD: overflow, maxnum since 1/x = 2^(emax + 1) */
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test7)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_mul_2ui (x, x, 1, MPFR_RNDN);  /* x = 2^emin */
  mpfr_set_inf (y, 1);
  inex1 = 1;
  flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
  mpfr_clear_flags ();
  /* MPFR_RNDU: overflow, infinity since 1/x = 2^emax */
  inex2 = mpfr_gamma (z, x, MPFR_RNDU);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test8)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_clear_flags ();
  /* MPFR_RNDN: overflow, infinity since 1/x = 2^emax */
  inex2 = mpfr_gamma (z, x, MPFR_RNDN);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test9)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_nextbelow (y);
  inex1 = -1;
  flags1 = MPFR_FLAGS_INEXACT;
  mpfr_clear_flags ();
  /* MPFR_RNDD: no overflow, maxnum since 1/x = 2^emax and euler > 0 */
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test10)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_set_emin (emin);
  mpfr_set_emax (emax);

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
Example #17
0
static void
check_nans (void)
{
  mpfr_t  x, y;
  int inexact;

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

  /* nan / 1.0 is nan */
  mpfr_set_nan (x);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 1.0, MPFR_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
  MPFR_ASSERTN (mpfr_nan_p (y));

  /* +inf / 1.0 == +inf */
  mpfr_set_inf (x, 1);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 1.0, MPFR_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (MPFR_IS_POS (y));

  /* -inf / 1.0 == -inf */
  mpfr_set_inf (x, -1);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 1.0, MPFR_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (MPFR_IS_NEG (y));

  /* 0.0 / 0.0 is nan */
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
  MPFR_ASSERTN (mpfr_nan_p (y));

  /* 1.0 / 0.0 == +inf */
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (MPFR_IS_POS (y));

  /* -1.0 / 0.0 == -inf */
  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (MPFR_IS_NEG (y));

  mpfr_clear (x);
  mpfr_clear (y);
}
Example #18
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y;

  tests_start_mpfr ();

  mpfr_init (x);
  mpfr_init (y);

  /* special values */
  mpfr_set_nan (x);
  mpfr_y0 (y, x, GMP_RNDN);
  MPFR_ASSERTN(mpfr_nan_p (y));

  mpfr_set_inf (x, 1); /* +Inf */
  mpfr_y0 (y, x, GMP_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));

  mpfr_set_inf (x, -1); /* -Inf */
  mpfr_y0 (y, x, GMP_RNDN);
  MPFR_ASSERTN(mpfr_nan_p (y));

  mpfr_set_ui (x, 0, GMP_RNDN); /* +0 */
  mpfr_y0 (y, x, GMP_RNDN);
  MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(+0)=-Inf */

  mpfr_set_ui (x, 0, GMP_RNDN);
  mpfr_neg (x, x, GMP_RNDN); /* -0 */
  mpfr_y0 (y, x, GMP_RNDN);
  MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(-0)=-Inf */

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

  mpfr_set_ui (x, 1, GMP_RNDN);
  mpfr_y0 (y, x, GMP_RNDN);
  mpfr_set_str_binary (x, "0.00010110100110000000001000100110111100110101100011011111");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_y0 for x=1, rnd=GMP_RNDN\n");
      printf ("Expected "); mpfr_dump (x);
      printf ("Got      "); mpfr_dump (y);
      exit (1);
    }

  mpfr_set_si (x, -1, GMP_RNDN);
  mpfr_y0 (y, x, GMP_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error in mpfr_y0 for x=-1, rnd=GMP_RNDN\n");
      printf ("Expected NaN\n");
      printf ("Got      "); mpfr_dump (y);
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);

  test_generic (2, 100, 1);

  data_check ("data/y0", mpfr_y0, "mpfr_y0");

  tests_end_mpfr ();

  return 0;
}
Example #19
0
int
main (void)
{
   mpfr_t x;
   mp_exp_t emax;

   tests_start_mpfr ();

   mpfr_init (x);

   mpfr_set_nan (x);
   mpfr_prec_round (x, 2, GMP_RNDN);
   MPFR_ASSERTN(mpfr_nan_p (x));

   mpfr_set_inf (x, 1);
   mpfr_prec_round (x, 2, GMP_RNDN);
   MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);

   mpfr_set_inf (x, -1);
   mpfr_prec_round (x, 2, GMP_RNDN);
   MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);

   mpfr_set_ui (x, 0, GMP_RNDN);
   mpfr_prec_round (x, 2, GMP_RNDN);
   MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));

   mpfr_set_ui (x, 0, GMP_RNDN);
   mpfr_neg (x, x, GMP_RNDN);
   mpfr_prec_round (x, 2, GMP_RNDN);
   MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG(x));

   emax = mpfr_get_emax ();
   set_emax (0);
   mpfr_set_prec (x, 3);
   mpfr_set_str_binary (x, "0.111");
   mpfr_prec_round (x, 2, GMP_RNDN);
   MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
   set_emax (emax);

   mpfr_set_prec (x, mp_bits_per_limb + 2);
   mpfr_set_ui (x, 1, GMP_RNDN);
   mpfr_nextbelow (x);
   mpfr_prec_round (x, mp_bits_per_limb + 1, GMP_RNDN);
   MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);

   mpfr_set_prec (x, 3);
   mpfr_set_ui (x, 5, GMP_RNDN);
   mpfr_prec_round (x, 2, GMP_RNDN);
   if (mpfr_cmp_ui(x, 4))
     {
       printf ("Error in tround: got ");
       mpfr_out_str (stdout, 10, 0, x, GMP_RNDN);
       printf (" instead of 4\n");
       exit (1);
     }

   /* check case when reallocation is needed */
   mpfr_set_prec (x, 3);
   mpfr_set_ui (x, 5, GMP_RNDN); /* exact */
   mpfr_prec_round (x, mp_bits_per_limb + 1, GMP_RNDN);
   if (mpfr_cmp_ui(x, 5))
     {
       printf ("Error in tround: got ");
       mpfr_out_str (stdout, 10, 0, x, GMP_RNDN);
       printf (" instead of 5\n");
       exit (1);
     }

   mpfr_clear(x);
   mpfr_init2 (x, 3);
   mpfr_set_si (x, -5, GMP_RNDN); /* exact */
   mpfr_prec_round (x, mp_bits_per_limb + 1, GMP_RNDN);
   if (mpfr_cmp_si(x, -5))
     {
       printf ("Error in tround: got ");
       mpfr_out_str (stdout, 10, 0, x, GMP_RNDN);
       printf (" instead of -5\n");
       exit (1);
     }

   /* check case when new precision needs less limbs */
   mpfr_set_prec (x, mp_bits_per_limb + 1);
   mpfr_set_ui (x, 5, GMP_RNDN); /* exact */
   mpfr_prec_round (x, 3, GMP_RNDN); /* exact */
   if (mpfr_cmp_ui(x, 5))
     {
       printf ("Error in tround: got ");
       mpfr_out_str (stdout, 10, 0, x, GMP_RNDN);
       printf (" instead of 5\n");
       exit (1);
     }

   mpfr_clear(x);

   tests_end_mpfr ();
   return 0;
}
Example #20
0
static void
check_specials (void)
{
  mpfr_t  x, y;

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

  mpfr_set_nan (x);
  mpfr_sech (y, x, MPFR_RNDN);
  if (! mpfr_nan_p (y))
    {
      printf ("Error: sech(NaN) != NaN\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_sech (y, x, MPFR_RNDN);
  if (! (MPFR_IS_ZERO (y) && MPFR_SIGN (y) > 0))
    {
      printf ("Error: sech(+Inf) != +0\n");
      exit (1);
    }

  mpfr_set_inf (x, -1);
  mpfr_sech (y, x, MPFR_RNDN);
  if (! (MPFR_IS_ZERO (y) && MPFR_SIGN (y) > 0))
    {
      printf ("Error: sech(-Inf) != +0\n");
      exit (1);
    }

  /* sec(+/-0) = 1 */
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_sech (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 1))
    {
      printf ("Error: sech(+0) != 1\n");
      exit (1);
    }
  mpfr_neg (x, x, MPFR_RNDN);
  mpfr_sech (y, x, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 1))
    {
      printf ("Error: sech(-0) != 1\n");
      exit (1);
    }

  /* check huge x */
  mpfr_set_str (x, "8e8", 10, MPFR_RNDN);
  mpfr_sech (y, x, MPFR_RNDN);
  if (! (mpfr_zero_p (y) && MPFR_SIGN (y) > 0))
    {
      printf ("Error: sech(8e8) != +0\n");
      exit (1);
    }
  mpfr_set_str (x, "-8e8", 10, MPFR_RNDN);
  mpfr_sech (y, x, MPFR_RNDN);
  if (! (mpfr_zero_p (y) && MPFR_SIGN (y) > 0))
    {
      printf ("Error: sech(-8e8) != +0\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
int
main (int argc, char *argv[])
{
  mpfr_t x, y;
  unsigned long k, bd, nc, i;
  char *str, *str2;
  mpfr_exp_t e;
  int base, logbase, prec, baseprec, ret, obase;

  tests_start_mpfr ();

  if (argc >= 2) /* tset_str <string> [<prec>] [<ibase>] [<obase>] */
    {
      prec = (argc >= 3) ? atoi (argv[2]) : 53;
      base = (argc >= 4) ? atoi (argv[3]) : 2;
      obase = (argc >= 5) ? atoi (argv[4]) : 10;
      mpfr_init2 (x, prec);
      mpfr_set_str (x, argv[1], base, MPFR_RNDN);
      mpfr_out_str (stdout, obase, 0, x, MPFR_RNDN);
      puts ("");
      mpfr_clear (x);
      return 0;
    }

  mpfr_init2 (x, 2);

  nc = (argc > 1) ? atoi(argv[1]) : 53;
  if (nc < 100)
    nc = 100;

  bd = randlimb () & 8;

  str2 = str = (char*) (*__gmp_allocate_func) (nc);

  if (bd)
    {
      for(k = 1; k <= bd; k++)
        *(str2++) = (randlimb () & 1) + '0';
    }
  else
    *(str2++) = '0';

  *(str2++) = '.';

  for (k = 1; k < nc - 17 - bd; k++)
    *(str2++) = '0' + (char) (randlimb () & 1);

  *(str2++) = 'e';
  sprintf (str2, "%d", (int) (randlimb () & INT_MAX) + INT_MIN/2);

  mpfr_set_prec (x, nc + 10);
  mpfr_set_str_binary (x, str);

  mpfr_set_prec (x, 54);
  mpfr_set_str_binary (x, "0.100100100110110101001010010101111000001011100100101010E-529");
  mpfr_init2 (y, 54);
  mpfr_set_str (y, "4.936a52bc17254@-133", 16, MPFR_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (1a):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str_binary (x, "0.111111101101110010111010100110000111011001010100001101E-529");
  mpfr_set_str (y, "0.fedcba98765434P-529", 16, MPFR_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (1b):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  (*__gmp_free_func) (str, nc);

  mpfr_set_prec (x, 53);
  mpfr_set_str_binary (x, "+110101100.01010000101101000000100111001000101011101110E00");

  mpfr_set_str_binary (x, "1.0");
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error in mpfr_set_str_binary for s=1.0\n");
      mpfr_clear(x);
      mpfr_clear(y);
      exit(1);
    }

  mpfr_set_str_binary (x, "+0000");
  mpfr_set_str_binary (x, "+0000E0");
  mpfr_set_str_binary (x, "0000E0");
  if (mpfr_cmp_ui (x, 0))
    {
      printf ("Error in mpfr_set_str_binary for s=0.0\n");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (x, "+243495834958.53452345E1", 10, MPFR_RNDN);
  mpfr_set_str (x, "9007199254740993", 10, MPFR_RNDN);
  mpfr_set_str (x, "9007199254740992", 10, MPFR_RNDU);
  mpfr_set_str (x, "9007199254740992", 10, MPFR_RNDD);
  mpfr_set_str (x, "9007199254740992", 10, MPFR_RNDZ);

  /* check a random number printed and read is not modified */
  prec = 53;
  mpfr_set_prec (x, prec);
  mpfr_set_prec (y, prec);
  for (i=0;i<N;i++)
    {
      mpfr_rnd_t rnd;

      mpfr_urandomb (x, RANDS);
      rnd = RND_RAND ();
      logbase = (randlimb () % 5) + 1;
      base = 1 << logbase;
      /* Warning: the number of bits needed to print exactly a number of
         'prec' bits in base 2^logbase may be greater than ceil(prec/logbase),
         for example 0.11E-1 in base 2 cannot be written exactly with only
         one digit in base 4 */
      if (base == 2)
        baseprec = prec;
      else
        baseprec = 1 + (prec - 2 + logbase) / logbase;
      str = mpfr_get_str (NULL, &e, base, baseprec, x, rnd);
      mpfr_set_str (y, str, base, rnd);
      MPFR_EXP(y) += logbase * (e - strlen (str));
      if (mpfr_cmp (x, y))
        {
          printf ("mpfr_set_str o mpfr_get_str <> id for rnd_mode=%s\n",
                  mpfr_print_rnd_mode (rnd));
          printf ("x=");
          mpfr_print_binary (x);
          puts ("");
          printf ("s=%s, exp=%d, base=%d\n", str, (int) e, base);
          printf ("y=");
          mpfr_print_binary (y);
          puts ("");
          mpfr_clear (x);
          mpfr_clear (y);
          exit (1);
        }
      (*__gmp_free_func) (str, strlen (str) + 1);
    }

  for (i = 2; i <= 62; i++)
    {
      if (mpfr_set_str (x, "@NaN@(garbage)", i, MPFR_RNDN) != 0 ||
          !mpfr_nan_p(x))
        {
          printf ("mpfr_set_str failed on @NaN@(garbage)\n");
          exit (1);
        }

      /*
      if (mpfr_set_str (x, "@Inf@garbage", i, MPFR_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
        {
          printf ("mpfr_set_str failed on @Inf@garbage\n");
          exit (1);
        }

      if (mpfr_set_str (x, "-@Inf@garbage", i, MPFR_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) > 0)
        {
          printf ("mpfr_set_str failed on -@Inf@garbage\n");
          exit (1);
        }

      if (mpfr_set_str (x, "+@Inf@garbage", i, MPFR_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
        {
          printf ("mpfr_set_str failed on +@Inf@garbage\n");
          exit (1);
        }
      */

      if (i > 16)
        continue;

      if (mpfr_set_str (x, "NaN", i, MPFR_RNDN) != 0 ||
          !mpfr_nan_p(x))
        {
          printf ("mpfr_set_str failed on NaN\n");
          exit (1);
        }

      if (mpfr_set_str (x, "Inf", i, MPFR_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
        {
          printf ("mpfr_set_str failed on Inf\n");
          exit (1);
        }

      if (mpfr_set_str (x, "-Inf", i, MPFR_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) > 0)
        {
          printf ("mpfr_set_str failed on -Inf\n");
          exit (1);
        }

      if (mpfr_set_str (x, "+Inf", i, MPFR_RNDN) != 0 ||
          !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
        {
          printf ("mpfr_set_str failed on +Inf\n");
          exit (1);
        }
    }

  /* check that mpfr_set_str works for uppercase letters too */
  mpfr_set_prec (x, 10);
  mpfr_set_str (x, "B", 16, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 11) != 0)
    {
      printf ("mpfr_set_str does not work for uppercase letters\n");
      exit (1);
    }

  /* start of tests added by Alain Delplanque */

  /* in this example an overflow can occur */
  mpfr_set_prec (x, 64);
  mpfr_set_prec (y, 64);
  mpfr_set_str_binary (x, "1.0E-532");
  mpfr_set_str (y, "0.71128279983522479470@-160", 10, MPFR_RNDU);
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (2):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  /* in this example, I think there was a pb in the old function :
     result of mpfr_set_str_old for the same number , but with more
     precision is: 1.111111111110000000000000000111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100111000100001100000010101100111010e184
     this result is the same as mpfr_set_str */
  mpfr_set_prec (x, 64);
  mpfr_set_prec (y, 64);
  mpfr_set_str_binary (x, "1.111111111110000000000000000111111111111111111111111110000000001E184");
  mpfr_set_str (y, "0.jo08hg31hc5mmpj5mjjmgn55p2h35g@39", 27, MPFR_RNDU);
  /* y = 49027884868983130654865109690613178467841148597221480052 */
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (3):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  /* not exact rounding in mpfr_set_str
     same number with more precision is : 1.111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011011111101000001101110110010101101000010100110011101110010001110e195
     this result is the same as mpfr_set_str */
  /* problem was : can_round was call with MPFR_RNDN round mode,
     so can_round use an error : 1/2 * 2^err * ulp(y)
     instead of 2^err * ulp(y)
     I have increase err by 1 */
  mpfr_set_prec (x, 64);  /* it was round down instead of up */
  mpfr_set_prec (y, 64);
  mpfr_set_str_binary (x, "1.111111111111111111111111111000000000000000000000000000000000001e195");
  mpfr_set_str (y, "0.6e23ekb6acgh96abk10b6c9f2ka16i@45", 21, MPFR_RNDU);
  /* y = 100433627392042473064661483711179345482301462325708736552078 */
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (4):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  /* may be an error in mpfr_set_str_old
     with more precision : 1.111111100000001111110000000000011111011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110111101010001110111011000010111001011100110110e180 */
  mpfr_set_prec (x, 64);  /* it was round down instead of up */
  mpfr_set_prec (y, 64);
  mpfr_set_str_binary (x, "1.111111100000001111110000000000011111011111111111111111111111111e180");
  mpfr_set_str (y, "0.10j8j2k82ehahha56390df0a1de030@41", 23, MPFR_RNDZ);
  /* y = 3053110535624388280648330929253842828159081875986159414 */
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (5):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_prec (x, 64);
  mpfr_set_prec (y, 64);
  mpfr_set_str (y, "0.jrchfhpp9en7hidqm9bmcofid9q3jg@39", 28, MPFR_RNDU);
  /* y = 196159429139499688661464718784226062699788036696626429952 */
  mpfr_set_str_binary (x, "0.1111111111111111111111111111111000000000000011100000001111100001E187");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (6):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_prec (x, 64);
  mpfr_set_prec (y, 64);
  mpfr_set_str (y, "0.h148m5ld5cf8gk1kd70b6ege92g6ba@47", 24, MPFR_RNDZ);
  /* y = 52652933527468502324759448399183654588831274530295083078827114496 */
  mpfr_set_str_binary (x, "0.1111111111111100000000001000000000000000000011111111111111101111E215");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (7):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  /* worst cases for rounding to nearest in double precision */
  mpfr_set_prec (x, 53);
  mpfr_set_prec (y, 53);

  mpfr_set_str (y, "5e125", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.10111101000101110110011000100000101001010000000111111E418");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (8):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "69e267", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.10000101101111100101101100000110010011001010011011010E894");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (9):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "623e100", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.10110010000001010011000101111001110101000001111011111E342");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (10):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "3571e263", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.10110001001100100010011000110000111010100000110101010E886");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (11):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "75569e-254", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.10101101001000110001011011001000111000110101010110011E-827");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (12):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "920657e-23", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.10101001110101001100110000101110110111101111001101100E-56");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (13):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "9210917e80", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.11101101000100011001000110100011111100110000000110010E289");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (14):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "87575437e-309", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.11110000001110011001000000110000000100000010101101100E-1000");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (15):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "245540327e122", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.10001101101100010001100011110000110001100010111001011E434");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (16):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "491080654e122", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.10001101101100010001100011110000110001100010111001011E435");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (17):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  mpfr_set_str (y, "83356057653e193", 10, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.10101010001001110011011011010111011100010101000011000E678");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_set_str (18):\n");
      mpfr_print_binary (x);
      puts ("");
      mpfr_print_binary (y);
      puts ("");
      mpfr_clear (x);
      mpfr_clear (y);
      exit (1);
    }

  CHECK53(y, "83356057653e193", MPFR_RNDN, x,
          "0.10101010001001110011011011010111011100010101000011000E678",
          18);

  CHECK53(y, "619534293513e124", MPFR_RNDN, x,
          "0.10001000011000010000000110000001111111110000011110001e452",
          19);

  CHECK53(y, "3142213164987e-294", MPFR_RNDN, x,
          "0.11101001101000000100111011111101111001010001001101111e-935",
          20);

  CHECK53(y, "36167929443327e-159", MPFR_RNDN, x,
          "0.11100111001110111110000101011001100110010100011111100e-483",
          21);

  CHECK53(y, "904198236083175e-161", MPFR_RNDN, x,
          "0.11100111001110111110000101011001100110010100011111100e-485",
          22);

  CHECK53(y, "3743626360493413e-165", MPFR_RNDN, x,
          "0.11000100000100011101001010111101011011011111011111001e-496",
          23);

  CHECK53(y, "94080055902682397e-242", MPFR_RNDN, x,
          "0.10110010010011000000111100011100111100110011011001010e-747",
          24);

  CHECK53(y, "7e-303", MPFR_RNDD, x,
          "0.10011001100111001000100110001110001000110111110001011e-1003",
          25);
  CHECK53(y, "7e-303", MPFR_RNDU, x,
          "0.10011001100111001000100110001110001000110111110001100e-1003",
          26);

  CHECK53(y, "93e-234", MPFR_RNDD, x,
          "0.10010011110110010111001001111001000010000000001110101E-770",
          27);
  CHECK53(y, "93e-234", MPFR_RNDU, x,
          "0.10010011110110010111001001111001000010000000001110110E-770",
          28);

  CHECK53(y, "755e174", MPFR_RNDD, x,
          "0.10111110110010011000110010011111101111000111111000101E588",
          29);
  CHECK53(y, "755e174", MPFR_RNDU, x,
          "0.10111110110010011000110010011111101111000111111000110E588",
          30);

  CHECK53(y, "8699e-276", MPFR_RNDD, x,
          "0.10010110100101101111100100100011011101100110100101100E-903",
          31);
  CHECK53(y, "8699e-276", MPFR_RNDU, x,
          "0.10010110100101101111100100100011011101100110100101101E-903",
          32);

  CHECK53(y, "82081e41", MPFR_RNDD, x,
          "0.10111000000010000010111011111001111010100011111001011E153",
          33);
  CHECK53(y, "82081e41", MPFR_RNDU, x,
          "0.10111000000010000010111011111001111010100011111001100E153",
          34);

  CHECK53(y, "584169e229", MPFR_RNDD, x,
          "0.11101011001010111000001011001110111000111100110101010E780",
          35);
  CHECK53(y, "584169e229", MPFR_RNDU, x,
          "0.11101011001010111000001011001110111000111100110101011E780",
          36);

  CHECK53(y, "5783893e-128", MPFR_RNDD, x,
          "0.10011000111100000110011110000101100111110011101110100E-402",
          37);
  CHECK53(y, "5783893e-128", MPFR_RNDU, x,
          "0.10011000111100000110011110000101100111110011101110101E-402",
          38);

  CHECK53(y, "87575437e-310", MPFR_RNDD, x,
          "0.11000000001011100000110011110011010000000010001010110E-1003",
          39);
  CHECK53(y, "87575437e-310", MPFR_RNDU, x,
          "0.11000000001011100000110011110011010000000010001010111E-1003",
          40);

  CHECK53(y, "245540327e121", MPFR_RNDD, x,
          "0.11100010101101001111010010110100011100000100101000100E430",
          41);
  CHECK53(y, "245540327e121", MPFR_RNDU, x,
          "0.11100010101101001111010010110100011100000100101000101E430",
          42);

  CHECK53(y, "9078555839e-109", MPFR_RNDD, x,
          "0.11111110001010111010110000110011100110001010011101101E-329",
          43);
  CHECK53(y, "9078555839e-109", MPFR_RNDU, x,
          "0.11111110001010111010110000110011100110001010011101110E-329",
          44);

  CHECK53(y, "42333842451e201", MPFR_RNDD, x,
          "0.10000000110001001101000100110110111110101011101011111E704",
          45);
  CHECK53(y, "42333842451e201", MPFR_RNDU, x,
          "0.10000000110001001101000100110110111110101011101100000E704",
          46);

  CHECK53(y, "778380362293e218", MPFR_RNDD, x,
          "0.11001101010111000001001100001100110010000001010010010E764",
          47);
  CHECK53(y, "778380362293e218", MPFR_RNDU, x,
          "0.11001101010111000001001100001100110010000001010010011E764",
          48);

  CHECK53(y, "7812878489261e-179", MPFR_RNDD, x,
          "0.10010011011011010111001111011101111101101101001110100E-551",
          49);
  CHECK53(y, "7812878489261e-179", MPFR_RNDU, x,
          "0.10010011011011010111001111011101111101101101001110101E-551",
          50);

  CHECK53(y, "77003665618895e-73", MPFR_RNDD, x,
          "0.11000101111110111111001111111101001101111000000101001E-196",
          51);
  CHECK53(y, "77003665618895e-73", MPFR_RNDU, x,
          "0.11000101111110111111001111111101001101111000000101010E-196",
          52);

  CHECK53(y, "834735494917063e-300", MPFR_RNDD, x,
          "0.11111110001101100001001101111100010011001110111010001E-947",
          53);
  CHECK53(y, "834735494917063e-300", MPFR_RNDU, x,
          "0.11111110001101100001001101111100010011001110111010010E-947",
          54);

  CHECK53(y, "6182410494241627e-119", MPFR_RNDD, x,
          "0.10001101110010110010001011000010001000101110100000111E-342",
          55);
  CHECK53(y, "6182410494241627e-119", MPFR_RNDU, x,
          "0.10001101110010110010001011000010001000101110100001000E-342",
          56);

  CHECK53(y, "26153245263757307e49", MPFR_RNDD, x,
          "0.10011110111100000000001011011110101100010000011011110E218",
          57);
  CHECK53(y, "26153245263757307e49", MPFR_RNDU, x,
          "0.10011110111100000000001011011110101100010000011011111E218",
          58);

  /* to check this problem : I convert limb (10--0 or 101--1) into base b
     with more than mp_bits_per_limb digits,
     so when convert into base 2 I should have
     the limb that I have choose */
  /* this use mpfr_get_str */
  {
    size_t nb_digit = mp_bits_per_limb;
    mp_limb_t check_limb[2] = {MPFR_LIMB_HIGHBIT, ~(MPFR_LIMB_HIGHBIT >> 1)};
    int base[3] = {10, 16, 19};
    mpfr_rnd_t rnd[3] = {MPFR_RNDU, MPFR_RNDN, MPFR_RNDD};
    int cbase, climb, crnd;
    char *str;

    mpfr_set_prec (x, mp_bits_per_limb); /* x and y have only one limb */
    mpfr_set_prec (y, mp_bits_per_limb);

    str = (char*) (*__gmp_allocate_func) (N + 20);

    mpfr_set_ui (x, 1, MPFR_RNDN); /* ensures that x is not NaN or Inf */
    for (; nb_digit < N; nb_digit *= 10)
      for (cbase = 0; cbase < 3; cbase++)
        for (climb = 0; climb < 2; climb++)
          for (crnd = 0; crnd < 3; crnd++)
            {
              char *str1;
              mpfr_exp_t exp;

              *(MPFR_MANT(x)) = check_limb[climb];
              MPFR_EXP(x) = 0;

              mpfr_get_str (str + 2, &exp, base[cbase],
                            nb_digit, x, rnd[crnd]);
              str[0] = '-';
              str[(str[2] == '-')] =  '0';
              str[(str[2] == '-') + 1] =  '.';

              for (str1 = str; *str1 != 0; str1++)
                ;
              sprintf (str1, "@%i", (int) exp);

              mpfr_set_str (y, str, base[cbase], rnd[2 - crnd]);

              if (mpfr_cmp (x, y) != 0)
                {
                  printf ("Error in mpfr_set_str for nb_digit=%u, base=%d, "
                          "rnd=%s:\n", (unsigned int) nb_digit, base[cbase],
                          mpfr_print_rnd_mode (rnd[crnd]));
                  printf ("instead of: ");
                  mpfr_print_binary (x);
                  puts ("");
                  printf ("return    : ");
                  mpfr_print_binary (y);
                  puts ("");
                  exit (1);
                }
            }

    (*__gmp_free_func) (str, N + 20);
  }

  /* end of tests added by Alain Delplanque */

  /* check that flags are correctly cleared */
  mpfr_set_nan (x);
  mpfr_set_str (x, "+0.0", 10, MPFR_RNDN);
  if (!mpfr_number_p(x) || mpfr_cmp_ui (x, 0) != 0 || mpfr_sgn (x) < 0)
    {
      printf ("x <- +0.0 failed after x=NaN\n");
      exit (1);
    }
  mpfr_set_str (x, "-0.0", 10, MPFR_RNDN);
  if (!mpfr_number_p(x) || mpfr_cmp_ui (x, 0) != 0 || mpfr_sgn (x) > 0)
    {
      printf ("x <- -0.0 failed after x=NaN\n");
      exit (1);
    }

  /* check invalid input */
  ret = mpfr_set_str (x, "1E10toto", 10, MPFR_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "1p10toto", 16, MPFR_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "", 16, MPFR_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "+", 16, MPFR_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "-", 16, MPFR_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "this_is_an_invalid_number_in_base_36", 36, MPFR_RNDN);
  MPFR_ASSERTN (ret == -1);
  ret = mpfr_set_str (x, "1.2.3", 10, MPFR_RNDN);
  MPFR_ASSERTN (ret == -1);
  mpfr_set_prec (x, 135);
  ret = mpfr_set_str (x, "thisisavalidnumberinbase36", 36, MPFR_RNDN);
  mpfr_set_prec (y, 135);
  mpfr_set_str (y, "23833565676460972739462619524519814462546", 10, MPFR_RNDN);
  MPFR_ASSERTN (mpfr_cmp (x, y) == 0 && ret == 0);

  /* coverage test for set_str_binary */
  mpfr_set_str_binary (x, "NaN");
  MPFR_ASSERTN(mpfr_nan_p (x));
  mpfr_set_str_binary (x, "Inf");
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
  mpfr_set_str_binary (x, "+Inf");
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
  mpfr_set_str_binary (x, "-Inf");
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);
  mpfr_set_prec (x, 3);
  mpfr_set_str_binary (x, "0.01E2");
  MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);
  mpfr_set_str_binary (x, "-0.01E2");
  MPFR_ASSERTN(mpfr_cmp_si (x, -1) == 0);

  mpfr_clear (x);
  mpfr_clear (y);

  check_underflow ();
  bug20081028 ();

  tests_end_mpfr ();
  return 0;
}
Example #22
0
int
main (int argc, char *argv[])
{
  mpfr_t x;
  mpfr_prec_t ret;
  unsigned long i;

  tests_start_mpfr ();

  mpfr_init2 (x, 53);

  /* Check special values */
  mpfr_set_nan (x);
  ret = mpfr_min_prec (x);
  MPFR_ASSERTN (ret == 0);

  mpfr_set_inf (x, 1);
  ret = mpfr_min_prec (x);
  MPFR_ASSERTN (ret == 0);

  mpfr_set_inf (x, -1);
  ret = mpfr_min_prec (x);
  MPFR_ASSERTN (ret == 0);

  mpfr_set_ui (x, 0, MPFR_RNDN);
  ret = mpfr_min_prec (x);
  MPFR_ASSERTN (ret == 0);

  /* Some constants */

  mpfr_set_ui (x, 1, MPFR_RNDN);
  ret = mpfr_min_prec (x);
  MPFR_ASSERTN (ret == 1);

  mpfr_set_ui (x, 17, MPFR_RNDN);
  ret = mpfr_min_prec (x);
  MPFR_ASSERTN (ret == 5);

  mpfr_set_ui (x, 42, MPFR_RNDN);
  ret = mpfr_min_prec (x);
  MPFR_ASSERTN (ret == 5);

  mpfr_set_prec (x, 256);
  for (i = 0; i <= 255; i++)
    {
      mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN);
      mpfr_add_ui (x, x, 1, MPFR_RNDN);
      ret = mpfr_min_prec (x);
      if (ret != i + 1)
        {
          printf ("Error for x = 2^%lu + 1\n", i);
          printf ("Expected %lu, got %lu\n", i + 1, (unsigned long) ret);
          exit (1);
        }
    }

  for (i = MPFR_PREC_MIN; i <= 255; i++)
    {
      mpfr_set_prec (x, i);
      mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN);
      mpfr_sub_ui (x, x, 1, MPFR_RNDN);
      ret = mpfr_min_prec (x);
      if (ret != i)
        {
          printf ("Error for x = 2^%lu - 1\n", i);
          printf ("Expected %lu, got %lu\n", i, (unsigned long) ret);
          exit (1);
        }
    }

  mpfr_clear (x);

  tests_end_mpfr ();
  return 0;
}
Example #23
0
static void
special (void)
{
  mpfr_t x, y;
  int inex;

  mpfr_init (x);
  mpfr_init (y);

  mpfr_set_nan (x);
  mpfr_lngamma (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for lngamma(NaN)\n");
      exit (1);
    }

  mpfr_set_inf (x, -1);
  mpfr_lngamma (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for lngamma(-Inf)\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_lngamma (y, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for lngamma(+Inf)\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    {
      printf ("Error for lngamma(+0)\n");
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_neg (x, x, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for lngamma(-0)\n");
      exit (1);
    }

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDN);
  if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
    {
      printf ("Error for lngamma(1)\n");
      exit (1);
    }

  mpfr_set_si (x, -1, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for lngamma(-1)\n");
      exit (1);
    }

  mpfr_set_ui (x, 2, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDN);
  if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
    {
      printf ("Error for lngamma(2)\n");
      exit (1);
    }

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

#define CHECK_X1 "1.0762904832837976166"
#define CHECK_Y1 "-0.039418362817587634939"

  mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDN);
  mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN);
  if (MPFR_IS_NAN (y) || mpfr_cmp (y, x))
    {
      printf ("mpfr_lngamma("CHECK_X1") is wrong:\n"
              "expected ");
      mpfr_print_binary (x); putchar ('\n');
      printf ("got      ");
      mpfr_print_binary (y); putchar ('\n');
      exit (1);
    }

#define CHECK_X2 "9.23709516716202383435e-01"
#define CHECK_Y2 "0.049010669407893718563"
  mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDN);
  mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN);
  if (MPFR_IS_NAN (y) || mpfr_cmp (y, x))
    {
      printf ("mpfr_lngamma("CHECK_X2") is wrong:\n"
              "expected ");
      mpfr_print_binary (x); putchar ('\n');
      printf ("got      ");
      mpfr_print_binary (y); putchar ('\n');
      exit (1);
    }

  mpfr_set_prec (x, 8);
  mpfr_set_prec (y, 175);
  mpfr_set_ui (x, 33, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDU);
  mpfr_set_prec (x, 175);
  mpfr_set_str_binary (x, "0.1010001100011101101011001101110010100001000001000001110011000001101100001111001001000101011011100100010101011110100111110101010100010011010010000101010111001100011000101111E7");
  if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_lngamma (1)\n");
      exit (1);
    }

  mpfr_set_prec (x, 21);
  mpfr_set_prec (y, 8);
  mpfr_set_ui (y, 120, MPFR_RNDN);
  mpfr_lngamma (x, y, MPFR_RNDZ);
  mpfr_set_prec (y, 21);
  mpfr_set_str_binary (y, "0.111000101000001100101E9");
  if (MPFR_IS_NAN (x) || mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_lngamma (120)\n");
      printf ("Expected "); mpfr_print_binary (y); puts ("");
      printf ("Got      "); mpfr_print_binary (x); puts ("");
      exit (1);
    }

  mpfr_set_prec (x, 3);
  mpfr_set_prec (y, 206);
  mpfr_set_str_binary (x, "0.110e10");
  inex = mpfr_lngamma (y, x, MPFR_RNDN);
  mpfr_set_prec (x, 206);
  mpfr_set_str_binary (x, "0.10000111011000000011100010101001100110001110000111100011000100100110110010001011011110101001111011110110000001010100111011010000000011100110110101100111000111010011110010000100010111101010001101000110101001E13");
  if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
    {
      printf ("Error in mpfr_lngamma (768)\n");
      exit (1);
    }
  if (inex >= 0)
    {
      printf ("Wrong flag for mpfr_lngamma (768)\n");
      exit (1);
    }

  mpfr_set_prec (x, 4);
  mpfr_set_prec (y, 4);
  mpfr_set_str_binary (x, "0.1100E-66");
  mpfr_lngamma (y, x, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.1100E6");
  if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
    {
      printf ("Error for lngamma(0.1100E-66)\n");
      exit (1);
    }

  mpfr_set_prec (x, 256);
  mpfr_set_prec (y, 32);
  mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN);
  mpfr_add_ui (x, x, 1, MPFR_RNDN);
  mpfr_div_2ui (x, x, 1, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDN);
  mpfr_set_prec (x, 32);
  mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207");
  if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
    {
      printf ("Error for lngamma(-2^199+0.5)\n");
      printf ("Got        ");
      mpfr_dump (y);
      printf ("instead of ");
      mpfr_dump (x);
      exit (1);
    }

  mpfr_set_prec (x, 256);
  mpfr_set_prec (y, 32);
  mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN);
  mpfr_sub_ui (x, x, 1, MPFR_RNDN);
  mpfr_div_2ui (x, x, 1, MPFR_RNDN);
  mpfr_lngamma (y, x, MPFR_RNDN);
  if (!mpfr_nan_p (y))
    {
      printf ("Error for lngamma(-2^199-0.5)\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
Example #24
0
static void
special (void)
{
  mpfr_t x, y;
  unsigned xprec, yprec;

  mpfr_init (x);
  mpfr_init (y);

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 32);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_div_ui (y, x, 3, MPFR_RNDN);

  mpfr_set_prec (x, 100);
  mpfr_set_prec (y, 100);
  mpfr_urandomb (x, RANDS);
  mpfr_div_ui (y, x, 123456, MPFR_RNDN);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_div_ui (y, x, 123456789, MPFR_RNDN);
  if (mpfr_cmp_ui (y, 0))
    {
      printf ("mpfr_div_ui gives non-zero for 0/ui\n");
      exit (1);
    }

  /* bug found by Norbert Mueller, 21 Aug 2001 */
  mpfr_set_prec (x, 110);
  mpfr_set_prec (y, 60);
  mpfr_set_str_binary (x, "0.110101110011111110011111001110011001110111000000111110001000111011000011E-44");
  mpfr_div_ui (y, x, 17, MPFR_RNDN);
  mpfr_set_str_binary (x, "0.11001010100101100011101110000001100001010110101001010011011E-48");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in x/17 for x=1/16!\n");
      printf ("Expected ");
      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
      printf ("\nGot      ");
      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  /* corner case */
  mpfr_set_prec (x, 2 * mp_bits_per_limb);
  mpfr_set_prec (y, 2);
  mpfr_set_ui (x, 4, MPFR_RNDN);
  mpfr_nextabove (x);
  mpfr_div_ui (y, x, 2, MPFR_RNDN); /* exactly in the middle */
  MPFR_ASSERTN(mpfr_cmp_ui (y, 2) == 0);
  (mpfr_div_ui) (y, x, 2, MPFR_RNDN); /* exactly in the middle */
  MPFR_ASSERTN(mpfr_cmp_ui (y, 2) == 0);

  mpfr_set_prec (x, 3 * mp_bits_per_limb);
  mpfr_set_prec (y, 2);
  mpfr_set_ui (x, 2, MPFR_RNDN);
  mpfr_nextabove (x);
  mpfr_div_ui (y, x, 2, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
  (mpfr_div_ui) (y, x, 2, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);

  mpfr_set_prec (x, 3 * mp_bits_per_limb);
  mpfr_set_prec (y, 2);
  mpfr_set_si (x, -4, MPFR_RNDN);
  mpfr_nextbelow (x);
  mpfr_div_ui (y, x, 2, MPFR_RNDD);
  MPFR_ASSERTN(mpfr_cmp_si (y, -3) == 0);
  (mpfr_div_ui) (y, x, 2, MPFR_RNDD);
  MPFR_ASSERTN(mpfr_cmp_si (y, -3) == 0);

  for (xprec = 53; xprec <= 128; xprec++)
    {
      mpfr_set_prec (x, xprec);
      mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2");
      for (yprec = 53; yprec <= 128; yprec++)
        {
          mpfr_set_prec (y, yprec);
          mpfr_div_ui (y, x, 1, MPFR_RNDN);
          if (mpfr_cmp(x,y))
            {
              printf ("division by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec);
              printf ("expected "); mpfr_dump (x);
              printf ("got      "); mpfr_dump (y);
              exit (1);
            }
        }
    }

  /* Bug reported by Mark Dickinson, 6 Nov 2007 */
  mpfr_set_si (x, 0, MPFR_RNDN);
  mpfr_set_si (y, -1, MPFR_RNDN);
  mpfr_div_ui (y, x, 4, MPFR_RNDN);
  MPFR_ASSERTN(MPFR_IS_ZERO(y) && MPFR_IS_POS(y));
  (mpfr_div_ui) (y, x, 4, MPFR_RNDN);
  MPFR_ASSERTN(MPFR_IS_ZERO(y) && MPFR_IS_POS(y));

  mpfr_clear (x);
  mpfr_clear (y);
}
Example #25
0
static void
check_special (void)
{
  mpfr_t x, y;
  int res;
  char *s;

  mpfr_init (x);
  mpfr_init (y);

  /* Check dummy case */
  res = mpfr_strtofr (x, "1234567.89E1", NULL, 10, MPFR_RNDN);
  mpfr_set_str (y, "1234567.89E1", 10, MPFR_RNDN);
  if (mpfr_cmp (x, y))
    {
      printf ("Results differ between strtofr and set_str.\n"
              " set_str gives: ");
      mpfr_dump (y);
      printf (" strtofr gives: ");
      mpfr_dump (x);
      exit (1);
    }

  /* Check NAN  */
  mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
  res = mpfr_strtofr (x, "NaN", &s, 10, MPFR_RNDN);
  if (res != 0 || !mpfr_nan_p (x) || *s != 0)
    {
      printf ("Error for setting NAN (1)\n");
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
  res = mpfr_strtofr (x, "+NaN", &s, 10, MPFR_RNDN);
  if (res != 0 || !mpfr_nan_p (x) || *s != 0)
    {
      printf ("Error for setting +NAN (1)\n");
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
  res = mpfr_strtofr (x, " -NaN", &s, 10, MPFR_RNDN);
  if (res != 0 || !mpfr_nan_p (x) || *s != 0)
    {
      printf ("Error for setting -NAN (1)\n");
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
  res = mpfr_strtofr (x, "@nAn@xx", &s, 16, MPFR_RNDN);
  if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "xx") )
    {
      printf ("Error for setting NAN (2)\n");
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
  res = mpfr_strtofr (x, "NAN(abcdEDF__1256)Hello", &s, 10, MPFR_RNDN);
  if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "Hello") )
    {
      printf ("Error for setting NAN (3)\n");
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
  res = mpfr_strtofr (x, "NAN(abcdEDF)__1256)Hello", &s, 10, MPFR_RNDN);
  if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "__1256)Hello") )
    {
      printf ("Error for setting NAN (4)\n");
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
  res = mpfr_strtofr (x, "NAN(abc%dEDF)__1256)Hello", &s, 10, MPFR_RNDN);
  if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "(abc%dEDF)__1256)Hello") )
    {
      printf ("Error for setting NAN (5)\n");
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
  res = mpfr_strtofr (x, "NAN((abc))", &s, 10, MPFR_RNDN);
  if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "((abc))") )
    {
      printf ("Error for setting NAN (6)\n");
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
  res = mpfr_strtofr (x, "NAN()foo", &s, 10, MPFR_RNDN);
  if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "foo") )
    {
      printf ("Error for setting NAN (7)\n");
      exit (1);
    }

  /* Check INF */
  res = mpfr_strtofr (x, "INFINITY", &s, 8, MPFR_RNDN);
  if (res != 0 || !mpfr_inf_p (x) || *s != 0)
    {
      printf ("Error for setting INFINITY (1)\n s=%s\n x=", s);
      mpfr_dump (x);
      exit (1);
    }
  res = mpfr_strtofr (x, "INFANITY", &s, 8, MPFR_RNDN);
  if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "ANITY"))
    {
      printf ("Error for setting INFINITY (2)\n s=%s\n x=", s);
      mpfr_dump (x);
      exit (1);
    }
  res = mpfr_strtofr (x, "@INF@*2", &s, 11, MPFR_RNDN);
  if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "*2"))
    {
      printf ("Error for setting INFINITY (3)\n s=%s\n x=", s);
      mpfr_dump (x);
      exit (1);
    }

  /* Check Zero */
  res = mpfr_strtofr (x, " 00000", &s, 11, MPFR_RNDN);
  if (res != 0 || !mpfr_zero_p (x) || s[0] != 0)
    {
      printf ("Error for setting ZERO (1)\n s=%s\n x=", s);
      mpfr_dump (x);
      exit (1);
    }

  /* Check base 62 */
  res = mpfr_strtofr (x, "A", NULL, 62, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 10))
    {
      printf ("Error for setting 'A' in base 62\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }
  res = mpfr_strtofr (x, "a", NULL, 62, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 36))
    {
      printf ("Error for setting 'a' in base 62\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }
  res = mpfr_strtofr (x, "Z", NULL, 62, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 35))
    {
      printf ("Error for setting 'Z' in base 62\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }
  res = mpfr_strtofr (x, "z", NULL, 62, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 61))
    {
      printf ("Error for setting 'z' in base 62\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }
  res = mpfr_strtofr (x, "ZA", NULL, 62, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 2180))
    {
      printf ("Error for setting 'ZA' in base 62\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }
  res = mpfr_strtofr (x, "za", NULL, 62, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 3818))
    {
      printf ("Error for setting 'za' in base 62\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }
  res = mpfr_strtofr (x, "aZ", NULL, 62, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 2267))
    {
      printf ("Error for setting 'aZ' in base 62\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }
  res = mpfr_strtofr (x, "Az", NULL, 62, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 681))
    {
      printf ("Error for setting 'Az' in base 62\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }

  /* Check base 60 */
  res = mpfr_strtofr (x, "Aa", NULL, 60, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 636))
    {
      printf ("Error for setting 'Aa' in base 60\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }
  res = mpfr_strtofr (x, "Zz", &s, 60, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 35) || strcmp(s, "z") )
    {
      printf ("Error for setting 'Zz' in base 60\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }

  /* Check base 61 */
  res = mpfr_strtofr (x, "z", &s, 61, MPFR_RNDN);
  if (res != 0 || mpfr_cmp_ui (x, 0) || strcmp(s, "z") )
    {
      printf ("Error for setting 'z' in base 61\n x=");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      putchar ('\n');
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
Example #26
0
int
main (void)
{
  mpfr_t x;
  int r;
  mp_prec_t p;

  tests_start_mpfr ();

  special ();

  mpfr_init (x);

  for (p=2; p<100; p++)
    {
      mpfr_set_prec (x, p);
      for (r = 0; r < GMP_RND_MAX; r++)
        {
          mpfr_set_ui (x, 1, GMP_RNDN);
          mpfr_cbrt (x, x, (mp_rnd_t) r);
          if (mpfr_cmp_ui (x, 1))
            {
              printf ("Error in mpfr_cbrt for x=1, rnd=%s\ngot ",
                      mpfr_print_rnd_mode ((mp_rnd_t) r));
              mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
              printf ("\n");
              exit (1);
            }
          mpfr_set_si (x, -1, GMP_RNDN);
          mpfr_cbrt (x, x, (mp_rnd_t) r);
          if (mpfr_cmp_si (x, -1))
            {
              printf ("Error in mpfr_cbrt for x=-1, rnd=%s\ngot ",
                      mpfr_print_rnd_mode ((mp_rnd_t) r));
              mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
              printf ("\n");
              exit (1);
            }

          if (p >= 5)
            {
              int i;
              for (i = -12; i <= 12; i++)
                {
                  mpfr_set_ui (x, 27, GMP_RNDN);
                  mpfr_mul_2si (x, x, 3*i, GMP_RNDN);
                  mpfr_cbrt (x, x, GMP_RNDN);
                  if (mpfr_cmp_si_2exp (x, 3, i))
                    {
                      printf ("Error in mpfr_cbrt for "
                              "x = 27.0 * 2^(%d), rnd=%s\ngot ",
                              3*i, mpfr_print_rnd_mode ((mp_rnd_t) r));
                      mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
                      printf ("\ninstead of 3 * 2^(%d)\n", i);
                      exit (1);
                    }
                }
            }
        }
    }

  mpfr_clear (x);

  tests_end_mpfr ();
  return 0;
}
Example #27
0
File: tadd.c Project: qsnake/mpfr
static void
check_1111 (void)
{
    mpfr_t one;
    long n;

    mpfr_init2 (one, MPFR_PREC_MIN);
    mpfr_set_ui (one, 1, MPFR_RNDN);
    for (n = 0; n < NUM; n++)
    {
        mpfr_prec_t prec_a, prec_b, prec_c;
        mpfr_exp_t tb=0, tc, diff;
        mpfr_t a, b, c, s;
        int m = 512;
        int sb, sc;
        int inex_a, inex_s;
        mpfr_rnd_t rnd_mode;

        prec_a = MPFR_PREC_MIN + (randlimb () % m);
        prec_b = MPFR_PREC_MIN + (randlimb () % m);
        prec_c = MPFR_PREC_MIN + (randlimb () % m);
        mpfr_init2 (a, prec_a);
        mpfr_init2 (b, prec_b);
        mpfr_init2 (c, prec_c);
        sb = randlimb () % 3;
        if (sb != 0)
        {
            tb = 1 + (randlimb () % (prec_b - (sb != 2)));
            mpfr_div_2ui (b, one, tb, MPFR_RNDN);
            if (sb == 2)
                mpfr_neg (b, b, MPFR_RNDN);
            test_add (b, b, one, MPFR_RNDN);
        }
        else
            mpfr_set (b, one, MPFR_RNDN);
        tc = 1 + (randlimb () % (prec_c - 1));
        mpfr_div_2ui (c, one, tc, MPFR_RNDN);
        sc = randlimb () % 2;
        if (sc)
            mpfr_neg (c, c, MPFR_RNDN);
        test_add (c, c, one, MPFR_RNDN);
        diff = (randlimb () % (2*m)) - m;
        mpfr_mul_2si (c, c, diff, MPFR_RNDN);
        rnd_mode = RND_RAND ();
        inex_a = test_add (a, b, c, rnd_mode);
        mpfr_init2 (s, MPFR_PREC_MIN + 2*m);
        inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */
        if (inex_s)
        {
            printf ("check_1111: result should have been exact.\n");
            exit (1);
        }
        inex_s = mpfr_prec_round (s, prec_a, rnd_mode);
        if ((inex_a < 0 && inex_s >= 0) ||
                (inex_a == 0 && inex_s != 0) ||
                (inex_a > 0 && inex_s <= 0) ||
                !mpfr_equal_p (a, s))
        {
            printf ("check_1111: results are different.\n");
            printf ("prec_a = %d, prec_b = %d, prec_c = %d\n",
                    (int) prec_a, (int) prec_b, (int) prec_c);
            printf ("tb = %d, tc = %d, diff = %d, rnd = %s\n",
                    (int) tb, (int) tc, (int) diff,
                    mpfr_print_rnd_mode (rnd_mode));
            printf ("sb = %d, sc = %d\n", sb, sc);
            printf ("a = ");
            mpfr_print_binary (a);
            puts ("");
            printf ("s = ");
            mpfr_print_binary (s);
            puts ("");
            printf ("inex_a = %d, inex_s = %d\n", inex_a, inex_s);
            exit (1);
        }
        mpfr_clear (a);
        mpfr_clear (b);
        mpfr_clear (c);
        mpfr_clear (s);
    }
    mpfr_clear (one);
}
Example #28
0
static void
special (void)
{
  mpfr_t x, y;

  mpfr_init (x);
  mpfr_init (y);

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

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

  /* cbrt(-Inf) =  -Inf */
  mpfr_set_inf (x, -1);
  mpfr_cbrt (y, x, GMP_RNDN);
  if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0)
    {
      printf ("Error: cbrt(-Inf) <> -Inf\n");
      exit (1);
    }

  /* cbrt(+/-0) =  +/-0 */
  mpfr_set_ui (x, 0, GMP_RNDN);
  mpfr_cbrt (y, x, GMP_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
    {
      printf ("Error: cbrt(+0) <> +0\n");
      exit (1);
    }
  mpfr_neg (x, x, GMP_RNDN);
  mpfr_cbrt (y, x, GMP_RNDN);
  if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
    {
      printf ("Error: cbrt(-0) <> -0\n");
      exit (1);
    }

  mpfr_set_prec (x, 53);
  mpfr_set_str (x, "8.39005285514734966412e-01", 10, GMP_RNDN);
  mpfr_cbrt (x, x, GMP_RNDN);
  if (mpfr_cmp_str1 (x, "9.43166207799662426048e-01"))
    {
      printf ("Error in crbrt (1)\n");
      exit (1);
    }

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 32);
  mpfr_set_str_binary (x, "0.10000100001100101001001001011001");
  mpfr_cbrt (x, x, GMP_RNDN);
  mpfr_set_str_binary (y, "0.11001101011000100111000111111001");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in cbrt (2)\n");
      exit (1);
    }

  mpfr_set_prec (x, 32);
  mpfr_set_prec (y, 32);
  mpfr_set_str_binary (x, "-0.1100001110110000010101011001011");
  mpfr_cbrt (x, x, GMP_RNDD);
  mpfr_set_str_binary (y, "-0.11101010000100100101000101011001");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in cbrt (3)\n");
      exit (1);
    }

  mpfr_set_prec (x, 82);
  mpfr_set_prec (y, 27);
  mpfr_set_str_binary (x, "0.1010001111011101011011000111001011001101100011110110010011011011011010011001100101e-7");
  mpfr_cbrt (y, x, GMP_RNDD);
  mpfr_set_str_binary (x, "0.101011110001110001000100011E-2");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in cbrt (4)\n");
      exit (1);
    }

  mpfr_set_prec (x, 204);
  mpfr_set_prec (y, 38);
  mpfr_set_str_binary (x, "0.101000000001101000000001100111111011111001110110100001111000100110100111001101100111110001110001011011010110010011100101111001111100001010010100111011101100000011011000101100010000000011000101001010001001E-5");
  mpfr_cbrt (y, x, GMP_RNDD);
  mpfr_set_str_binary (x, "0.10001001111010011011101000010110110010E-1");
  if (mpfr_cmp (x, y))
    {
      printf ("Error in cbrt (5)\n");
      exit (1);
    }

  mpfr_clear (x);
  mpfr_clear (y);
}
Example #29
0
/* Implements asymptotic expansion for jn or yn (formulae 9.2.5 and 9.2.6
   from Abramowitz & Stegun).
   Assumes |z| > p log(2)/2, where p is the target precision
   (z can be negative only for jn).
   Return 0 if the expansion does not converge enough (the value 0 as inexact
   flag should not happen for normal input).
*/
static int
FUNCTION (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
{
  mpfr_t s, c, P, Q, t, iz, err_t, err_s, err_u;
  mpfr_prec_t w;
  long k;
  int inex, stop, diverge = 0;
  mpfr_exp_t err2, err;
  MPFR_ZIV_DECL (loop);

  mpfr_init (c);

  w = MPFR_PREC(res) + MPFR_INT_CEIL_LOG2(MPFR_PREC(res)) + 4;

  MPFR_ZIV_INIT (loop, w);
  for (;;)
    {
      mpfr_set_prec (c, w);
      mpfr_init2 (s, w);
      mpfr_init2 (P, w);
      mpfr_init2 (Q, w);
      mpfr_init2 (t, w);
      mpfr_init2 (iz, w);
      mpfr_init2 (err_t, 31);
      mpfr_init2 (err_s, 31);
      mpfr_init2 (err_u, 31);

      /* Approximate sin(z) and cos(z). In the following, err <= k means that
         the approximate value y and the true value x are related by
         y = x * (1 + u)^k with |u| <= 2^(-w), following Higham's method. */
      mpfr_sin_cos (s, c, z, MPFR_RNDN);
      if (MPFR_IS_NEG(z))
        mpfr_neg (s, s, MPFR_RNDN); /* compute jn/yn(|z|), fix sign later */
      /* The absolute error on s/c is bounded by 1/2 ulp(1/2) <= 2^(-w-1). */
      mpfr_add (t, s, c, MPFR_RNDN);
      mpfr_sub (c, s, c, MPFR_RNDN);
      mpfr_swap (s, t);
      /* now s approximates sin(z)+cos(z), and c approximates sin(z)-cos(z),
         with total absolute error bounded by 2^(1-w). */

      /* precompute 1/(8|z|) */
      mpfr_si_div (iz, MPFR_IS_POS(z) ? 1 : -1, z, MPFR_RNDN);   /* err <= 1 */
      mpfr_div_2ui (iz, iz, 3, MPFR_RNDN);

      /* compute P and Q */
      mpfr_set_ui (P, 1, MPFR_RNDN);
      mpfr_set_ui (Q, 0, MPFR_RNDN);
      mpfr_set_ui (t, 1, MPFR_RNDN); /* current term */
      mpfr_set_ui (err_t, 0, MPFR_RNDN); /* error on t */
      mpfr_set_ui (err_s, 0, MPFR_RNDN); /* error on P and Q (sum of errors) */
      for (k = 1, stop = 0; stop < 4; k++)
        {
          /* compute next term: t(k)/t(k-1) = (2n+2k-1)(2n-2k+1)/(8kz) */
          mpfr_mul_si (t, t, 2 * (n + k) - 1, MPFR_RNDN); /* err <= err_k + 1 */
          mpfr_mul_si (t, t, 2 * (n - k) + 1, MPFR_RNDN); /* err <= err_k + 2 */
          mpfr_div_ui (t, t, k, MPFR_RNDN);               /* err <= err_k + 3 */
          mpfr_mul (t, t, iz, MPFR_RNDN);                 /* err <= err_k + 5 */
          /* the relative error on t is bounded by (1+u)^(5k)-1, which is
             bounded by 6ku for 6ku <= 0.02: first |5 log(1+u)| <= |5.5u|
             for |u| <= 0.15, then |exp(5.5u)-1| <= 6u for |u| <= 0.02. */
          mpfr_mul_ui (err_t, t, 6 * k, MPFR_IS_POS(t) ? MPFR_RNDU : MPFR_RNDD);
          mpfr_abs (err_t, err_t, MPFR_RNDN); /* exact */
          /* the absolute error on t is bounded by err_t * 2^(-w) */
          mpfr_abs (err_u, t, MPFR_RNDU);
          mpfr_mul_2ui (err_u, err_u, w, MPFR_RNDU); /* t * 2^w */
          mpfr_add (err_u, err_u, err_t, MPFR_RNDU); /* max|t| * 2^w */
          if (stop >= 2)
            {
              /* take into account the neglected terms: t * 2^w */
              mpfr_div_2ui (err_s, err_s, w, MPFR_RNDU);
              if (MPFR_IS_POS(t))
                mpfr_add (err_s, err_s, t, MPFR_RNDU);
              else
                mpfr_sub (err_s, err_s, t, MPFR_RNDU);
              mpfr_mul_2ui (err_s, err_s, w, MPFR_RNDU);
              stop ++;
            }
          /* if k is odd, add to Q, otherwise to P */
          else if (k & 1)
            {
              /* if k = 1 mod 4, add, otherwise subtract */
              if ((k & 2) == 0)
                mpfr_add (Q, Q, t, MPFR_RNDN);
              else
                mpfr_sub (Q, Q, t, MPFR_RNDN);
              /* check if the next term is smaller than ulp(Q): if EXP(err_u)
                 <= EXP(Q), since the current term is bounded by
                 err_u * 2^(-w), it is bounded by ulp(Q) */
              if (MPFR_EXP(err_u) <= MPFR_EXP(Q))
                stop ++;
              else
                stop = 0;
            }
          else
            {
              /* if k = 0 mod 4, add, otherwise subtract */
              if ((k & 2) == 0)
                mpfr_add (P, P, t, MPFR_RNDN);
              else
                mpfr_sub (P, P, t, MPFR_RNDN);
              /* check if the next term is smaller than ulp(P) */
              if (MPFR_EXP(err_u) <= MPFR_EXP(P))
                stop ++;
              else
                stop = 0;
            }
          mpfr_add (err_s, err_s, err_t, MPFR_RNDU);
          /* the sum of the rounding errors on P and Q is bounded by
             err_s * 2^(-w) */

          /* stop when start to diverge */
          if (stop < 2 &&
              ((MPFR_IS_POS(z) && mpfr_cmp_ui (z, (k + 1) / 2) < 0) ||
               (MPFR_IS_NEG(z) && mpfr_cmp_si (z, - ((k + 1) / 2)) > 0)))
            {
              /* if we have to stop the series because it diverges, then
                 increasing the precision will most probably fail, since
                 we will stop to the same point, and thus compute a very
                 similar approximation */
              diverge = 1;
              stop = 2; /* force stop */
            }
        }
      /* the sum of the total errors on P and Q is bounded by err_s * 2^(-w) */

      /* Now combine: the sum of the rounding errors on P and Q is bounded by
         err_s * 2^(-w), and the absolute error on s/c is bounded by 2^(1-w) */
      if ((n & 1) == 0) /* n even: P * (sin + cos) + Q (cos - sin) for jn
                                   Q * (sin + cos) + P (sin - cos) for yn */
        {
#ifdef MPFR_JN
          mpfr_mul (c, c, Q, MPFR_RNDN); /* Q * (sin - cos) */
          mpfr_mul (s, s, P, MPFR_RNDN); /* P * (sin + cos) */
#else
          mpfr_mul (c, c, P, MPFR_RNDN); /* P * (sin - cos) */
          mpfr_mul (s, s, Q, MPFR_RNDN); /* Q * (sin + cos) */
#endif
          err = MPFR_EXP(c);
          if (MPFR_EXP(s) > err)
            err = MPFR_EXP(s);
#ifdef MPFR_JN
          mpfr_sub (s, s, c, MPFR_RNDN);
#else
          mpfr_add (s, s, c, MPFR_RNDN);
#endif
        }
      else /* n odd: P * (sin - cos) + Q (cos + sin) for jn,
                     Q * (sin - cos) - P (cos + sin) for yn */
        {
#ifdef MPFR_JN
          mpfr_mul (c, c, P, MPFR_RNDN); /* P * (sin - cos) */
          mpfr_mul (s, s, Q, MPFR_RNDN); /* Q * (sin + cos) */
#else
          mpfr_mul (c, c, Q, MPFR_RNDN); /* Q * (sin - cos) */
          mpfr_mul (s, s, P, MPFR_RNDN); /* P * (sin + cos) */
#endif
          err = MPFR_EXP(c);
          if (MPFR_EXP(s) > err)
            err = MPFR_EXP(s);
#ifdef MPFR_JN
          mpfr_add (s, s, c, MPFR_RNDN);
#else
          mpfr_sub (s, c, s, MPFR_RNDN);
#endif
        }
      if ((n & 2) != 0)
        mpfr_neg (s, s, MPFR_RNDN);
      if (MPFR_EXP(s) > err)
        err = MPFR_EXP(s);
      /* the absolute error on s is bounded by P*err(s/c) + Q*err(s/c)
         + err(P)*(s/c) + err(Q)*(s/c) + 3 * 2^(err - w - 1)
         <= (|P|+|Q|) * 2^(1-w) + err_s * 2^(1-w) + 2^err * 2^(1-w),
         since |c|, |old_s| <= 2. */
      err2 = (MPFR_EXP(P) >= MPFR_EXP(Q)) ? MPFR_EXP(P) + 2 : MPFR_EXP(Q) + 2;
      /* (|P| + |Q|) * 2^(1 - w) <= 2^(err2 - w) */
      err = MPFR_EXP(err_s) >= err ? MPFR_EXP(err_s) + 2 : err + 2;
      /* err_s * 2^(1-w) + 2^old_err * 2^(1-w) <= 2^err * 2^(-w) */
      err2 = (err >= err2) ? err + 1 : err2 + 1;
      /* now the absolute error on s is bounded by 2^(err2 - w) */

      /* multiply by sqrt(1/(Pi*z)) */
      mpfr_const_pi (c, MPFR_RNDN);     /* Pi, err <= 1 */
      mpfr_mul (c, c, z, MPFR_RNDN);    /* err <= 2 */
      mpfr_si_div (c, MPFR_IS_POS(z) ? 1 : -1, c, MPFR_RNDN); /* err <= 3 */
      mpfr_sqrt (c, c, MPFR_RNDN);      /* err<=5/2, thus the absolute error is
                                          bounded by 3*u*|c| for |u| <= 0.25 */
      mpfr_mul (err_t, c, s, MPFR_SIGN(c)==MPFR_SIGN(s) ? MPFR_RNDU : MPFR_RNDD);
      mpfr_abs (err_t, err_t, MPFR_RNDU);
      mpfr_mul_ui (err_t, err_t, 3, MPFR_RNDU);
      /* 3*2^(-w)*|old_c|*|s| [see below] is bounded by err_t * 2^(-w) */
      err2 += MPFR_EXP(c);
      /* |old_c| * 2^(err2 - w) [see below] is bounded by 2^(err2-w) */
      mpfr_mul (c, c, s, MPFR_RNDN);    /* the absolute error on c is bounded by
                                          1/2 ulp(c) + 3*2^(-w)*|old_c|*|s|
                                          + |old_c| * 2^(err2 - w) */
      /* compute err_t * 2^(-w) + 1/2 ulp(c) = (err_t + 2^EXP(c)) * 2^(-w) */
      err = (MPFR_EXP(err_t) > MPFR_EXP(c)) ? MPFR_EXP(err_t) + 1 : MPFR_EXP(c) + 1;
      /* err_t * 2^(-w) + 1/2 ulp(c) <= 2^(err - w) */
      /* now err_t * 2^(-w) bounds 1/2 ulp(c) + 3*2^(-w)*|old_c|*|s| */
      err = (err >= err2) ? err + 1 : err2 + 1;
      /* the absolute error on c is bounded by 2^(err - w) */

      mpfr_clear (s);
      mpfr_clear (P);
      mpfr_clear (Q);
      mpfr_clear (t);
      mpfr_clear (iz);
      mpfr_clear (err_t);
      mpfr_clear (err_s);
      mpfr_clear (err_u);

      err -= MPFR_EXP(c);
      if (MPFR_LIKELY (MPFR_CAN_ROUND (c, w - err, MPFR_PREC(res), r)))
        break;
      if (diverge != 0)
        {
          mpfr_set (c, z, r); /* will force inex=0 below, which means the
                               asymptotic expansion failed */
          break;
        }
      MPFR_ZIV_NEXT (loop, w);
    }
  MPFR_ZIV_FREE (loop);

  inex = (MPFR_IS_POS(z) || ((n & 1) == 0)) ? mpfr_set (res, c, r)
    : mpfr_neg (res, c, r);
  mpfr_clear (c);

  return inex;
}
Example #30
0
File: tdiv.c Project: cmjonze/mpfr
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);
}