static void check_overflow (void) { mpfr_t x, y, z1, z2; mpfr_exp_t emin, emax; emin = mpfr_get_emin (); emax = mpfr_get_emax (); set_emin (-1021); set_emax (1024); mpfr_inits (x, y, z1, z2, (mpfr_ptr) 0); mpfr_set_str1 (x, "8.00468257869324898448e+307"); mpfr_set_str1 (y, "7.44784712422708645156e+307"); mpfr_add1sp (z1, x, y, MPFR_RNDN); mpfr_add1 (z2, x, y, MPFR_RNDN); if (mpfr_cmp (z1, z2)) { printf ("Overflow bug in add1sp.\n"); exit (1); } mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); set_emin (emin); set_emax (emax); }
static void special_overflow (void) { mpfr_t x, y; mpfr_exp_t emin, emax; emin = mpfr_get_emin (); emax = mpfr_get_emax (); set_emin (-125); set_emax (128); mpfr_init2 (x, 24); mpfr_init2 (y, 48); mpfr_set_str_binary (x, "0.101100100000000000110100E0"); mpfr_asin (y, x, MPFR_RNDN); if (mpfr_cmp_str (y, "0.110001001101001111110000010110001000111011001000E0", 2, MPFR_RNDN)) { printf("Special Overflow error.\n"); mpfr_dump (y); exit (1); } mpfr_clear (y); mpfr_clear (x); set_emin (emin); set_emax (emax); }
/* This bug occurs in mpfr_exp_2 on a Linux-64 machine, r5475. */ static void bug20080731 (void) { mpfr_exp_t emin; mpfr_t x, y1, y2; mpfr_prec_t prec = 64; emin = mpfr_get_emin (); set_emin (MPFR_EMIN_MIN); mpfr_init2 (x, 200); mpfr_set_str (x, "-2.c5c85fdf473de6af278ece700fcbdabd03cd0cb9ca62d8b62c@7", 16, MPFR_RNDN); mpfr_init2 (y1, prec); mpfr_exp (y1, x, MPFR_RNDU); /* Compute the result with a higher internal precision. */ mpfr_init2 (y2, 300); mpfr_exp (y2, x, MPFR_RNDU); mpfr_prec_round (y2, prec, MPFR_RNDU); if (mpfr_cmp0 (y1, y2) != 0) { printf ("Error in bug20080731\nExpected "); mpfr_out_str (stdout, 16, 0, y2, MPFR_RNDN); printf ("\nGot "); mpfr_out_str (stdout, 16, 0, y1, MPFR_RNDN); printf ("\n"); exit (1); } mpfr_clears (x, y1, y2, (mpfr_ptr) 0); set_emin (emin); }
static void special_overflow (void) { mpfr_t x, y; int inex; mpfr_exp_t emin, emax; 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.101100100000000000110100E15"); inex = mpfr_exp2 (y, x, MPFR_RNDN); if (!mpfr_inf_p (y) || inex <= 0) { printf ("Overflow error.\n"); mpfr_dump (y); printf ("inex = %d\n", inex); exit (1); } mpfr_clear (y); mpfr_clear (x); set_emin (emin); set_emax (emax); }
static void check_emin_aux (mpfr_exp_t e) { mpfr_t x; char *s1, s2[256]; int i; mpfr_exp_t emin; mpz_t ee; MPFR_ASSERTN (e >= LONG_MIN); emin = mpfr_get_emin (); set_emin (e); mpfr_init2 (x, 16); mpz_init (ee); mpfr_setmin (x, e); mpz_set_si (ee, e); mpz_sub_ui (ee, ee, 1); i = mpfr_asprintf (&s1, "%Ra", x); MPFR_ASSERTN (i > 0); gmp_snprintf (s2, 256, "0x1p%Zd", ee); if (strcmp (s1, s2) != 0) { printf ("Error in check_emin_aux for emin = %ld\n", (long) e); printf ("Expected %s\n", s2); printf ("Got %s\n", s1); exit (1); } mpfr_free_str (s1); i = mpfr_asprintf (&s1, "%Rb", x); MPFR_ASSERTN (i > 0); gmp_snprintf (s2, 256, "1p%Zd", ee); if (strcmp (s1, s2) != 0) { printf ("Error in check_emin_aux for emin = %ld\n", (long) e); printf ("Expected %s\n", s2); printf ("Got %s\n", s1); exit (1); } mpfr_free_str (s1); mpfr_clear (x); mpz_clear (ee); set_emin (emin); }
static void special_overflow (void) { /* Check for overflow in 3 cases: 1. cosh(x) is representable, but not exp(x) 2. cosh(x) is not representable in the selected range of exp. 3. cosh(x) exp overflow even with the largest range of exp */ mpfr_t x, y; mp_exp_t emin, emax; 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_cosh (y, x, GMP_RNDN); if (mpfr_cmp_str (y, "0.101010001111001010001110E128", 2, GMP_RNDN)) { printf("Special overflow error 1.\n"); mpfr_dump (y); exit (1); } mpfr_set_str_binary (x, "0.101100100000000000110100E8"); mpfr_cosh (y, x, GMP_RNDN); if (!mpfr_inf_p(y)) { printf("Special overflow error 2.\n"); mpfr_dump (y); exit (1); } set_emin (emin); set_emax (emax); mpfr_set_str_binary (x, "0.101100100000000000110100E1000000"); mpfr_cosh (y, x, GMP_RNDN); if (!mpfr_inf_p(y)) { printf("Special overflow error 3.\n"); mpfr_dump (y); exit (1); } mpfr_clear (y); mpfr_clear (x); }
static void check_overflow (void) { mpfr_t sum1, sum2, x, y; mpfr_ptr t[2 * NOVFL]; mpfr_exp_t emin, emax; int i, r; emin = mpfr_get_emin (); emax = mpfr_get_emax (); set_emin (MPFR_EMIN_MIN); set_emax (MPFR_EMAX_MAX); mpfr_inits2 (32, sum1, sum2, x, y, (mpfr_ptr) 0); mpfr_setmax (x, mpfr_get_emax ()); mpfr_neg (y, x, MPFR_RNDN); for (i = 0; i < 2 * NOVFL; i++) t[i] = i < NOVFL ? x : y; /* Two kinds of test: * i = 1: overflow. * i = 2: intermediate overflow (exact sum is 0). */ for (i = 1; i <= 2; i++) RND_LOOP(r) { int inex1, inex2; inex1 = mpfr_add (sum1, x, i == 1 ? x : y, (mpfr_rnd_t) r); inex2 = mpfr_sum (sum2, t, i * NOVFL, (mpfr_rnd_t) r); MPFR_ASSERTN (mpfr_check (sum1)); MPFR_ASSERTN (mpfr_check (sum2)); if (!(mpfr_equal_p (sum1, sum2) && SAME_SIGN (inex1, inex2))) { printf ("Error in check_overflow on %s, i = %d\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); printf ("Expected "); mpfr_dump (sum1); printf ("with inex = %d\n", inex1); printf ("Got "); mpfr_dump (sum2); printf ("with inex = %d\n", inex2); exit (1); } } mpfr_clears (sum1, sum2, x, y, (mpfr_ptr) 0); set_emin (emin); set_emax (emax); }
static void check_large (void) { mpz_t z; mpfr_t x, y; mpfr_exp_t emax, emin; mpz_init (z); mpfr_init2 (x, 160); mpfr_init2 (y, 160); mpz_set_str (z, "77031627725494291259359895954016675357279104942148788042", 10); mpfr_set_z (x, z, MPFR_RNDN); mpfr_set_str_binary (y, "0.1100100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111000001001E186"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_set_z on large input\n"); exit (1); } /* check overflow */ emax = mpfr_get_emax (); set_emax (2); mpz_set_str (z, "7", 10); mpfr_set_z (x, z, MPFR_RNDU); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); set_emax (3); mpfr_set_prec (x, 2); mpz_set_str (z, "7", 10); mpfr_set_z (x, z, MPFR_RNDU); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); set_emax (emax); /* check underflow */ emin = mpfr_get_emin (); set_emin (3); mpz_set_str (z, "1", 10); mpfr_set_z (x, z, MPFR_RNDZ); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); set_emin (2); mpfr_set_z (x, z, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); set_emin (emin); mpz_clear (z); mpfr_clear (x); mpfr_clear (y); }
static void underflow (void) { mpfr_exp_t emin; underflow_up (0); emin = mpfr_get_emin (); set_emin (MPFR_EMIN_MIN); if (mpfr_get_emin () != emin) { underflow_up (1); set_emin (emin); } }
static void check_emin_emax (void) { mpfr_exp_t old_emin, old_emax; old_emin = mpfr_get_emin (); old_emax = mpfr_get_emax (); /* Check the functions not the macros ! */ if ((mpfr_set_emin)(MPFR_EMIN_MIN) != 0) ERROR("set_emin failed!"); if ((mpfr_get_emin)() != MPFR_EMIN_MIN) ERROR("get_emin FAILED!"); if ((mpfr_set_emin)(MPFR_EMIN_MIN-1) == 0) ERROR("set_emin failed! (2)"); if ((mpfr_set_emax)(MPFR_EMAX_MAX) != 0) ERROR("set_emax failed!"); if ((mpfr_get_emax)() != MPFR_EMAX_MAX) ERROR("get_emax FAILED!"); if ((mpfr_set_emax)(MPFR_EMAX_MAX+1) == 0) ERROR("set_emax failed! (2)"); if ((mpfr_get_emin_min) () != MPFR_EMIN_MIN) ERROR ("get_emin_min"); if ((mpfr_get_emin_max) () != MPFR_EMIN_MAX) ERROR ("get_emin_max"); if ((mpfr_get_emax_min) () != MPFR_EMAX_MIN) ERROR ("get_emax_min"); if ((mpfr_get_emax_max) () != MPFR_EMAX_MAX) ERROR ("get_emax_max"); set_emin (old_emin); set_emax (old_emax); }
static void mpfr_set_double_range (void) { mpfr_set_default_prec (54); if (mpfr_get_default_prec () != 54) ERROR ("get_default_prec failed (1)"); mpfr_set_default_prec (53); if ((mpfr_get_default_prec) () != 53) ERROR ("get_default_prec failed (2)"); /* in double precision format, the unbiased exponent is between 0 and 2047, where 0 is used for subnormal numbers, and 2047 for special numbers (infinities, NaN), and the bias is 1023, thus "normal" numbers have an exponent between -1022 and 1023, corresponding to numbers between 2^(-1022) and previous(2^(1024)). (The smallest subnormal number is 0.(0^51)1*2^(-1022)= 2^(-1074).) The smallest normal power of two is 1.0*2^(-1022). The largest normal power of two is 2^1023. (We have to add one for mpfr since mantissa are between 1/2 and 1.) */ set_emin (-1021); set_emax (1024); }
/* bug found by Kevin P. Rauch on 22 Oct 2007 */ static void check2 (void) { mpfr_t x, y, z; int tern; mpfr_exp_t emin; emin = mpfr_get_emin (); mpfr_init2 (x, 32); mpfr_init2 (y, 32); mpfr_init2 (z, 32); mpfr_set_ui (x, 0xC0000000U, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); mpfr_set_ui (y, 0xFFFFFFFEU, MPFR_RNDN); mpfr_set_exp (x, 0); mpfr_set_exp (y, 0); mpfr_set_emin (-29); tern = mpfr_mul (z, x, y, MPFR_RNDN); /* z = -0.BFFFFFFE, tern > 0 */ tern = mpfr_subnormalize (z, tern, MPFR_RNDN); /* z should be -0.75 */ MPFR_ASSERTN (tern < 0 && mpfr_cmp_si_2exp (z, -3, -2) == 0); mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); MPFR_ASSERTN (mpfr_get_emin () == -29); set_emin (emin); }
/* https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00008.html * Incorrect flags (in debug mode on a 32-bit machine, assertion failure). */ static void reduced_expo_range (void) { mpfr_exp_t emin, emax; mpfr_t x, y, ex_y; int inex, ex_inex; unsigned int flags, ex_flags; emin = mpfr_get_emin (); emax = mpfr_get_emax (); mpfr_inits2 (12, x, y, ex_y, (mpfr_ptr) 0); mpfr_set_str (x, "0.1e-5", 2, MPFR_RNDN); set_emin (-5); set_emax (-5); mpfr_clear_flags (); inex = mpfr_atan (y, x, MPFR_RNDN); flags = __gmpfr_flags; set_emin (emin); set_emax (emax); mpfr_set_str (ex_y, "0.1e-5", 2, MPFR_RNDN); ex_inex = 1; ex_flags = MPFR_FLAGS_INEXACT; if (SIGN (inex) != ex_inex || flags != ex_flags || ! mpfr_equal_p (y, ex_y)) { printf ("Error in reduced_expo_range\non x = "); mpfr_dump (x); printf ("Expected y = "); mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN); printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags); printf ("Got y = "); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags); exit (1); } mpfr_clears (x, y, ex_y, (mpfr_ptr) 0); }
/* bug found by Kevin P. Rauch on 22 Oct 2007 */ static void check3 (void) { mpfr_t x, y, z; int tern; mpfr_exp_t emin; emin = mpfr_get_emin (); mpfr_init2 (x, 32); mpfr_init2 (y, 32); mpfr_init2 (z, 32); mpfr_set_ui (x, 0xBFFFFFFFU, MPFR_RNDN); /* 3221225471/2^32 */ mpfr_set_ui (y, 0x80000001U, MPFR_RNDN); /* 2147483649/2^32 */ mpfr_set_exp (x, 0); mpfr_set_exp (y, 0); mpfr_set_emin (-1); /* the exact product is 6917529028714823679/2^64, which is rounded to 3/8 = 0.375, which is smaller, thus tern < 0 */ tern = mpfr_mul (z, x, y, MPFR_RNDN); MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0); tern = mpfr_subnormalize (z, tern, MPFR_RNDN); /* since emin = -1, and EXP(z)=-1, z should be rounded to precision EXP(z)-emin+1 = 1, i.e., z should be a multiple of the smallest possible positive representable value with emin=-1, which is 1/4. The two possible values are 1/4 and 2/4, which are at equal distance of z. But since tern < 0, we should choose the largest value, i.e., 2/4. */ MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0); /* here is another test for the alternate case, where z was rounded up first, thus we have to round down */ mpfr_set_str_binary (x, "0.11111111111010110101011011011011"); mpfr_set_str_binary (y, "0.01100000000001111100000000001110"); tern = mpfr_mul (z, x, y, MPFR_RNDN); MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0); tern = mpfr_subnormalize (z, tern, MPFR_RNDN); MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 1, -2) == 0); /* finally the case where z was exact, which we simulate here */ mpfr_set_ui_2exp (z, 3, -3, MPFR_RNDN); tern = mpfr_subnormalize (z, 0, MPFR_RNDN); MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0); mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); MPFR_ASSERTN (mpfr_get_emin () == -1); set_emin (emin); }
int main (int argc, char *argv[]) { mpfr_t x; int ret; mpfr_exp_t emin, emax; tests_start_mpfr (); emin = mpfr_get_emin (); emax = mpfr_get_emax (); mpfr_init (x); mpfr_set_ui (x, 1, MPFR_RNDN); ret = mpfr_set_exp (x, 2); MPFR_ASSERTN(ret == 0 && mpfr_cmp_ui (x, 2) == 0); set_emin (-1); ret = mpfr_set_exp (x, -1); MPFR_ASSERTN(ret == 0 && mpfr_cmp_ui_2exp (x, 1, -2) == 0); set_emax (1); ret = mpfr_set_exp (x, 1); MPFR_ASSERTN(ret == 0 && mpfr_cmp_ui (x, 1) == 0); ret = mpfr_set_exp (x, -2); MPFR_ASSERTN(ret != 0 && mpfr_cmp_ui (x, 1) == 0); ret = mpfr_set_exp (x, 2); MPFR_ASSERTN(ret != 0 && mpfr_cmp_ui (x, 1) == 0); mpfr_clear (x); set_emin (emin); set_emax (emax); tests_end_mpfr (); return 0; }
static void exp_range (void) { mpfr_t x; mpfr_exp_t emin; emin = mpfr_get_emin (); set_emin (3); mpfr_init2 (x, 8); mpfr_set_ui (x, 5, MPFR_RNDN); mpfr_exp2 (x, x, MPFR_RNDN); set_emin (emin); if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 32) != 0) { printf ("Error in mpfr_exp2 for x = 5, with emin = 3\n"); printf ("Expected 32, got "); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\n"); exit (1); } mpfr_clear (x); }
static void special_overflow (void) { mpfr_t x, y; mpfr_exp_t emin, emax; emin = mpfr_get_emin (); emax = mpfr_get_emax (); mpfr_init2 (x, 24); mpfr_init2 (y, 73); /* Check special case: An overflow in const_pi could occurs! */ set_emin (-125); set_emax (128); mpfr_set_str_binary (x, "0.111101010110110011101101E6"); test_cos (y, x, MPFR_RNDZ); set_emin (emin); set_emax (emax); mpfr_clear (x); mpfr_clear (y); }
static void check_flags (void) { mpfr_t x; mpfr_exp_t old_emin, old_emax; old_emin = mpfr_get_emin (); old_emax = mpfr_get_emax (); mpfr_init (x); /* Check the functions not the macros ! */ (mpfr_clear_flags)(); mpfr_set_double_range (); mpfr_set_ui (x, 1, MPFR_RNDN); (mpfr_clear_overflow)(); mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); if (!(mpfr_overflow_p)()) ERROR("ERROR: No overflow detected!\n"); (mpfr_clear_underflow)(); mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_div_2exp (x, x, 1025, MPFR_RNDN); if (!(mpfr_underflow_p)()) ERROR("ERROR: No underflow detected!\n"); (mpfr_clear_nanflag)(); MPFR_SET_NAN(x); mpfr_add (x, x, x, MPFR_RNDN); if (!(mpfr_nanflag_p)()) ERROR("ERROR: No NaN flag!\n"); (mpfr_clear_inexflag)(); mpfr_set_ui(x, 2, MPFR_RNDN); mpfr_cos(x, x, MPFR_RNDN); if (!(mpfr_inexflag_p)()) ERROR("ERROR: No inexact flag!\n"); (mpfr_clear_erangeflag) (); mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); mpfr_get_ui (x, MPFR_RNDN); if (!(mpfr_erangeflag_p)()) ERROR ("ERROR: No erange flag!\n"); mpfr_clear (x); set_emin (old_emin); set_emax (old_emax); }
static void alltst (void) { mpfr_exp_t emin, emax; ext = 0; test_small (); test_large_small (); check_overflow (); emin = mpfr_get_emin (); emax = mpfr_get_emax (); set_emin (MPFR_EMIN_MIN); set_emax (MPFR_EMAX_MAX); if (mpfr_get_emin () != emin || mpfr_get_emax () != emax) { ext = 1; test_small (); test_large_small (); check_overflow (); set_emin (emin); set_emax (emax); } }
static void alltst (void) { mpfr_exp_t emin, emax; ext = 0; tst (); underflow_up (); overflow_inv (); emin = mpfr_get_emin (); emax = mpfr_get_emax (); set_emin (MPFR_EMIN_MIN); set_emax (MPFR_EMAX_MAX); if (mpfr_get_emin () != emin || mpfr_get_emax () != emax) { ext = 1; tst (); underflow_up (); overflow_inv (); set_emin (emin); set_emax (emax); } }
static void check_underflow (void) { mpfr_t a; mp_exp_t emin, emax; int res; mpfr_init (a); /* Check underflow */ emin = mpfr_get_emin (); set_emin (-20); res = mpfr_set_str (a, "0.00000000001", 10, GMP_RNDZ); if (!MPFR_IS_ZERO (a)) { printf("ERROR for mpfr_set_str (a, \"0.00000000001\", 10, GMP_RNDN)\n" " with emin=-20\n" "res=%d\n", res); mpfr_dump (a); exit (1); } set_emin (emin); /* check overflow */ emax = mpfr_get_emax (); set_emax (1073741823); /* 2^30-1 */ mpfr_set_str (a, "2E1000000000", 10, GMP_RNDN); if (!mpfr_inf_p (a) || mpfr_sgn (a) < 0) { printf("ERROR for mpfr_set_str (a, \"2E1000000000\", 10, GMP_RNDN);\n"); exit (1); } set_emax (emax); mpfr_clear (a); }
static void check_max(void) { mpfr_t xx, yy, zz; mpfr_exp_t emin; mpfr_init2(xx, 4); mpfr_init2(yy, 4); mpfr_init2(zz, 4); mpfr_set_str1 (xx, "0.68750"); mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, MPFR_RNDN); mpfr_set_str1 (yy, "0.68750"); mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, MPFR_RNDN); mpfr_clear_flags(); test_mul(zz, xx, yy, MPFR_RNDU); if (!(mpfr_overflow_p() && MPFR_IS_INF(zz))) { printf("check_max failed (should be an overflow)\n"); exit(1); } mpfr_clear_flags(); test_mul(zz, xx, yy, MPFR_RNDD); if (mpfr_overflow_p() || MPFR_IS_INF(zz)) { printf("check_max failed (should NOT be an overflow)\n"); exit(1); } mpfr_set_str1 (xx, "0.93750"); mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, MPFR_RNDN); if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz))) { printf("check_max failed (internal error)\n"); exit(1); } if (mpfr_cmp(xx, zz) != 0) { printf("check_max failed: got "); mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ); printf(" instead of "); mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ); printf("\n"); exit(1); } /* check underflow */ emin = mpfr_get_emin (); set_emin (0); mpfr_set_str_binary (xx, "0.1E0"); mpfr_set_str_binary (yy, "0.1E0"); test_mul (zz, xx, yy, MPFR_RNDN); /* exact result is 0.1E-1, which should round to 0 */ MPFR_ASSERTN(mpfr_cmp_ui (zz, 0) == 0 && MPFR_IS_POS(zz)); set_emin (emin); /* coverage test for mpfr_powerof2_raw */ emin = mpfr_get_emin (); set_emin (0); mpfr_set_prec (xx, mp_bits_per_limb + 1); mpfr_set_str_binary (xx, "0.1E0"); mpfr_nextabove (xx); mpfr_set_str_binary (yy, "0.1E0"); test_mul (zz, xx, yy, MPFR_RNDN); /* exact result is just above 0.1E-1, which should round to minfloat */ MPFR_ASSERTN(mpfr_cmp (zz, yy) == 0); set_emin (emin); mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz); }
static void test_urandomb (long nbtests, mpfr_prec_t prec, int verbose) { mpfr_t x; int *tab, size_tab, k, sh, xn; double d, av = 0, var = 0, chi2 = 0, th; mpfr_exp_t emin; size_tab = (nbtests >= 1000 ? nbtests / 50 : 20); tab = (int *) calloc (size_tab, sizeof(int)); if (tab == NULL) { fprintf (stderr, "trandom: can't allocate memory in test_urandomb\n"); exit (1); } mpfr_init2 (x, prec); xn = 1 + (prec - 1) / mp_bits_per_limb; sh = xn * mp_bits_per_limb - prec; for (k = 0; k < nbtests; k++) { mpfr_urandomb (x, RANDS); /* check that lower bits are zero */ if (MPFR_MANT(x)[0] & MPFR_LIMB_MASK(sh)) { printf ("Error: mpfr_urandomb() returns invalid numbers:\n"); mpfr_print_binary (x); puts (""); exit (1); } d = mpfr_get_d1 (x); av += d; var += d*d; tab[(int)(size_tab * d)]++; } /* coverage test */ emin = mpfr_get_emin (); set_emin (1); /* the generated number in [0,1[ is not in the exponent range, except if it is zero */ k = mpfr_urandomb (x, RANDS); if (MPFR_IS_ZERO(x) == 0 && (k == 0 || mpfr_nan_p (x) == 0)) { printf ("Error in mpfr_urandomb, expected NaN, got "); mpfr_dump (x); exit (1); } set_emin (emin); mpfr_clear (x); if (!verbose) { free(tab); return; } av /= nbtests; var = (var / nbtests) - av * av; th = (double)nbtests / size_tab; printf("Average = %.5f\nVariance = %.5f\n", av, var); printf("Repartition for urandomb. Each integer should be close to %d.\n", (int)th); for (k = 0; k < size_tab; k++) { chi2 += (tab[k] - th) * (tab[k] - th) / th; printf("%d ", tab[k]); if (((k+1) & 7) == 0) printf("\n"); } printf("\nChi2 statistics value (with %d degrees of freedom) : %.5f\n\n", size_tab - 1, chi2); free(tab); return; }
static void underflowed_cothinf (void) { mpfr_t x, y; int i, inex, rnd, err = 0; mpfr_exp_t old_emin; old_emin = mpfr_get_emin (); mpfr_init2 (x, 8); mpfr_init2 (y, 8); for (i = -1; i <= 1; i += 2) RND_LOOP (rnd) { mpfr_set_inf (x, i); mpfr_clear_flags (); set_emin (2); /* 1 is not representable. */ inex = mpfr_coth (x, x, (mpfr_rnd_t) rnd); set_emin (old_emin); if (! mpfr_underflow_p ()) { printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" " The underflow flag is not set.\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } mpfr_set_si (y, (i < 0 && (rnd == MPFR_RNDD || rnd == MPFR_RNDA)) || (i > 0 && (rnd == MPFR_RNDU || rnd == MPFR_RNDA)) ? 2 : 0, MPFR_RNDN); if (i < 0) mpfr_neg (y, y, MPFR_RNDN); if (! (mpfr_equal_p (x, y) && MPFR_MULT_SIGN (MPFR_SIGN (x), MPFR_SIGN (y)) > 0)) { printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_print_binary (x); printf (" instead of "); mpfr_print_binary (y); printf (".\n"); err = 1; } if ((rnd == MPFR_RNDD || (i > 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex >= 0) { printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" " The inexact value must be negative.\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if ((rnd == MPFR_RNDU || (i < 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex <= 0) { printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" " The inexact value must be positive.\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } } if (err) exit (1); mpfr_clear (x); mpfr_clear (y); }
static void special_overflow (void) { mpfr_t x, y; mp_exp_t emin, emax; int inex; emin = mpfr_get_emin (); emax = mpfr_get_emax (); set_emin (-125); set_emax (128); mpfr_init2 (x, 24); mpfr_init2 (y, 24); mpfr_set_str_binary (x, "0.101100100000000000110100E7"); mpfr_gamma (y, x, GMP_RNDN); if (!mpfr_inf_p (y)) { printf ("Overflow error.\n"); mpfr_dump (y); exit (1); } /* problem mentioned by Kenneth Wilder, 18 Aug 2005 */ mpfr_set_prec (x, 29); mpfr_set_prec (y, 29); mpfr_set_str (x, "-200000000.5", 10, GMP_RNDN); /* exact */ mpfr_gamma (y, x, GMP_RNDN); if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0)) { printf ("Error for gamma(-200000000.5)\n"); printf ("expected -0"); printf ("got "); mpfr_dump (y); exit (1); } mpfr_set_prec (x, 53); mpfr_set_prec (y, 53); mpfr_set_str (x, "-200000000.1", 10, GMP_RNDN); mpfr_gamma (y, x, GMP_RNDN); if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0)) { printf ("Error for gamma(-200000000.1), prec=53\n"); printf ("expected -0"); printf ("got "); mpfr_dump (y); exit (1); } /* another problem mentioned by Kenneth Wilder, 29 Aug 2005 */ mpfr_set_prec (x, 333); mpfr_set_prec (y, 14); mpfr_set_str (x, "-2.0000000000000000000000005", 10, GMP_RNDN); mpfr_gamma (y, x, GMP_RNDN); mpfr_set_prec (x, 14); mpfr_set_str_binary (x, "-11010011110001E66"); if (mpfr_cmp (x, y)) { printf ("Error for gamma(-2.0000000000000000000000005)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } /* another tests from Kenneth Wilder, 31 Aug 2005 */ set_emax (200); set_emin (-200); mpfr_set_prec (x, 38); mpfr_set_prec (y, 54); mpfr_set_str_binary (x, "0.11101111011100111101001001010110101001E-166"); mpfr_gamma (y, x, GMP_RNDN); mpfr_set_prec (x, 54); mpfr_set_str_binary (x, "0.100010001101100001110110001010111111010000100101011E167"); if (mpfr_cmp (x, y)) { printf ("Error for gamma (test 1)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } set_emax (1000); set_emin (-2000); mpfr_set_prec (x, 38); mpfr_set_prec (y, 71); mpfr_set_str_binary (x, "10101011011100001111111000010111110010E-1034"); /* 184083777010*2^(-1034) */ mpfr_gamma (y, x, GMP_RNDN); mpfr_set_prec (x, 71); mpfr_set_str_binary (x, "10111111001000011110010001000000000000110011110000000011101011111111100E926"); /* 1762885132679550982140*2^926 */ if (mpfr_cmp (x, y)) { printf ("Error for gamma (test 2)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } mpfr_set_prec (x, 38); mpfr_set_prec (y, 88); mpfr_set_str_binary (x, "10111100111001010000100001100100100101E-104"); /* 202824096037*2^(-104) */ mpfr_gamma (y, x, GMP_RNDN); mpfr_set_prec (x, 88); mpfr_set_str_binary (x, "1010110101111000111010111100010110101010100110111000001011000111000011101100001101110010E-21"); /* 209715199999500283894743922*2^(-21) */ if (mpfr_cmp (x, y)) { printf ("Error for gamma (test 3)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } mpfr_set_prec (x, 171); mpfr_set_prec (y, 38); mpfr_set_str (x, "-2993155353253689176481146537402947624254601559176535", 10, GMP_RNDN); mpfr_div_2exp (x, x, 170, GMP_RNDN); mpfr_gamma (y, x, GMP_RNDN); mpfr_set_prec (x, 38); mpfr_set_str (x, "201948391737", 10, GMP_RNDN); mpfr_mul_2exp (x, x, 92, GMP_RNDN); if (mpfr_cmp (x, y)) { printf ("Error for gamma (test 5)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } set_emin (-500000); mpfr_set_prec (x, 337); mpfr_set_prec (y, 38); mpfr_set_str (x, "-30000.000000000000000000000000000000000000000000001", 10, GMP_RNDN); mpfr_gamma (y, x, GMP_RNDN); mpfr_set_prec (x, 38); mpfr_set_str (x, "-3.623795987425E-121243", 10, GMP_RNDN); if (mpfr_cmp (x, y)) { printf ("Error for gamma (test 7)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } /* was producing infinite loop */ set_emin (emin); mpfr_set_prec (x, 71); mpfr_set_prec (y, 71); mpfr_set_str (x, "-200000000.1", 10, GMP_RNDN); mpfr_gamma (y, x, GMP_RNDN); if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0)) { printf ("Error for gamma (test 8)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } set_emax (1073741823); mpfr_set_prec (x, 29); mpfr_set_prec (y, 29); mpfr_set_str (x, "423786866", 10, GMP_RNDN); mpfr_gamma (y, x, GMP_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) { printf ("Error for gamma(423786866)\n"); exit (1); } /* check exact result */ mpfr_set_prec (x, 2); mpfr_set_ui (x, 3, GMP_RNDN); inex = mpfr_gamma (x, x, GMP_RNDN); if (inex != 0 || mpfr_cmp_ui (x, 2) != 0) { printf ("Error for gamma(3)\n"); exit (1); } mpfr_set_emax (1024); mpfr_set_prec (x, 53); mpfr_set_prec (y, 53); mpfr_set_str_binary (x, "101010110100110011111010000110001000111100000110101E-43"); mpfr_gamma (x, x, GMP_RNDU); mpfr_set_str_binary (y, "110000011110001000111110110101011110000100001111111E971"); if (mpfr_cmp (x, y) != 0) { printf ("Error for gamma(4)\n"); printf ("expected "); mpfr_dump (y); printf ("got "); mpfr_dump (x); exit (1); } mpfr_clear (y); mpfr_clear (x); set_emin (emin); set_emax (emax); }
int main (int argc, char *argv[]) { mpfr_t x, y; mpfr_exp_t emin, emax; tests_start_mpfr (); special_overflow (); emax_m_eps (); exp_range (); mpfr_init (x); mpfr_init (y); mpfr_set_ui (x, 4, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 16) != 0) { printf ("Error for 2^4, MPFR_RNDN\n"); exit (1); } mpfr_exp2 (y, x, MPFR_RNDD); if (mpfr_cmp_ui (y, 16) != 0) { printf ("Error for 2^4, MPFR_RNDD\n"); exit (1); } mpfr_exp2 (y, x, MPFR_RNDU); if (mpfr_cmp_ui (y, 16) != 0) { printf ("Error for 2^4, MPFR_RNDU\n"); exit (1); } mpfr_set_si (x, -4, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) { printf ("Error for 2^(-4), MPFR_RNDN\n"); exit (1); } mpfr_exp2 (y, x, MPFR_RNDD); if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) { printf ("Error for 2^(-4), MPFR_RNDD\n"); exit (1); } mpfr_exp2 (y, x, MPFR_RNDU); if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) { printf ("Error for 2^(-4), MPFR_RNDU\n"); exit (1); } mpfr_set_prec (x, 53); mpfr_set_prec (y, 53); mpfr_set_str (x, /*-1683977482443233.0 / 2199023255552.0*/ "-7.6578429909351734750089235603809357e2", 10, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (mpfr_cmp_str1 (y, "2.991959870867646566478e-231")) { printf ("Error for x=-1683977482443233/2^41\n"); exit (1); } mpfr_set_prec (x, 10); mpfr_set_prec (y, 10); /* save emin */ emin = mpfr_get_emin (); set_emin (-10); mpfr_set_si (x, -12, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) { printf ("Error for x=emin-2, RNDN\n"); printf ("Expected +0\n"); printf ("Got "); mpfr_print_binary (y); puts (""); exit (1); } /* restore emin */ set_emin (emin); /* save emax */ emax = mpfr_get_emax (); set_emax (10); mpfr_set_ui (x, 11, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) { printf ("Error for x=emax+1, RNDN\n"); exit (1); } /* restore emax */ set_emax (emax); MPFR_SET_INF(x); MPFR_SET_POS(x); mpfr_exp2 (y, x, MPFR_RNDN); if(!MPFR_IS_INF(y)) { printf ("evaluation of function in INF does not return INF\n"); exit (1); } MPFR_CHANGE_SIGN(x); mpfr_exp2 (y, x, MPFR_RNDN); if(!MPFR_IS_ZERO(y)) { printf ("evaluation of function in -INF does not return 0\n"); exit (1); } MPFR_SET_NAN(x); mpfr_exp2 (y, x, MPFR_RNDN); if(!MPFR_IS_NAN(y)) { printf ("evaluation of function in NaN does not return NaN\n"); exit (1); } if ((mpfr_uexp_t) 8 << 31 != 0 || mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000) { /* emax <= 10000000000 */ mpfr_set_prec (x, 40); mpfr_set_prec (y, 40); mpfr_set_str (x, "10000000000.5", 10, MPFR_RNDN); mpfr_clear_flags (); mpfr_exp2 (y, x, MPFR_RNDN); if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && mpfr_overflow_p ())) { printf ("exp2(10000000000.5) should overflow.\n"); exit (1); } } mpfr_set_prec (x, 2); mpfr_set_prec (y, 2); mpfr_set_str_binary (x, "-1.0E-26"); mpfr_exp2 (y, x, MPFR_RNDD); mpfr_set_str_binary (x, "1.1E-1"); if (mpfr_cmp (x, y)) { printf ("Error for exp(-2^(-26)) for prec=2\n"); exit (1); } test_generic (2, 100, 100); mpfr_clear (x); mpfr_clear (y); overflowed_exp2_0 (); data_check ("data/exp2", mpfr_exp2, "mpfr_exp2"); tests_end_mpfr (); return 0; }
static void check4 (const char *as, const char *bs, mpfr_rnd_t rnd_mode, const char *res, int inex) { mpfr_t ta, tb, tc, tres; mpfr_exp_t emin, emax; int i; emin = mpfr_get_emin (); emax = mpfr_get_emax (); mpfr_inits2 (53, ta, tb, tc, tres, (mpfr_ptr) 0); for (i = 0; i <= 2; i++) { unsigned int expflags, newflags; int inex2; mpfr_set_str1 (ta, as); mpfr_set_str1 (tb, bs); mpfr_set_str1 (tc, res); if (i > 0) { mpfr_exp_t ea, eb, ec, e0; set_emin (MPFR_EMIN_MIN); set_emax (MPFR_EMAX_MAX); ea = mpfr_get_exp (ta); eb = mpfr_get_exp (tb); ec = mpfr_get_exp (tc); e0 = i == 1 ? __gmpfr_emin : __gmpfr_emax; if ((i == 1 && ea < eb) || (i == 2 && ea > eb)) { mpfr_set_exp (ta, e0); mpfr_set_exp (tb, e0 + (eb - ea)); mpfr_set_exp (tc, e0 + (ec - ea)); } else { mpfr_set_exp (ta, e0 + (ea - eb)); mpfr_set_exp (tb, e0); mpfr_set_exp (tc, e0 + (ec - eb)); } } __gmpfr_flags = expflags = (randlimb () & 1) ? MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE : 0; inex2 = mpfr_agm (tres, ta, tb, rnd_mode); newflags = __gmpfr_flags; expflags |= MPFR_FLAGS_INEXACT; if (SIGN (inex2) != inex || newflags != expflags || ! mpfr_equal_p (tres, tc)) { printf ("mpfr_agm failed in rnd_mode=%s for\n", mpfr_print_rnd_mode (rnd_mode)); printf (" a = "); mpfr_out_str (stdout, 10, 0, ta, MPFR_RNDN); printf ("\n"); printf (" b = "); mpfr_out_str (stdout, 10, 0, tb, MPFR_RNDN); printf ("\n"); printf ("expected inex = %d, flags = %u,\n" " ", inex, expflags); mpfr_dump (tc); printf ("got inex = %d, flags = %u,\n" " ", inex2, newflags); mpfr_dump (tres); exit (1); } set_emin (emin); set_emax (emax); } mpfr_clears (ta, tb, tc, tres, (mpfr_ptr) 0); }
static void check_special (void) { mpfr_t a, d, q; mpfr_exp_t emax, emin; int i; mpfr_init2 (a, 100L); mpfr_init2 (d, 100L); mpfr_init2 (q, 100L); /* 1/nan == nan */ mpfr_set_ui (a, 1L, MPFR_RNDN); MPFR_SET_NAN (d); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); /* nan/1 == nan */ MPFR_SET_NAN (a); mpfr_set_ui (d, 1L, MPFR_RNDN); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); /* +inf/1 == +inf */ MPFR_SET_INF (a); MPFR_SET_POS (a); mpfr_set_ui (d, 1L, MPFR_RNDN); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q)); MPFR_ASSERTN (mpfr_sgn (q) > 0); MPFR_ASSERTN (__gmpfr_flags == 0); /* +inf/-1 == -inf */ MPFR_SET_INF (a); MPFR_SET_POS (a); mpfr_set_si (d, -1, MPFR_RNDN); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q)); MPFR_ASSERTN (mpfr_sgn (q) < 0); MPFR_ASSERTN (__gmpfr_flags == 0); /* -inf/1 == -inf */ MPFR_SET_INF (a); MPFR_SET_NEG (a); mpfr_set_ui (d, 1L, MPFR_RNDN); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q)); MPFR_ASSERTN (mpfr_sgn (q) < 0); MPFR_ASSERTN (__gmpfr_flags == 0); /* -inf/-1 == +inf */ MPFR_SET_INF (a); MPFR_SET_NEG (a); mpfr_set_si (d, -1, MPFR_RNDN); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q)); MPFR_ASSERTN (mpfr_sgn (q) > 0); MPFR_ASSERTN (__gmpfr_flags == 0); /* 1/+inf == +0 */ mpfr_set_ui (a, 1L, MPFR_RNDN); MPFR_SET_INF (d); MPFR_SET_POS (d); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_number_p (q)); MPFR_ASSERTN (mpfr_sgn (q) == 0); MPFR_ASSERTN (MPFR_IS_POS (q)); MPFR_ASSERTN (__gmpfr_flags == 0); /* 1/-inf == -0 */ mpfr_set_ui (a, 1L, MPFR_RNDN); MPFR_SET_INF (d); MPFR_SET_NEG (d); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_number_p (q)); MPFR_ASSERTN (mpfr_sgn (q) == 0); MPFR_ASSERTN (MPFR_IS_NEG (q)); MPFR_ASSERTN (__gmpfr_flags == 0); /* -1/+inf == -0 */ mpfr_set_si (a, -1, MPFR_RNDN); MPFR_SET_INF (d); MPFR_SET_POS (d); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_number_p (q)); MPFR_ASSERTN (mpfr_sgn (q) == 0); MPFR_ASSERTN (MPFR_IS_NEG (q)); MPFR_ASSERTN (__gmpfr_flags == 0); /* -1/-inf == +0 */ mpfr_set_si (a, -1, MPFR_RNDN); MPFR_SET_INF (d); MPFR_SET_NEG (d); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_number_p (q)); MPFR_ASSERTN (mpfr_sgn (q) == 0); MPFR_ASSERTN (MPFR_IS_POS (q)); MPFR_ASSERTN (__gmpfr_flags == 0); /* 0/0 == nan */ mpfr_set_ui (a, 0L, MPFR_RNDN); mpfr_set_ui (d, 0L, MPFR_RNDN); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); /* +inf/+inf == nan */ MPFR_SET_INF (a); MPFR_SET_POS (a); MPFR_SET_INF (d); MPFR_SET_POS (d); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); /* 1/+0 = +inf */ mpfr_set_ui (a, 1, MPFR_RNDZ); mpfr_set_ui (d, 0, MPFR_RNDZ); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); /* 1/-0 = -inf */ mpfr_set_ui (a, 1, MPFR_RNDZ); mpfr_set_ui (d, 0, MPFR_RNDZ); mpfr_neg (d, d, MPFR_RNDZ); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0); MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); /* -1/+0 = -inf */ mpfr_set_si (a, -1, MPFR_RNDZ); mpfr_set_ui (d, 0, MPFR_RNDZ); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0); MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); /* -1/-0 = +inf */ mpfr_set_si (a, -1, MPFR_RNDZ); mpfr_set_ui (d, 0, MPFR_RNDZ); mpfr_neg (d, d, MPFR_RNDZ); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); /* +inf/+0 = +inf */ MPFR_SET_INF (a); MPFR_SET_POS (a); mpfr_set_ui (d, 0, MPFR_RNDZ); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); MPFR_ASSERTN (__gmpfr_flags == 0); /* +inf/-0 = -inf */ MPFR_SET_INF (a); MPFR_SET_POS (a); mpfr_set_ui (d, 0, MPFR_RNDZ); mpfr_neg (d, d, MPFR_RNDZ); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0); MPFR_ASSERTN (__gmpfr_flags == 0); /* -inf/+0 = -inf */ MPFR_SET_INF (a); MPFR_SET_NEG (a); mpfr_set_ui (d, 0, MPFR_RNDZ); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0); MPFR_ASSERTN (__gmpfr_flags == 0); /* -inf/-0 = +inf */ MPFR_SET_INF (a); MPFR_SET_NEG (a); mpfr_set_ui (d, 0, MPFR_RNDZ); mpfr_neg (d, d, MPFR_RNDZ); mpfr_clear_flags (); MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); MPFR_ASSERTN (__gmpfr_flags == 0); /* check overflow */ emax = mpfr_get_emax (); set_emax (1); mpfr_set_ui (a, 1, MPFR_RNDZ); mpfr_set_ui (d, 1, MPFR_RNDZ); mpfr_div_2exp (d, d, 1, MPFR_RNDZ); mpfr_clear_flags (); test_div (q, a, d, MPFR_RNDU); /* 1 / 0.5 = 2 -> overflow */ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); MPFR_ASSERTN (__gmpfr_flags == (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT)); set_emax (emax); /* check underflow */ emin = mpfr_get_emin (); set_emin (-1); mpfr_set_ui (a, 1, MPFR_RNDZ); mpfr_div_2exp (a, a, 2, MPFR_RNDZ); mpfr_set_prec (d, mpfr_get_prec (q) + 8); for (i = -1; i <= 1; i++) { int sign; /* Test 2^(-2) / (+/- (2 + eps)), with eps < 0, eps = 0, eps > 0. -> underflow. With div.c r5513, this test fails for eps > 0 in MPFR_RNDN. */ mpfr_set_ui (d, 2, MPFR_RNDZ); if (i < 0) mpfr_nextbelow (d); if (i > 0) mpfr_nextabove (d); for (sign = 0; sign <= 1; sign++) { mpfr_clear_flags (); test_div (q, a, d, MPFR_RNDZ); /* result = 0 */ MPFR_ASSERTN (__gmpfr_flags == (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT)); MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q)); MPFR_ASSERTN (MPFR_IS_ZERO (q)); mpfr_clear_flags (); test_div (q, a, d, MPFR_RNDN); /* result = 0 iff eps >= 0 */ MPFR_ASSERTN (__gmpfr_flags == (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT)); MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q)); if (i < 0) mpfr_nexttozero (q); MPFR_ASSERTN (MPFR_IS_ZERO (q)); mpfr_neg (d, d, MPFR_RNDN); } } set_emin (emin); mpfr_clear (a); mpfr_clear (d); mpfr_clear (q); }
static void check_special (void) { mpfr_t x,y,z,x2; int r; mpfr_prec_t p; int i = -1, inexact1, inexact2; mp_exp_t es; mpfr_inits (x, y, z, x2, (mpfr_ptr) 0); for (r = 0 ; r < GMP_RND_MAX ; r++) { p = 53; mpfr_set_prec(x, 53); mpfr_set_prec(x2, 53); mpfr_set_prec(y, 53); mpfr_set_prec(z, 53); mpfr_set_str_binary (y, "0.10110111101101110010010010011011000001101101011011001E31"); mpfr_sub1sp (x, y, y, (mp_rnd_t) r); if (mpfr_cmp_ui(x, 0)) { printf("Error for x-x with p=%lu. Expected 0. Got:", p); mpfr_print_binary(x); exit(1); } mpfr_set(z, y, (mp_rnd_t) r); mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp_ui(x, 0)) { printf("Error for x-y with y=x and p=%lu. Expected 0. Got:", p); mpfr_print_binary(x); exit(1); } /* diff = 0 */ mpfr_set_str_binary (y, "0.10110111101101110010010010011011001001101101011011001E31"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; /* Diff = 1 */ mpfr_set_str_binary (y, "0.10110111101101110010010010011011000001101101011011001E30"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; /* Diff = 2 */ mpfr_set_str_binary (y, "0.10110111101101110010010010011011000101101101011011001E32"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; /* Diff = 32 */ mpfr_set_str_binary (y, "0.10110111101101110010010010011011000001101101011011001E63"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; /* Diff = 52 */ mpfr_set_str_binary (y, "0.10110111101101110010010010011011010001101101011011001E83"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; /* Diff = 53 */ mpfr_set_str_binary (y, "0.10110111101101110010010010011111000001101101011011001E31"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; /* Diff > 200 */ mpfr_set_str_binary (y, "0.10110111101101110010010010011011000001101101011011001E331"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.10000000000000000000000000000000000000000000000000000E31"); mpfr_set_str_binary (z, "0.11111111111111111111111111111111111111111111111111111E30"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.10000000000000000000000000000000000000000000000000000E31"); mpfr_set_str_binary (z, "0.11111111111111111111111111111111111111111111111111111E29"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.10000000000000000000000000000000000000000000000000000E52"); mpfr_set_str_binary (z, "0.10000000000010000000000000000000000000000000000000000E00"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.11100000000000000000000000000000000000000000000000000E53"); mpfr_set_str_binary (z, "0.10000000000000000000000000000000000000000000000000000E00"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(z, y, z, (mp_rnd_t) r); mpfr_set(x, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.10000000000000000000000000000000000000000000000000000E53"); mpfr_set_str_binary (z, "0.10100000000000000000000000000000000000000000000000000E00"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.10000000000000000000000000000000000000000000000000000E54"); mpfr_set_str_binary (z, "0.10100000000000000000000000000000000000000000000000000E00"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; p = 63; mpfr_set_prec(x, p); mpfr_set_prec(x2, p); mpfr_set_prec(y, p); mpfr_set_prec(z, p); mpfr_set_str_binary (y, "0.100000000000000000000000000000000000000000000000000000000000000E62"); mpfr_set_str_binary (z, "0.110000000000000000000000000000000000000000000000000000000000000E00"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; p = 64; mpfr_set_prec(x, 64); mpfr_set_prec(x2, 64); mpfr_set_prec(y, 64); mpfr_set_prec(z, 64); mpfr_set_str_binary (y, "0.1100000000000000000000000000000000000000000000000000000000000000E31"); mpfr_set_str_binary (z, "0.1111111111111111111111111110000000000000000000000000011111111111E29"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.1000000000000000000000000000000000000000000000000000000000000000E63"); mpfr_set_str_binary (z, "0.1011000000000000000000000000000000000000000000000000000000000000E00"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.1000000000000000000000000000000000000000000000000000000000000000E63"); mpfr_set_str_binary (z, "0.1110000000000000000000000000000000000000000000000000000000000000E00"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.10000000000000000000000000000000000000000000000000000000000000E63"); mpfr_set_str_binary (z, "0.10000000000000000000000000000000000000000000000000000000000000E00"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.1000000000000000000000000000000000000000000000000000000000000000E64"); mpfr_set_str_binary (z, "0.1010000000000000000000000000000000000000000000000000000000000000E00"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; MPFR_SET_NAN(x); MPFR_SET_NAN(x2); mpfr_set_str_binary (y, "0.1000000000000000000000000000000000000000000000000000000000000000" "E-1073741823"); mpfr_set_str_binary (z, "0.1100000000000000000000000000000000000000000000000000000000000000" "E-1073741823"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; p = 9; mpfr_set_prec(x, p); mpfr_set_prec(x2, p); mpfr_set_prec(y, p); mpfr_set_prec(z, p); mpfr_set_str_binary (y, "0.100000000E1"); mpfr_set_str_binary (z, "0.100000000E-8"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; p = 34; mpfr_set_prec(x, p); mpfr_set_prec(x2, p); mpfr_set_prec(y, p); mpfr_set_prec(z, p); mpfr_set_str_binary (y, "-0.1011110000111100010111011100110100E-18"); mpfr_set_str_binary (z, "0.1000101010110011010101011110000000E-14"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; p = 124; mpfr_set_prec(x, p); mpfr_set_prec(x2, p); mpfr_set_prec(y, p); mpfr_set_prec(z, p); mpfr_set_str_binary (y, "0.1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1"); mpfr_set_str_binary (z, "0.1011111000100111000011001000011101010101101100101010101001000001110100001101110110001110111010000011101001100010111110001100E-31"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; p = 288; mpfr_set_prec(x, p); mpfr_set_prec(x2, p); mpfr_set_prec(y, p); mpfr_set_prec(z, p); mpfr_set_str_binary (y, "0.111000110011000001000111101010111011110011101001101111111110000011100101000001001010110010101010011001010100000001110011110001010101101010001011101110100100001011110100110000101101100011010001001011011010101010000010001101001000110010010111111011110001111101001000101101001100101100101000E80"); mpfr_set_str_binary (z, "-0.100001111111101001011010001100110010100111001110000110011101001011010100001000000100111011010110110010000000000010101101011000010000110001110010100001100101011100100100001011000100011110000001010101000100011101001000010111100000111000111011001000100100011000100000010010111000000100100111E-258"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; p = 85; mpfr_set_prec(x, p); mpfr_set_prec(x2, p); mpfr_set_prec(y, p); mpfr_set_prec(z, p); mpfr_set_str_binary (y, "0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4"); mpfr_set_str_binary (z, "0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; p = 64; mpfr_set_prec(x, p); mpfr_set_prec(x2, p); mpfr_set_prec(y, p); mpfr_set_prec(z, p); mpfr_set_str_binary (y, "0.11000000000000000000000000000000" "00000000000000000000000000000000E1"); mpfr_set_str_binary (z, "0.10000000000000000000000000000000" "00000000000000000000000000000001E0"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.11000000000000000000000000000000" "000000000000000000000000000001E1"); mpfr_set_str_binary (z, "0.10000000000000000000000000000000" "00000000000000000000000000000001E0"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; es = mpfr_get_emin (); set_emin (-1024); mpfr_set_str_binary (y, "0.10000000000000000000000000000000" "000000000000000000000000000000E-1023"); mpfr_set_str_binary (z, "0.10000000000000000000000000000000" "00000000000000000000000000000001E-1023"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; mpfr_set_str_binary (y, "0.10000000000000000000000000000000" "000000000000000000000000000000E-1023"); mpfr_set_str_binary (z, "0.1000000000000000000000000000000" "000000000000000000000000000000E-1023"); inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; set_emin (es); } mpfr_clears (x, y, z, x2, (mpfr_ptr) 0); }
static void special_overflow (void) { mpfr_t x, y; mpfr_exp_t emin, emax; emin = mpfr_get_emin (); emax = mpfr_get_emax (); set_emin (-125); set_emax (128); mpfr_init2 (x, 24); mpfr_init2 (y, 48); mpfr_set_str_binary (x, "0.101101010001001101111010E0"); mpfr_atan (y, x, MPFR_RNDN); if (mpfr_cmp_str (y, "0.100111011001100111000010111101000111010101011110E0", 2, MPFR_RNDN)) { printf("Special Overflow error.\n"); mpfr_dump (y); exit (1); } /* intermediate Pi overflows while atan(+Inf) = Pi/2 is representable */ set_emax (1); mpfr_set_inf (x, +1); mpfr_clear_flags (); mpfr_atan (y, x, MPFR_RNDN); if (mpfr_cmp_str (y, "C90FDAA22169p-47", 16, MPFR_RNDN) || mpfr_overflow_p ()) { printf("atan(+Inf) = Pi/2 should not overflow when emax = %ld\n", (long int) mpfr_get_emax ()); mpfr_dump (y); exit (1); } /* atan(+Inf) = Pi/2 underflows */ set_emax (128); set_emin (3); mpfr_clear_flags (); mpfr_atan (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ()) { printf("atan(+Inf) = Pi/2 should underflow when emin = %ld\n", (long int) mpfr_get_emin ()); mpfr_dump (y); exit (1); } /* intermediate Pi overflows while atan(+1) = Pi/4 is representable */ set_emax (1); set_emin (-128); mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_clear_flags (); mpfr_atan (y, x, MPFR_RNDN); if (mpfr_cmp_str (y, "C90FDAA22169p-48", 16, MPFR_RNDN) || mpfr_overflow_p ()) { printf("atan(+1) = Pi/4 should not overflow when emax = %ld\n", (long int) mpfr_get_emax ()); mpfr_dump (y); exit (1); } /* atan(+1) = Pi/4 underflows and is rounded up to 1 */ set_emax (128); set_emin (1); mpfr_set_prec (y, 2); mpfr_clear_flags (); mpfr_atan (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 1) || !mpfr_underflow_p ()) { printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n", (long int) mpfr_get_emin ()); mpfr_dump (y); exit (1); } /* atan(+1) = Pi/4 underflows and is rounded down to 0 */ mpfr_clear_flags (); mpfr_atan (y, x, MPFR_RNDD); if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ()) { printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n", (long int) mpfr_get_emin ()); mpfr_dump (y); exit (1); } mpfr_clear (y); mpfr_clear (x); set_emin (emin); set_emax (emax); }