static void test_underflow2 (void) { mpfr_t x, y, z, r; int b, i, inex, same, err = 0; mpfr_inits2 (32, x, y, z, r, (void *) 0); mpfr_set_si_2exp (z, 1, mpfr_get_emin (), GMP_RNDN); /* z = 2^emin */ mpfr_set_si_2exp (x, 1, mpfr_get_emin (), GMP_RNDN); /* x = 2^emin */ for (b = 0; b <= 1; b++) { for (i = 15; i <= 17; i++) { mpfr_set_si_2exp (y, i, -4 - MPFR_PREC (z), GMP_RNDN); /* z = 1.000...00b * xy = 01111 * or 10000 * or 10001 */ mpfr_clear_flags (); inex = mpfr_fma (r, x, y, z, GMP_RNDN); #define ERRTU2 "Error in test_underflow2 (b = %d, i = %d)\n " if (__gmpfr_flags != MPFR_FLAGS_INEXACT) { printf (ERRTU2 "flags = %u instead of %u\n", b, i, __gmpfr_flags, (unsigned int) MPFR_FLAGS_INEXACT); err = 1; } same = i == 15 || (i == 16 && b == 0); if (same ? (inex >= 0) : (inex <= 0)) { printf (ERRTU2 "incorrect ternary value (%d instead of %c 0)\n", b, i, inex, same ? '<' : '>'); err = 1; } mpfr_set (y, z, GMP_RNDN); if (!same) mpfr_nextabove (y); if (! mpfr_equal_p (r, y)) { printf (ERRTU2 "expected ", b, i); mpfr_dump (y); printf (" got "); mpfr_dump (r); err = 1; } } mpfr_nextabove (z); } if (err) exit (1); mpfr_clears (x, y, z, r, (void *) 0); }
static void pow_si_long_min (void) { mpfr_t x, y, z; int inex; mpfr_inits2 (sizeof(long) * CHAR_BIT + 32, x, y, z, (void *) 0); mpfr_set_si_2exp (x, 3, -1, GMP_RNDN); /* 1.5 */ inex = mpfr_set_si (y, LONG_MIN, GMP_RNDN); MPFR_ASSERTN (inex == 0); mpfr_nextbelow (y); mpfr_pow (y, x, y, GMP_RNDD); inex = mpfr_set_si (z, LONG_MIN, GMP_RNDN); MPFR_ASSERTN (inex == 0); mpfr_nextabove (z); mpfr_pow (z, x, z, GMP_RNDU); mpfr_pow_si (x, x, LONG_MIN, GMP_RNDN); /* 1.5^LONG_MIN */ if (mpfr_cmp (x, y) < 0 || mpfr_cmp (x, z) > 0) { printf ("Error in pow_si_long_min\n"); exit (1); } mpfr_clears (x, y, z, (void *) 0); }
int fmpr_get_mpfr(mpfr_t x, const fmpr_t y, mpfr_rnd_t rnd) { int r; if (fmpr_is_special(y)) { if (fmpr_is_zero(y)) mpfr_set_zero(x, 0); else if (fmpr_is_pos_inf(y)) mpfr_set_inf(x, 1); else if (fmpr_is_neg_inf(y)) mpfr_set_inf(x, -1); else mpfr_set_nan(x); r = 0; } else if (COEFF_IS_MPZ(*fmpr_expref(y))) { flint_printf("exception: exponent too large to convert to mpfr"); abort(); } else { if (!COEFF_IS_MPZ(*fmpr_manref(y))) #if defined(__MINGW64__) r = mpfr_set_sj_2exp(x, *fmpr_manref(y), *fmpr_expref(y), rnd); #else r = mpfr_set_si_2exp(x, *fmpr_manref(y), *fmpr_expref(y), rnd); #endif else r = mpfr_set_z_2exp(x, COEFF_TO_PTR(*fmpr_manref(y)), *fmpr_expref(y), rnd); if (!mpfr_regular_p(x)) { flint_printf("exception: exponent too large to convert to mpfr"); abort(); } }
static void test_small (void) { mpfr_t x, y, z1, z2; int inex1, inex2; unsigned int flags; /* Test hypot(x,x) with x = 2^(emin-1). Result is x * sqrt(2). */ mpfr_inits2 (8, x, y, z1, z2, (mpfr_ptr) 0); mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN); mpfr_set_si_2exp (y, 1, mpfr_get_emin () - 1, MPFR_RNDN); mpfr_set_ui (z1, 2, MPFR_RNDN); inex1 = mpfr_sqrt (z1, z1, MPFR_RNDN); inex2 = mpfr_mul (z1, z1, x, MPFR_RNDN); MPFR_ASSERTN (inex2 == 0); mpfr_clear_flags (); inex2 = mpfr_hypot (z2, x, y, MPFR_RNDN); flags = __gmpfr_flags; if (mpfr_cmp (z1, z2) != 0) { printf ("Error in test_small%s\nExpected ", ext ? ", extended exponent range" : ""); mpfr_out_str (stdout, 2, 0, z1, MPFR_RNDN); printf ("\nGot "); mpfr_out_str (stdout, 2, 0, z2, MPFR_RNDN); printf ("\n"); exit (1); } if (! SAME_SIGN (inex1, inex2)) { printf ("Bad ternary value in test_small%s\nExpected %d, got %d\n", ext ? ", extended exponent range" : "", inex1, inex2); exit (1); } if (flags != MPFR_FLAGS_INEXACT) { printf ("Bad flags in test_small%s\nExpected %u, got %u\n", ext ? ", extended exponent range" : "", (unsigned int) MPFR_FLAGS_INEXACT, flags); exit (1); } mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); }
static void test_get_uj_smallneg (void) { mpfr_t x; int i; mpfr_init2 (x, 64); for (i = 1; i <= 4; i++) { int r; mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN); RND_LOOP (r) { intmax_t s; uintmax_t u; mpfr_clear_erangeflag (); s = mpfr_get_sj (x, (mpfr_rnd_t) r); if (mpfr_erangeflag_p ()) { printf ("ERROR for get_sj + ERANGE + small negative op" " for rnd = %s and x = -%d/4\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); exit (1); } u = mpfr_get_uj (x, (mpfr_rnd_t) r); if (u != 0) { printf ("ERROR for get_uj + ERANGE + small negative op" " for rnd = %s and x = -%d/4\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); printf ("Expected 0, got %ju\n", u); exit (1); } if ((s == 0) ^ !mpfr_erangeflag_p ()) { char *not = s == 0 ? "" : " not"; printf ("ERROR for get_uj + ERANGE + small negative op" " for rnd = %s and x = -%d/4\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); printf ("The rounding integer (%jd) is%s representable in " "unsigned long,\nbut the erange flag is%s set.\n", s, not, not); exit (1); } } } mpfr_clear (x); }
static void check_sj (intmax_t s, mpfr_ptr x) { mpfr_t y; int i; mpfr_init2 (y, MPFR_PREC (x)); for (i = -1; i <= 1; i++) { int rnd; mpfr_set_si_2exp (y, i, -2, MPFR_RNDN); mpfr_add (y, y, x, MPFR_RNDN); for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) { intmax_t r; if (rnd == MPFR_RNDZ && i < 0 && s >= 0) continue; if (rnd == MPFR_RNDZ && i > 0 && s <= 0) continue; if (rnd == MPFR_RNDD && i < 0) continue; if (rnd == MPFR_RNDU && i > 0) continue; if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) || (MPFR_IS_NEG(y) && i < 0))) continue; /* rint (y) == x == s */ r = mpfr_get_sj (y, (mpfr_rnd_t) rnd); if (r != s) { printf ("Error in check_sj for y = "); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); printf ("Got %jd instead of %jd.\n", r, s); exit (1); } } } mpfr_clear (y); }
static void test_erfc (void) { mpfr_t x, y, z; int inex; mpfr_exp_t emin; mpfr_inits2 (40, x, y, z, (mpfr_ptr) 0); mpfr_set_si_2exp (x, -1, -10, MPFR_RNDN); mpfr_set_str_binary (z, "0.1000000000100100000110111010110111100000E1"); mpfr_erfc (y, x, MPFR_RNDN); if (mpfr_cmp (y, z) != 0) { printf ("mpfr_erfc failed for x = "); mpfr_dump (x); printf ("got "); mpfr_dump (y); printf ("instead of "); mpfr_dump (z); exit (1); } /* slowness detected by Kevin Rauch on 26 Oct 2007 */ mpfr_set_prec (x, 128); mpfr_set_si (x, -256, MPFR_RNDN); inex = mpfr_erfc (x, x, MPFR_RNDN); MPFR_ASSERTN(inex > 0 && mpfr_cmp_ui (x, 2) == 0); /* bug found by Pascal Molin on March 10, 2011 */ emin = mpfr_get_emin (); if (! mpfr_set_emin (-1073808789)) { /* Typically, a 64-bit machine. */ mpfr_set_si (x, 27282, MPFR_RNDN); mpfr_erfc (y, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 0) != 0); mpfr_set_emin (emin); } mpfr_clears (x, y, z, (mpfr_ptr) 0); }
/* Bug found while adding tests for mpfr_cot */ static void test_20070628 (void) { mpfr_exp_t old_emax; mpfr_t x, y; int inex, err = 0; old_emax = mpfr_get_emax (); if (mpfr_set_emax (256)) { printf ("Can't change exponent range\n"); exit (1); } mpfr_inits2 (53, x, y, (mpfr_ptr) 0); mpfr_set_si (x, -1, MPFR_RNDN); mpfr_set_si_2exp (y, 1, -256, MPFR_RNDN); mpfr_clear_flags (); inex = mpfr_div (x, x, y, MPFR_RNDD); if (MPFR_SIGN (x) >= 0 || ! mpfr_inf_p (x)) { printf ("Error in test_20070628: expected -Inf, got\n"); mpfr_dump (x); err++; } if (inex >= 0) { printf ("Error in test_20070628: expected inex < 0, got %d\n", inex); err++; } if (! mpfr_overflow_p ()) { printf ("Error in test_20070628: overflow flag is not set\n"); err++; } mpfr_clears (x, y, (mpfr_ptr) 0); mpfr_set_emax (old_emax); }
static int decimal (void) { mpfr_prec_t p = 128; mpfr_t x; mpfr_t z; mpfr_init (z); mpfr_init2 (x, p); /* specifier 'P' for precision */ check_vsprintf ("128", "%Pu", p); check_vsprintf ("00128", "%.5Pu", p); /* special numbers */ mpfr_set_inf (x, 1); check_sprintf (pinf_str, "%Re", x); check_sprintf (pinf_str, "%RUe", x); check_sprintf (pinf_uc_str, "%RE", x); check_sprintf (pinf_uc_str, "%RDE", x); check_sprintf (pinf_str, "%Rf", x); check_sprintf (pinf_str, "%RYf", x); check_sprintf (pinf_uc_str, "%RF", x); check_sprintf (pinf_uc_str, "%RZF", x); check_sprintf (pinf_str, "%Rg", x); check_sprintf (pinf_str, "%RNg", x); check_sprintf (pinf_uc_str, "%RG", x); check_sprintf (pinf_uc_str, "%RUG", x); check_sprintf (" inf", "%010Re", x); check_sprintf (" inf", "%010RDe", x); mpfr_set_inf (x, -1); check_sprintf (minf_str, "%Re", x); check_sprintf (minf_str, "%RYe", x); check_sprintf (minf_uc_str, "%RE", x); check_sprintf (minf_uc_str, "%RZE", x); check_sprintf (minf_str, "%Rf", x); check_sprintf (minf_str, "%RNf", x); check_sprintf (minf_uc_str, "%RF", x); check_sprintf (minf_uc_str, "%RUF", x); check_sprintf (minf_str, "%Rg", x); check_sprintf (minf_str, "%RDg", x); check_sprintf (minf_uc_str, "%RG", x); check_sprintf (minf_uc_str, "%RYG", x); check_sprintf (" -inf", "%010Re", x); check_sprintf (" -inf", "%010RZe", x); mpfr_set_nan (x); check_sprintf (nan_str, "%Re", x); check_sprintf (nan_str, "%RNe", x); check_sprintf (nan_uc_str, "%RE", x); check_sprintf (nan_uc_str, "%RUE", x); check_sprintf (nan_str, "%Rf", x); check_sprintf (nan_str, "%RDf", x); check_sprintf (nan_uc_str, "%RF", x); check_sprintf (nan_uc_str, "%RYF", x); check_sprintf (nan_str, "%Rg", x); check_sprintf (nan_str, "%RZg", x); check_sprintf (nan_uc_str, "%RG", x); check_sprintf (nan_uc_str, "%RNG", x); check_sprintf (" nan", "%010Re", x); /* positive numbers */ mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN); mpfr_set_ui (z, 0, MPFR_RNDD); /* simplest case right justified */ check_sprintf (" 1.899347461279296875e+07", "%30Re", x); check_sprintf (" 2e+07", "%30.0Re", x); check_sprintf (" 18993474.612793", "%30Rf", x); check_sprintf (" 18993474.6127930", "%30.7Rf", x); check_sprintf (" 1.89935e+07", "%30Rg", x); check_sprintf (" 2e+07", "%30.0Rg", x); check_sprintf (" 18993474.61279296875", "%30.19Rg", x); check_sprintf (" 0e+00", "%30.0Re", z); check_sprintf (" 0", "%30.0Rf", z); check_sprintf (" 0.0000", "%30.4Rf", z); check_sprintf (" 0", "%30.0Rg", z); check_sprintf (" 0", "%30.4Rg", z); /* sign or space, pad with leading zeros */ check_sprintf (" 000001.899347461279296875E+07", "% 030RE", x); check_sprintf (" 0000000000000000001.89935E+07", "% 030RG", x); check_sprintf (" 0000000000000000000000002E+07", "% 030.0RE", x); check_sprintf (" 0000000000000000000000000E+00", "% 030.0RE", z); check_sprintf (" 00000000000000000000000000000", "% 030.0RF", z); /* sign + or -, left justified */ check_sprintf ("+1.899347461279296875e+07 ", "%+-30Re", x); check_sprintf ("+2e+07 ", "%+-30.0Re", x); check_sprintf ("+0e+00 ", "%+-30.0Re", z); check_sprintf ("+0 ", "%+-30.0Rf", z); /* decimal point, left justified, precision and rounding parameter */ check_vsprintf ("1.9E+07 ", "%#-10.*R*E", 1, MPFR_RNDN, x); check_vsprintf ("2.E+07 ", "%#*.*R*E", -10, 0, MPFR_RNDN, x); check_vsprintf ("2.E+07 ", "%#-10.*R*G", 0, MPFR_RNDN, x); check_vsprintf ("0.E+00 ", "%#-10.*R*E", 0, MPFR_RNDN, z); check_vsprintf ("0. ", "%#-10.*R*F", 0, MPFR_RNDN, z); check_vsprintf ("0. ", "%#-10.*R*G", 0, MPFR_RNDN, z); /* sign or space */ check_sprintf (" 1.899e+07", "% .3RNe", x); check_sprintf (" 2e+07", "% .0RNe", x); /* sign + or -, decimal point, pad with leading zeros */ check_sprintf ("+0001.8E+07", "%0+#11.1RZE", x); check_sprintf ("+00001.E+07", "%0+#11.0RZE", x); check_sprintf ("+0000.0E+00", "%0+#11.1RZE", z); check_sprintf ("+00000000.0", "%0+#11.1RZF", z); /* pad with leading zero */ check_sprintf ("0000001.899347461279296875e+07", "%030RDe", x); check_sprintf ("00000000000000000000000001e+07", "%030.0RDe", x); /* sign or space, decimal point, left justified */ check_sprintf (" 1.8E+07 ", "%- #11.1RDE", x); check_sprintf (" 1.E+07 ", "%- #11.0RDE", x); /* negative numbers */ mpfr_mul_si (x, x, -1, MPFR_RNDD); mpfr_mul_si (z, z, -1, MPFR_RNDD); /* sign + or - */ check_sprintf (" -1.8e+07", "%+10.1RUe", x); check_sprintf (" -1e+07", "%+10.0RUe", x); check_sprintf (" -0e+00", "%+10.0RUe", z); check_sprintf (" -0", "%+10.0RUf", z); /* neighborhood of 1 */ mpfr_set_str (x, "0.99993896484375", 10, MPFR_RNDN); check_sprintf ("9.9993896484375E-01 ", "%-20RE", x); check_sprintf ("9.9993896484375E-01 ", "%-20.RE", x); check_sprintf ("1E+00 ", "%-20.0RE", x); check_sprintf ("1.0E+00 ", "%-20.1RE", x); check_sprintf ("1.00E+00 ", "%-20.2RE", x); check_sprintf ("9.999E-01 ", "%-20.3RE", x); check_sprintf ("9.9994E-01 ", "%-20.4RE", x); check_sprintf ("0.999939 ", "%-20RF", x); check_sprintf ("0.999939 ", "%-20.RF", x); check_sprintf ("1 ", "%-20.0RF", x); check_sprintf ("1.0 ", "%-20.1RF", x); check_sprintf ("1.00 ", "%-20.2RF", x); check_sprintf ("1.000 ", "%-20.3RF", x); check_sprintf ("0.9999 ", "%-20.4RF", x); check_sprintf ("0.999939 ", "%-#20RF", x); check_sprintf ("0.999939 ", "%-#20.RF", x); check_sprintf ("1. ", "%-#20.0RF", x); check_sprintf ("1.0 ", "%-#20.1RF", x); check_sprintf ("1.00 ", "%-#20.2RF", x); check_sprintf ("1.000 ", "%-#20.3RF", x); check_sprintf ("0.9999 ", "%-#20.4RF", x); check_sprintf ("1 ", "%-20.0RG", x); check_sprintf ("1 ", "%-20.1RG", x); check_sprintf ("1 ", "%-20.2RG", x); check_sprintf ("1 ", "%-20.3RG", x); check_sprintf ("0.9999 ", "%-20.4RG", x); check_sprintf ("0.999939 ", "%-#20RG", x); check_sprintf ("0.999939 ", "%-#20.RG", x); check_sprintf ("1. ", "%-#20.0RG", x); check_sprintf ("1. ", "%-#20.1RG", x); check_sprintf ("1.0 ", "%-#20.2RG", x); check_sprintf ("1.00 ", "%-#20.3RG", x); check_sprintf ("0.9999 ", "%-#20.4RG", x); /* multiple of 10 */ mpfr_set_str (x, "1e17", 10, MPFR_RNDN); check_sprintf ("1e+17", "%Re", x); check_sprintf ("1.000e+17", "%.3Re", x); check_sprintf ("100000000000000000", "%.0Rf", x); check_sprintf ("100000000000000000.0", "%.1Rf", x); check_sprintf ("100000000000000000.000000", "%'Rf", x); check_sprintf ("100000000000000000.0", "%'.1Rf", x); mpfr_ui_div (x, 1, x, MPFR_RNDN); /* x=1e-17 */ check_sprintf ("1e-17", "%Re", x); check_sprintf ("0.000000", "%Rf", x); check_sprintf ("1e-17", "%Rg", x); check_sprintf ("0.0", "%.1RDf", x); check_sprintf ("0.0", "%.1RZf", x); check_sprintf ("0.1", "%.1RUf", x); check_sprintf ("0.1", "%.1RYf", x); check_sprintf ("0", "%.0RDf", x); check_sprintf ("0", "%.0RZf", x); check_sprintf ("1", "%.0RUf", x); check_sprintf ("1", "%.0RYf", x); /* multiple of 10 with 'g' style */ mpfr_set_str (x, "10", 10, MPFR_RNDN); check_sprintf ("10", "%Rg", x); check_sprintf ("1e+01", "%.0Rg", x); check_sprintf ("1e+01", "%.1Rg", x); check_sprintf ("10", "%.2Rg", x); mpfr_ui_div (x, 1, x, MPFR_RNDN); check_sprintf ("0.1", "%Rg", x); check_sprintf ("0.1", "%.0Rg", x); check_sprintf ("0.1", "%.1Rg", x); mpfr_set_str (x, "1000", 10, MPFR_RNDN); check_sprintf ("1000", "%Rg", x); check_sprintf ("1e+03", "%.0Rg", x); check_sprintf ("1e+03", "%.3Rg", x); check_sprintf ("1000", "%.4Rg", x); mpfr_ui_div (x, 1, x, MPFR_RNDN); check_sprintf ("0.001", "%Rg", x); check_sprintf ("0.001", "%.0Rg", x); check_sprintf ("0.001", "%.1Rg", x); mpfr_set_str (x, "100000", 10, MPFR_RNDN); check_sprintf ("100000", "%Rg", x); check_sprintf ("1e+05", "%.0Rg", x); check_sprintf ("1e+05", "%.5Rg", x); check_sprintf ("100000", "%.6Rg", x); mpfr_ui_div (x, 1, x, MPFR_RNDN); check_sprintf ("1e-05", "%Rg", x); check_sprintf ("1e-05", "%.0Rg", x); check_sprintf ("1e-05", "%.1Rg", x); /* check rounding mode */ mpfr_set_str (x, "0.0076", 10, MPFR_RNDN); check_sprintf ("0.007", "%.3RDF", x); check_sprintf ("0.007", "%.3RZF", x); check_sprintf ("0.008", "%.3RF", x); check_sprintf ("0.008", "%.3RUF", x); check_sprintf ("0.008", "%.3RYF", x); check_vsprintf ("0.008", "%.3R*F", MPFR_RNDA, x); /* check limit between %f-style and %g-style */ mpfr_set_str (x, "0.0000999", 10, MPFR_RNDN); check_sprintf ("0.0001", "%.0Rg", x); check_sprintf ("9e-05", "%.0RDg", x); check_sprintf ("0.0001", "%.1Rg", x); check_sprintf ("0.0001", "%.2Rg", x); check_sprintf ("9.99e-05", "%.3Rg", x); /* trailing zeros */ mpfr_set_si_2exp (x, -1, -15, MPFR_RNDN); /* x=-2^-15 */ check_sprintf ("-3.0517578125e-05", "%.30Rg", x); check_sprintf ("-3.051757812500000000000000000000e-05", "%.30Re", x); check_sprintf ("-3.05175781250000000000000000000e-05", "%#.30Rg", x); check_sprintf ("-0.000030517578125000000000000000", "%.30Rf", x); /* bug 20081023 */ check_sprintf ("-3.0517578125e-05", "%.30Rg", x); mpfr_set_str (x, "1.9999", 10, MPFR_RNDN); check_sprintf ("1.999900 ", "%-#10.7RG", x); check_sprintf ("1.9999 ", "%-10.7RG", x); mpfr_set_ui (x, 1, MPFR_RNDN); check_sprintf ("1.00000000000000000000000000000", "%#.30Rg", x); check_sprintf ("1", "%.30Rg", x); mpfr_set_ui (x, 0, MPFR_RNDN); check_sprintf ("0.000000000000000000000000000000", "%#.30Rg", x); check_sprintf ("0", "%.30Rg", x); /* following tests with precision 53 bits */ mpfr_set_prec (x, 53); /* Exponent zero has a plus sign */ mpfr_set_str (x, "-9.95645044213728791504536275169812142849e-01", 10, MPFR_RNDN); check_sprintf ("-1.0e+00", "%- #0.1Re", x); /* Decimal point and no figure after it with '#' flag and 'G' style */ mpfr_set_str (x, "-9.90597761233942053494e-01", 10, MPFR_RNDN); check_sprintf ("-1.", "%- #0.1RG", x); /* precision zero */ mpfr_set_d (x, 9.5, MPFR_RNDN); check_sprintf ("9", "%.0RDf", x); check_sprintf ("10", "%.0RUf", x); mpfr_set_d (x, 19.5, MPFR_RNDN); check_sprintf ("19", "%.0RDf", x); check_sprintf ("20", "%.0RUf", x); mpfr_set_d (x, 99.5, MPFR_RNDN); check_sprintf ("99", "%.0RDf", x); check_sprintf ("100", "%.0RUf", x); mpfr_set_d (x, -9.5, MPFR_RNDN); check_sprintf ("-10", "%.0RDf", x); check_sprintf ("-10", "%.0RYf", x); check_sprintf ("-10", "%.0Rf", x); check_sprintf ("-1e+01", "%.0Re", x); check_sprintf ("-1e+01", "%.0Rg", x); mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN); check_sprintf ("0", "%.0Rf", x); check_sprintf ("5e-01", "%.0Re", x); check_sprintf ("0.5", "%.0Rg", x); mpfr_set_ui_2exp (x, 3, -1, MPFR_RNDN); check_sprintf ("2", "%.0Rf", x); mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN); check_sprintf ("2", "%.0Rf", x); mpfr_set_ui (x, 0x1f, MPFR_RNDN); check_sprintf ("0x1p+5", "%.0Ra", x); mpfr_set_ui (x, 3, MPFR_RNDN); check_sprintf ("1p+2", "%.0Rb", x); /* round to next ten power with %f but not with %g */ mpfr_set_str (x, "-6.64464380544039223686e-02", 10, MPFR_RNDN); check_sprintf ("-0.1", "%.1Rf", x); check_sprintf ("-0.0", "%.1RZf", x); check_sprintf ("-0.07", "%.1Rg", x); check_sprintf ("-0.06", "%.1RZg", x); /* round to next ten power and do not remove trailing zeros */ mpfr_set_str (x, "9.98429393291486722006e-02", 10, MPFR_RNDN); check_sprintf ("0.1", "%#.1Rg", x); check_sprintf ("0.10", "%#.2Rg", x); check_sprintf ("0.099", "%#.2RZg", x); /* Halfway cases */ mpfr_set_str (x, "1.5", 10, MPFR_RNDN); check_sprintf ("2e+00", "%.0Re", x); mpfr_set_str (x, "2.5", 10, MPFR_RNDN); check_sprintf ("2e+00", "%.0Re", x); mpfr_set_str (x, "9.5", 10, MPFR_RNDN); check_sprintf ("1e+01", "%.0Re", x); mpfr_set_str (x, "1.25", 10, MPFR_RNDN); check_sprintf ("1.2e+00", "%.1Re", x); mpfr_set_str (x, "1.75", 10, MPFR_RNDN); check_sprintf ("1.8e+00", "%.1Re", x); mpfr_set_str (x, "-0.5", 10, MPFR_RNDN); check_sprintf ("-0", "%.0Rf", x); mpfr_set_str (x, "1.25", 10, MPFR_RNDN); check_sprintf ("1.2", "%.1Rf", x); mpfr_set_str (x, "1.75", 10, MPFR_RNDN); check_sprintf ("1.8", "%.1Rf", x); mpfr_set_str (x, "1.5", 10, MPFR_RNDN); check_sprintf ("2", "%.1Rg", x); mpfr_set_str (x, "2.5", 10, MPFR_RNDN); check_sprintf ("2", "%.1Rg", x); mpfr_set_str (x, "9.25", 10, MPFR_RNDN); check_sprintf ("9.2", "%.2Rg", x); mpfr_set_str (x, "9.75", 10, MPFR_RNDN); check_sprintf ("9.8", "%.2Rg", x); /* assertion failure in r6320 */ mpfr_set_str (x, "-9.996", 10, MPFR_RNDN); check_sprintf ("-10.0", "%.1Rf", x); /* regression in MPFR 3.1.0 (bug introduced in r7761, fixed in r7931) */ check_sprintf ("-10", "%.2Rg", x); mpfr_clears (x, z, (mpfr_ptr) 0); return 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); }
int main (void) { mpfr_t x, y; int i, r; tests_start_mpfr (); mpfr_init2 (x, 256); mpfr_init2 (y, 8); RND_LOOP (r) { /* Check NAN */ mpfr_set_nan (x); if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r)) ERROR1 (1); if (mpfr_fits_slong_p (x, (mpfr_rnd_t) r)) ERROR1 (2); if (mpfr_fits_uint_p (x, (mpfr_rnd_t) r)) ERROR1 (3); if (mpfr_fits_sint_p (x, (mpfr_rnd_t) r)) ERROR1 (4); if (mpfr_fits_ushort_p (x, (mpfr_rnd_t) r)) ERROR1 (5); if (mpfr_fits_sshort_p (x, (mpfr_rnd_t) r)) ERROR1 (6); /* Check INF */ mpfr_set_inf (x, 1); if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r)) ERROR1 (7); if (mpfr_fits_slong_p (x, (mpfr_rnd_t) r)) ERROR1 (8); if (mpfr_fits_uint_p (x, (mpfr_rnd_t) r)) ERROR1 (9); if (mpfr_fits_sint_p (x, (mpfr_rnd_t) r)) ERROR1 (10); if (mpfr_fits_ushort_p (x, (mpfr_rnd_t) r)) ERROR1 (11); if (mpfr_fits_sshort_p (x, (mpfr_rnd_t) r)) ERROR1 (12); /* Check Zero */ MPFR_SET_ZERO (x); if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r)) ERROR1 (13); if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r)) ERROR1 (14); if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r)) ERROR1 (15); if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r)) ERROR1 (16); if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r)) ERROR1 (17); if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r)) ERROR1 (18); /* Check small positive op */ mpfr_set_str1 (x, "1@-1"); if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r)) ERROR1 (19); if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r)) ERROR1 (20); if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r)) ERROR1 (21); if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r)) ERROR1 (22); if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r)) ERROR1 (23); if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r)) ERROR1 (24); /* Check 17 */ mpfr_set_ui (x, 17, MPFR_RNDN); if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r)) ERROR1 (25); if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r)) ERROR1 (26); if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r)) ERROR1 (27); if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r)) ERROR1 (28); if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r)) ERROR1 (29); if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r)) ERROR1 (30); /* Check all other values */ mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN); mpfr_mul_2exp (x, x, 1, MPFR_RNDN); if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r)) ERROR1 (31); if (mpfr_fits_slong_p (x, (mpfr_rnd_t) r)) ERROR1 (32); mpfr_mul_2exp (x, x, 40, MPFR_RNDN); if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r)) ERROR1 (33); if (mpfr_fits_uint_p (x, (mpfr_rnd_t) r)) ERROR1 (34); if (mpfr_fits_sint_p (x, (mpfr_rnd_t) r)) ERROR1 (35); if (mpfr_fits_ushort_p (x, (mpfr_rnd_t) r)) ERROR1 (36); if (mpfr_fits_sshort_p (x, (mpfr_rnd_t) r)) ERROR1 (37); mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN); if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r)) ERROR1 (38); mpfr_set_ui (x, LONG_MAX, MPFR_RNDN); if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r)) ERROR1 (39); mpfr_set_ui (x, UINT_MAX, MPFR_RNDN); if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r)) ERROR1 (40); mpfr_set_ui (x, INT_MAX, MPFR_RNDN); if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r)) ERROR1 (41); mpfr_set_ui (x, USHRT_MAX, MPFR_RNDN); if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r)) ERROR1 (42); mpfr_set_ui (x, SHRT_MAX, MPFR_RNDN); if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r)) ERROR1 (43); mpfr_set_si (x, 1, MPFR_RNDN); if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r)) ERROR1 (44); if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r)) ERROR1 (45); /* Check negative op */ for (i = 1; i <= 4; i++) { int inv; mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN); mpfr_rint (y, x, (mpfr_rnd_t) r); inv = MPFR_NOTZERO (y); if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r) ^ inv) ERROR1 (46); if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r)) ERROR1 (47); if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r) ^ inv) ERROR1 (48); if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r)) ERROR1 (49); if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r) ^ inv) ERROR1 (50); if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r)) ERROR1 (51); } } mpfr_clear (x); mpfr_clear (y); check_intmax (); tests_end_mpfr (); return 0; }
static void test_underflow1 (void) { mpfr_t x, y, z, r; int inex, signy, signz, rnd, err = 0; mpfr_inits2 (8, x, y, z, r, (void *) 0); MPFR_SET_POS (x); mpfr_setmin (x, mpfr_get_emin ()); /* x = 0.1@emin */ for (signy = -1; signy <= 1; signy += 2) { mpfr_set_si_2exp (y, signy, -1, GMP_RNDN); /* |y| = 1/2 */ for (signz = -3; signz <= 3; signz += 2) { RND_LOOP (rnd) { mpfr_set_si (z, signz, GMP_RNDN); if (ABS (signz) != 1) mpfr_setmax (z, mpfr_get_emax ()); /* |z| = 1 or 2^emax - ulp */ mpfr_clear_flags (); inex = mpfr_fma (r, x, y, z, rnd); #define ERRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n " if (mpfr_nanflag_p ()) { printf (ERRTU1 "NaN flag is set\n", signy, signz, mpfr_print_rnd_mode (rnd)); err = 1; } if (signy < 0 && (rnd == GMP_RNDD || (rnd == GMP_RNDZ && signz > 0))) mpfr_nextbelow (z); if (signy > 0 && (rnd == GMP_RNDU || (rnd == GMP_RNDZ && signz < 0))) mpfr_nextabove (z); if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0)) { printf (ERRTU1 "wrong overflow flag\n", signy, signz, mpfr_print_rnd_mode (rnd)); err = 1; } if (mpfr_underflow_p ()) { printf (ERRTU1 "underflow flag is set\n", signy, signz, mpfr_print_rnd_mode (rnd)); err = 1; } if (! mpfr_equal_p (r, z)) { printf (ERRTU1 "got ", signy, signz, mpfr_print_rnd_mode (rnd)); mpfr_print_binary (r); printf (" instead of "); mpfr_print_binary (z); printf ("\n"); err = 1; } if (inex >= 0 && (rnd == GMP_RNDD || (rnd == GMP_RNDZ && signz > 0) || (rnd == GMP_RNDN && signy > 0))) { printf (ERRTU1 "ternary value = %d instead of < 0\n", signy, signz, mpfr_print_rnd_mode (rnd), inex); err = 1; } if (inex <= 0 && (rnd == GMP_RNDU || (rnd == GMP_RNDZ && signz < 0) || (rnd == GMP_RNDN && signy < 0))) { printf (ERRTU1 "ternary value = %d instead of > 0\n", signy, signz, mpfr_print_rnd_mode (rnd), inex); err = 1; } } } } if (err) exit (1); mpfr_clears (x, y, z, r, (void *) 0); }
static void special (void) { mpfr_t x, y; int inex; int sign; mpfr_init (x); mpfr_init (y); mpfr_set_nan (x); mpfr_lgamma (y, &sign, x, GMP_RNDN); if (!mpfr_nan_p (y)) { printf ("Error for lgamma(NaN)\n"); exit (1); } mpfr_set_inf (x, -1); mpfr_lgamma (y, &sign, x, GMP_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) { printf ("Error for lgamma(-Inf)\n"); exit (1); } mpfr_set_inf (x, 1); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != 1) { printf ("Error for lgamma(+Inf)\n"); exit (1); } mpfr_set_ui (x, 0, GMP_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != 1) { printf ("Error for lgamma(+0)\n"); exit (1); } mpfr_set_ui (x, 0, GMP_RNDN); mpfr_neg (x, x, GMP_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != -1) { printf ("Error for lgamma(-0)\n"); exit (1); } mpfr_set_ui (x, 1, GMP_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y) || sign != 1) { printf ("Error for lgamma(1)\n"); exit (1); } mpfr_set_si (x, -1, GMP_RNDN); mpfr_lgamma (y, &sign, x, GMP_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) { printf ("Error for lgamma(-1)\n"); exit (1); } mpfr_set_ui (x, 2, GMP_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y) || sign != 1) { printf ("Error for lgamma(2)\n"); exit (1); } mpfr_set_prec (x, 53); mpfr_set_prec (y, 53); #define CHECK_X1 "1.0762904832837976166" #define CHECK_Y1 "-0.039418362817587634939" mpfr_set_str (x, CHECK_X1, 10, GMP_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str (x, CHECK_Y1, 10, GMP_RNDN); if (mpfr_equal_p (y, x) == 0 || sign != 1) { printf ("mpfr_lgamma("CHECK_X1") is wrong:\n" "expected "); mpfr_print_binary (x); putchar ('\n'); printf ("got "); mpfr_print_binary (y); putchar ('\n'); exit (1); } #define CHECK_X2 "9.23709516716202383435e-01" #define CHECK_Y2 "0.049010669407893718563" mpfr_set_str (x, CHECK_X2, 10, GMP_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str (x, CHECK_Y2, 10, GMP_RNDN); if (mpfr_equal_p (y, x) == 0 || sign != 1) { printf ("mpfr_lgamma("CHECK_X2") is wrong:\n" "expected "); mpfr_print_binary (x); putchar ('\n'); printf ("got "); mpfr_print_binary (y); putchar ('\n'); exit (1); } mpfr_set_prec (x, 8); mpfr_set_prec (y, 175); mpfr_set_ui (x, 33, GMP_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDU); mpfr_set_prec (x, 175); mpfr_set_str_binary (x, "0.1010001100011101101011001101110010100001000001000001110011000001101100001111001001000101011011100100010101011110100111110101010100010011010010000101010111001100011000101111E7"); if (mpfr_equal_p (x, y) == 0 || sign != 1) { printf ("Error in mpfr_lgamma (1)\n"); exit (1); } mpfr_set_prec (x, 21); mpfr_set_prec (y, 8); mpfr_set_ui (y, 120, GMP_RNDN); sign = -17; mpfr_lgamma (x, &sign, y, GMP_RNDZ); mpfr_set_prec (y, 21); mpfr_set_str_binary (y, "0.111000101000001100101E9"); if (mpfr_equal_p (x, y) == 0 || sign != 1) { printf ("Error in mpfr_lgamma (120)\n"); printf ("Expected "); mpfr_print_binary (y); puts (""); printf ("Got "); mpfr_print_binary (x); puts (""); exit (1); } mpfr_set_prec (x, 3); mpfr_set_prec (y, 206); mpfr_set_str_binary (x, "0.110e10"); sign = -17; inex = mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_prec (x, 206); mpfr_set_str_binary (x, "0.10000111011000000011100010101001100110001110000111100011000100100110110010001011011110101001111011110110000001010100111011010000000011100110110101100111000111010011110010000100010111101010001101000110101001E13"); if (mpfr_equal_p (x, y) == 0 || sign != 1) { printf ("Error in mpfr_lgamma (768)\n"); exit (1); } if (inex >= 0) { printf ("Wrong flag for mpfr_lgamma (768)\n"); exit (1); } mpfr_set_prec (x, 4); mpfr_set_prec (y, 4); mpfr_set_str_binary (x, "0.1100E-66"); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str_binary (x, "0.1100E6"); if (mpfr_equal_p (x, y) == 0 || sign != 1) { printf ("Error for lgamma(0.1100E-66)\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_prec (x, 256); mpfr_set_prec (y, 32); mpfr_set_si_2exp (x, -1, 200, GMP_RNDN); mpfr_add_ui (x, x, 1, GMP_RNDN); mpfr_div_2ui (x, x, 1, GMP_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_prec (x, 32); mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207"); if (mpfr_equal_p (x, y) == 0 || sign != 1) { printf ("Error for lgamma(-2^199+0.5)\n"); printf ("Got "); mpfr_dump (y); printf ("instead of "); mpfr_dump (x); exit (1); } mpfr_set_prec (x, 256); mpfr_set_prec (y, 32); mpfr_set_si_2exp (x, -1, 200, GMP_RNDN); mpfr_sub_ui (x, x, 1, GMP_RNDN); mpfr_div_2ui (x, x, 1, GMP_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_prec (x, 32); mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207"); if (mpfr_equal_p (x, y) == 0 || sign != -1) { printf ("Error for lgamma(-2^199-0.5)\n"); printf ("Got "); mpfr_dump (y); printf ("with sign %d instead of ", sign); mpfr_dump (x); printf ("with sign -1.\n"); exit (1); } mpfr_set_prec (x, 10); mpfr_set_prec (y, 10); mpfr_set_str_binary (x, "-0.1101111000E-3"); inex = mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str_binary (x, "10.01001011"); if (mpfr_equal_p (x, y) == 0 || sign != -1 || inex >= 0) { printf ("Error for lgamma(-0.1101111000E-3)\n"); printf ("Got "); mpfr_dump (y); printf ("instead of "); mpfr_dump (x); printf ("with sign %d instead of -1 (inex=%d).\n", sign, inex); exit (1); } mpfr_set_prec (x, 18); mpfr_set_prec (y, 28); mpfr_set_str_binary (x, "-1.10001101010001101e-196"); inex = mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_prec (x, 28); mpfr_set_str_binary (x, "0.100001110110101011011010011E8"); MPFR_ASSERTN (mpfr_equal_p (x, y) && inex < 0); /* values reported by Kaveh Ghazi on 14 Jul 2007, where mpfr_lgamma() takes forever */ #define VAL1 "-0.11100001001010110111001010001001001011110100110000110E-55" #define OUT1 "100110.01000000010111001110110101110101001001100110111" #define VAL2 "-0.11100001001010110111001010001001001011110011111111100E-55" #define OUT2 "100110.0100000001011100111011010111010100100110011111" #define VAL3 "-0.11100001001010110111001010001001001001110101101010100E-55" #define OUT3 "100110.01000000010111001110110101110101001011110111011" #define VAL4 "-0.10001111110110110100100100000000001111110001001001011E-57" #define OUT4 "101000.0001010111110011101101000101111111010001100011" #define VAL5 "-0.10001111110110110100100100000000001111011111100001000E-57" #define OUT5 "101000.00010101111100111011010001011111110100111000001" #define VAL6 "-0.10001111110110110100100100000000001111011101100011001E-57" #define OUT6 "101000.0001010111110011101101000101111111010011101111" mpfr_set_prec (x, 53); mpfr_set_prec (y, 53); mpfr_set_str_binary (x, VAL1); mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str_binary (x, OUT1); MPFR_ASSERTN(sign == -1 && mpfr_equal_p(x, y)); mpfr_set_str_binary (x, VAL2); mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str_binary (x, OUT2); MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); mpfr_set_str_binary (x, VAL3); mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str_binary (x, OUT3); MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); mpfr_set_str_binary (x, VAL4); mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str_binary (x, OUT4); MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); mpfr_set_str_binary (x, VAL5); mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str_binary (x, OUT5); MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); mpfr_set_str_binary (x, VAL6); mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str_binary (x, OUT6); MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); /* further test from Kaveh Ghazi */ mpfr_set_str_binary (x, "-0.10011010101001010010001110010111010111011101010111001E-53"); mpfr_lgamma (y, &sign, x, GMP_RNDN); mpfr_set_str_binary (x, "100101.00111101101010000000101010111010001111001101111"); MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); mpfr_clear (x); mpfr_clear (y); }
tree ubsan_instrument_float_cast (location_t loc, tree type, tree expr) { tree expr_type = TREE_TYPE (expr); tree t, tt, fn, min, max; enum machine_mode mode = TYPE_MODE (expr_type); int prec = TYPE_PRECISION (type); bool uns_p = TYPE_UNSIGNED (type); /* Float to integer conversion first truncates toward zero, so even signed char c = 127.875f; is not problematic. Therefore, we should complain only if EXPR is unordered or smaller or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than TYPE_MAX_VALUE + 1.0. */ if (REAL_MODE_FORMAT (mode)->b == 2) { /* For maximum, TYPE_MAX_VALUE might not be representable in EXPR_TYPE, e.g. if TYPE is 64-bit long long and EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is either representable or infinity. */ REAL_VALUE_TYPE maxval = dconst1; SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p); real_convert (&maxval, mode, &maxval); max = build_real (expr_type, maxval); /* For unsigned, assume -1.0 is always representable. */ if (uns_p) min = build_minus_one_cst (expr_type); else { /* TYPE_MIN_VALUE is generally representable (or -inf), but TYPE_MIN_VALUE - 1.0 might not be. */ REAL_VALUE_TYPE minval = dconstm1, minval2; SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1); real_convert (&minval, mode, &minval); real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1); real_convert (&minval2, mode, &minval2); if (real_compare (EQ_EXPR, &minval, &minval2) && !real_isinf (&minval)) { /* If TYPE_MIN_VALUE - 1.0 is not representable and rounds to TYPE_MIN_VALUE, we need to subtract more. As REAL_MODE_FORMAT (mode)->p is the number of base digits, we want to subtract a number that will be 1 << (REAL_MODE_FORMAT (mode)->p - 1) times smaller than minval. */ minval2 = dconst1; gcc_assert (prec > REAL_MODE_FORMAT (mode)->p); SET_REAL_EXP (&minval2, REAL_EXP (&minval2) + prec - 1 - REAL_MODE_FORMAT (mode)->p + 1); real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2); real_convert (&minval2, mode, &minval2); } min = build_real (expr_type, minval2); } } else if (REAL_MODE_FORMAT (mode)->b == 10) { /* For _Decimal128 up to 34 decimal digits, - sign, dot, e, exponent. */ char buf[64]; mpfr_t m; int p = REAL_MODE_FORMAT (mode)->p; REAL_VALUE_TYPE maxval, minval; /* Use mpfr_snprintf rounding to compute the smallest representable decimal number greater or equal than 1 << (prec - !uns_p). */ mpfr_init2 (m, prec + 2); mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN); mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m); decimal_real_from_string (&maxval, buf); max = build_real (expr_type, maxval); /* For unsigned, assume -1.0 is always representable. */ if (uns_p) min = build_minus_one_cst (expr_type); else { /* Use mpfr_snprintf rounding to compute the largest representable decimal number less or equal than (-1 << (prec - 1)) - 1. */ mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN); mpfr_sub_ui (m, m, 1, GMP_RNDN); mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m); decimal_real_from_string (&minval, buf); min = build_real (expr_type, minval); } mpfr_clear (m); } else return NULL_TREE; if (flag_sanitize_undefined_trap_on_error) fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0); else { /* Create the __ubsan_handle_float_cast_overflow fn call. */ tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", NULL, NULL, ubsan_type_descriptor (expr_type), ubsan_type_descriptor (type), NULL_TREE); enum built_in_function bcode = flag_sanitize_recover ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT; fn = builtin_decl_explicit (bcode); fn = build_call_expr_loc (loc, fn, 2, build_fold_addr_expr_loc (loc, data), ubsan_encode_value (expr, false)); } t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min); tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max); return fold_build3 (COND_EXPR, void_type_node, fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt), fn, integer_zero_node); }
static void underflows (void) { mpfr_t x, y, z; int err = 0; int inexact; int i; mp_exp_t emin; mpfr_init2 (x, 64); mpfr_init2 (y, 64); mpfr_set_ui (x, 1, GMP_RNDN); mpfr_set_exp (x, mpfr_get_emin()); for (i = 3; i < 10; i++) { mpfr_set_ui (y, i, GMP_RNDN); mpfr_div_2ui (y, y, 1, GMP_RNDN); test_pow (y, x, y, GMP_RNDN); if (!MPFR_IS_FP(y) || mpfr_cmp_ui (y, 0)) { printf ("Error in mpfr_pow for "); mpfr_out_str (stdout, 2, 0, x, GMP_RNDN); printf (" ^ (%d/2)\nGot ", i); mpfr_out_str (stdout, 2, 0, y, GMP_RNDN); printf (" instead of 0.\n"); exit (1); } } mpfr_init2 (z, 55); mpfr_set_str (x, "0.110011010011101001110001110100010000110111101E0", 2, GMP_RNDN); mpfr_set_str (y, "0.101110010011111001011010100011011100111110011E40", 2, GMP_RNDN); mpfr_clear_flags (); inexact = mpfr_pow (z, x, y, GMP_RNDU); if (!mpfr_underflow_p ()) { printf ("Underflow flag is not set for special underflow test.\n"); err = 1; } if (inexact <= 0) { printf ("Ternary value is wrong for special underflow test.\n"); err = 1; } mpfr_set_ui (x, 0, GMP_RNDN); mpfr_nextabove (x); if (mpfr_cmp (x, z) != 0) { printf ("Wrong value for special underflow test.\nGot "); mpfr_out_str (stdout, 2, 0, z, GMP_RNDN); printf ("\ninstead of "); mpfr_out_str (stdout, 2, 2, x, GMP_RNDN); printf ("\n"); err = 1; } if (err) exit (1); /* MPFR currently (2006-08-19) segfaults on the following code (and possibly makes other programs crash due to the lack of memory), because y is converted into an mpz_t, and the required precision is too high. */ mpfr_set_prec (x, 2); mpfr_set_prec (y, 2); mpfr_set_prec (z, 12); mpfr_set_ui_2exp (x, 3, -2, GMP_RNDN); mpfr_set_ui_2exp (y, 1, mpfr_get_emax () - 1, GMP_RNDN); mpfr_clear_flags (); mpfr_pow (z, x, y, GMP_RNDN); if (!mpfr_underflow_p () || MPFR_NOTZERO (z)) { printf ("Underflow test with large y fails.\n"); exit (1); } emin = mpfr_get_emin (); mpfr_set_emin (-256); mpfr_set_prec (x, 2); mpfr_set_prec (y, 2); mpfr_set_prec (z, 12); mpfr_set_ui_2exp (x, 3, -2, GMP_RNDN); mpfr_set_ui_2exp (y, 1, 38, GMP_RNDN); mpfr_clear_flags (); inexact = mpfr_pow (z, x, y, GMP_RNDN); if (!mpfr_underflow_p () || MPFR_NOTZERO (z) || inexact >= 0) { printf ("Bad underflow detection for 0.75^(2^38). Obtained:\n" "Underflow flag... %-3s (should be 'yes')\n" "Zero result...... %-3s (should be 'yes')\n" "Inexact value.... %-3d (should be negative)\n", mpfr_underflow_p () ? "yes" : "no", MPFR_IS_ZERO (z) ? "yes" : "no", inexact); exit (1); } mpfr_set_emin (emin); emin = mpfr_get_emin (); mpfr_set_emin (-256); mpfr_set_prec (x, 2); mpfr_set_prec (y, 40); mpfr_set_prec (z, 12); mpfr_set_ui_2exp (x, 3, -1, GMP_RNDN); mpfr_set_si_2exp (y, -1, 38, GMP_RNDN); for (i = 0; i < 4; i++) { if (i == 2) mpfr_neg (x, x, GMP_RNDN); mpfr_clear_flags (); inexact = mpfr_pow (z, x, y, GMP_RNDN); if (!mpfr_underflow_p () || MPFR_NOTZERO (z) || (i == 3 ? (inexact <= 0) : (inexact >= 0))) { printf ("Bad underflow detection for ("); mpfr_out_str (stdout, 10, 0, x, GMP_RNDN); printf (")^(-2^38-%d). Obtained:\n" "Overflow flag.... %-3s (should be 'no')\n" "Underflow flag... %-3s (should be 'yes')\n" "Zero result...... %-3s (should be 'yes')\n" "Inexact value.... %-3d (should be %s)\n", i, mpfr_overflow_p () ? "yes" : "no", mpfr_underflow_p () ? "yes" : "no", MPFR_IS_ZERO (z) ? "yes" : "no", inexact, i == 3 ? "positive" : "negative"); exit (1); } inexact = mpfr_sub_ui (y, y, 1, GMP_RNDN); MPFR_ASSERTN (inexact == 0); } mpfr_set_emin (emin); mpfr_clears (x, y, z, (void *) 0); }
int mpfr_zeta (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode) { mpfr_t z_pre, s1, y, p; double sd, eps, m1, c; long add; mp_prec_t precz, prec1, precs, precs1; int inex; MPFR_GROUP_DECL (group); MPFR_ZIV_DECL (loop); MPFR_SAVE_EXPO_DECL (expo); MPFR_LOG_FUNC (("s[%#R]=%R rnd=%d", s, s, rnd_mode), ("z[%#R]=%R inexact=%d", z, z, inex)); /* Zero, Nan or Inf ? */ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (s))) { if (MPFR_IS_NAN (s)) { MPFR_SET_NAN (z); MPFR_RET_NAN; } else if (MPFR_IS_INF (s)) { if (MPFR_IS_POS (s)) return mpfr_set_ui (z, 1, GMP_RNDN); /* Zeta(+Inf) = 1 */ MPFR_SET_NAN (z); /* Zeta(-Inf) = NaN */ MPFR_RET_NAN; } else /* s iz zero */ { MPFR_ASSERTD (MPFR_IS_ZERO (s)); mpfr_set_ui (z, 1, rnd_mode); mpfr_div_2ui (z, z, 1, rnd_mode); MPFR_CHANGE_SIGN (z); MPFR_RET (0); } } /* s is neither Nan, nor Inf, nor Zero */ /* check tiny s: we have zeta(s) = -1/2 - 1/2 log(2 Pi) s + ... around s=0, and for |s| <= 0.074, we have |zeta(s) + 1/2| <= |s|. Thus if |s| <= 1/4*ulp(1/2), we can deduce the correct rounding (the 1/4 covers the case where |zeta(s)| < 1/2 and rounding to nearest). A sufficient condition is that EXP(s) + 1 < -PREC(z). */ if (MPFR_EXP(s) + 1 < - (mp_exp_t) MPFR_PREC(z)) { int signs = MPFR_SIGN(s); mpfr_set_si_2exp (z, -1, -1, rnd_mode); /* -1/2 */ if ((rnd_mode == GMP_RNDU || rnd_mode == GMP_RNDZ) && signs < 0) { mpfr_nextabove (z); /* z = -1/2 + epsilon */ inex = 1; } else if (rnd_mode == GMP_RNDD && signs > 0) { mpfr_nextbelow (z); /* z = -1/2 - epsilon */ inex = -1; } else { if (rnd_mode == GMP_RNDU) /* s > 0: z = -1/2 */ inex = 1; else if (rnd_mode == GMP_RNDD) inex = -1; /* s < 0: z = -1/2 */ else /* (GMP_RNDZ and s > 0) or GMP_RNDN: z = -1/2 */ inex = (signs > 0) ? 1 : -1; } return mpfr_check_range (z, inex, rnd_mode); } /* Check for case s= -2n */ if (MPFR_IS_NEG (s)) { mpfr_t tmp; tmp[0] = *s; MPFR_EXP (tmp) = MPFR_EXP (s) - 1; if (mpfr_integer_p (tmp)) { MPFR_SET_ZERO (z); MPFR_SET_POS (z); MPFR_RET (0); } } MPFR_SAVE_EXPO_MARK (expo); /* Compute Zeta */ if (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0) /* Case s >= 1/2 */ inex = mpfr_zeta_pos (z, s, rnd_mode); else /* use reflection formula zeta(s) = 2^s*Pi^(s-1)*sin(Pi*s/2)*gamma(1-s)*zeta(1-s) */ { precz = MPFR_PREC (z); precs = MPFR_PREC (s); /* Precision precs1 needed to represent 1 - s, and s + 2, without any truncation */ precs1 = precs + 2 + MAX (0, - MPFR_GET_EXP (s)); sd = mpfr_get_d (s, GMP_RNDN) - 1.0; if (sd < 0.0) sd = -sd; /* now sd = abs(s-1.0) */ /* Precision prec1 is the precision on elementary computations; it ensures a final precision prec1 - add for zeta(s) */ /* eps = pow (2.0, - (double) precz - 14.0); */ eps = __gmpfr_ceil_exp2 (- (double) precz - 14.0); m1 = 1.0 + MAX(1.0 / eps, 2.0 * sd) * (1.0 + eps); c = (1.0 + eps) * (1.0 + eps * MAX(8.0, m1)); /* add = 1 + floor(log(c*c*c*(13 + m1))/log(2)); */ add = __gmpfr_ceil_log2 (c * c * c * (13.0 + m1)); prec1 = precz + add; prec1 = MAX (prec1, precs1) + 10; MPFR_GROUP_INIT_4 (group, prec1, z_pre, s1, y, p); MPFR_ZIV_INIT (loop, prec1); for (;;) { mpfr_sub (s1, __gmpfr_one, s, GMP_RNDN);/* s1 = 1-s */ mpfr_zeta_pos (z_pre, s1, GMP_RNDN); /* zeta(1-s) */ mpfr_gamma (y, s1, GMP_RNDN); /* gamma(1-s) */ if (MPFR_IS_INF (y)) /* Zeta(s) < 0 for -4k-2 < s < -4k, Zeta(s) > 0 for -4k < s < -4k+2 */ { MPFR_SET_INF (z_pre); mpfr_div_2ui (s1, s, 2, GMP_RNDN); /* s/4, exact */ mpfr_frac (s1, s1, GMP_RNDN); /* exact, -1 < s1 < 0 */ if (mpfr_cmp_si_2exp (s1, -1, -1) > 0) MPFR_SET_NEG (z_pre); else MPFR_SET_POS (z_pre); break; } mpfr_mul (z_pre, z_pre, y, GMP_RNDN); /* gamma(1-s)*zeta(1-s) */ mpfr_const_pi (p, GMP_RNDD); mpfr_mul (y, s, p, GMP_RNDN); mpfr_div_2ui (y, y, 1, GMP_RNDN); /* s*Pi/2 */ mpfr_sin (y, y, GMP_RNDN); /* sin(Pi*s/2) */ mpfr_mul (z_pre, z_pre, y, GMP_RNDN); mpfr_mul_2ui (y, p, 1, GMP_RNDN); /* 2*Pi */ mpfr_neg (s1, s1, GMP_RNDN); /* s-1 */ mpfr_pow (y, y, s1, GMP_RNDN); /* (2*Pi)^(s-1) */ mpfr_mul (z_pre, z_pre, y, GMP_RNDN); mpfr_mul_2ui (z_pre, z_pre, 1, GMP_RNDN); if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, prec1 - add, precz, rnd_mode))) break; MPFR_ZIV_NEXT (loop, prec1); MPFR_GROUP_REPREC_4 (group, prec1, z_pre, s1, y, p); } MPFR_ZIV_FREE (loop); inex = mpfr_set (z, z_pre, rnd_mode); MPFR_GROUP_CLEAR (group); } MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (z, inex, rnd_mode); }
static void check_pow_si (void) { mpfr_t x; mpfr_init (x); mpfr_set_nan (x); mpfr_pow_si (x, x, -1, GMP_RNDN); MPFR_ASSERTN(mpfr_nan_p (x)); mpfr_set_inf (x, 1); mpfr_pow_si (x, x, -1, GMP_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); mpfr_set_inf (x, -1); mpfr_pow_si (x, x, -1, GMP_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG(x)); mpfr_set_inf (x, -1); mpfr_pow_si (x, x, -2, GMP_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); mpfr_set_ui (x, 0, GMP_RNDN); mpfr_pow_si (x, x, -1, GMP_RNDN); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); mpfr_set_ui (x, 0, GMP_RNDN); mpfr_neg (x, x, GMP_RNDN); mpfr_pow_si (x, x, -1, GMP_RNDN); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0); mpfr_set_ui (x, 0, GMP_RNDN); mpfr_neg (x, x, GMP_RNDN); mpfr_pow_si (x, x, -2, GMP_RNDN); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); mpfr_set_si (x, 2, GMP_RNDN); mpfr_pow_si (x, x, LONG_MAX, GMP_RNDN); /* 2^LONG_MAX */ if (LONG_MAX > mpfr_get_emax () - 1) /* LONG_MAX + 1 > emax */ { MPFR_ASSERTN (mpfr_inf_p (x)); } else { MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, LONG_MAX)); } mpfr_set_si (x, 2, GMP_RNDN); mpfr_pow_si (x, x, LONG_MIN, GMP_RNDN); /* 2^LONG_MIN */ if (LONG_MIN + 1 < mpfr_get_emin ()) { MPFR_ASSERTN (mpfr_zero_p (x)); } else { MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, LONG_MIN)); } mpfr_set_si (x, 2, GMP_RNDN); mpfr_pow_si (x, x, LONG_MIN + 1, GMP_RNDN); /* 2^(LONG_MIN+1) */ if (mpfr_nan_p (x)) { printf ("Error in pow_si(2, LONG_MIN+1): got NaN\n"); exit (1); } if (LONG_MIN + 2 < mpfr_get_emin ()) { MPFR_ASSERTN (mpfr_zero_p (x)); } else { MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, LONG_MIN + 1)); } mpfr_set_si_2exp (x, 1, -1, GMP_RNDN); /* 0.5 */ mpfr_pow_si (x, x, LONG_MIN, GMP_RNDN); /* 2^(-LONG_MIN) */ if (LONG_MIN < 1 - mpfr_get_emax ()) /* 1 - LONG_MIN > emax */ { MPFR_ASSERTN (mpfr_inf_p (x)); } else { MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 2, - (LONG_MIN + 1))); } mpfr_clear (x); }
int mpfr_frexp (mpfr_exp_t *exp, mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) { int inex; mpfr_flags_t saved_flags = __gmpfr_flags; MPFR_BLOCK_DECL (flags); MPFR_LOG_FUNC (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd), ("y[%Pu]=%.*Rg exp=%" MPFR_EXP_FSPEC "d inex=%d", mpfr_get_prec (y), mpfr_log_prec, y, (mpfr_eexp_t) *exp, inex)); if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x))) { if (MPFR_IS_NAN(x)) { MPFR_SET_NAN(y); MPFR_RET_NAN; /* exp is unspecified */ } else if (MPFR_IS_INF(x)) { MPFR_SET_INF(y); MPFR_SET_SAME_SIGN(y,x); MPFR_RET(0); /* exp is unspecified */ } else { MPFR_SET_ZERO(y); MPFR_SET_SAME_SIGN(y,x); *exp = 0; MPFR_RET(0); } } MPFR_BLOCK (flags, inex = mpfr_set (y, x, rnd)); __gmpfr_flags = saved_flags; /* Possible overflow due to the rounding, no possible underflow. */ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags))) { int inex2; /* An overflow here means that the exponent of y would be larger than the one of x, thus x would be rounded to the next power of 2, and the returned y should be 1/2 in absolute value, rounded (i.e. with possible underflow or overflow). This also implies that x and y are different objects, so that the exponent of x has not been lost. */ MPFR_LOG_MSG (("Internal overflow\n", 0)); MPFR_ASSERTD (x != y); *exp = MPFR_GET_EXP (x) + 1; inex2 = mpfr_set_si_2exp (y, MPFR_INT_SIGN (x), -1, rnd); MPFR_LOG_MSG (("inex=%d inex2=%d\n", inex, inex2)); if (inex2 != 0) inex = inex2; MPFR_RET (inex); } *exp = MPFR_GET_EXP (y); /* Do not use MPFR_SET_EXP because the range has not been checked yet. */ MPFR_EXP (y) = 0; return mpfr_check_range (y, inex, rnd); }
int mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mpfr_rnd_t rnd) { MPFR_LOG_FUNC (("x[%Pu]=%.*Rg n=%ld rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, n, rnd), ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y)); if (n >= 0) return mpfr_pow_ui (y, x, n, rnd); else { if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x))) { if (MPFR_IS_NAN (x)) { MPFR_SET_NAN (y); MPFR_RET_NAN; } else { int positive = MPFR_IS_POS (x) || ((unsigned long) n & 1) == 0; if (MPFR_IS_INF (x)) MPFR_SET_ZERO (y); else /* x is zero */ { MPFR_ASSERTD (MPFR_IS_ZERO (x)); MPFR_SET_INF (y); mpfr_set_divby0 (); } if (positive) MPFR_SET_POS (y); else MPFR_SET_NEG (y); MPFR_RET (0); } } /* detect exact powers: x^(-n) is exact iff x is a power of 2 */ if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), MPFR_EXP(x) - 1) == 0) { mpfr_exp_t expx = MPFR_EXP (x) - 1, expy; MPFR_ASSERTD (n < 0); /* Warning: n * expx may overflow! * * Some systems (apparently alpha-freebsd) abort with * LONG_MIN / 1, and LONG_MIN / -1 is undefined. * http://www.freebsd.org/cgi/query-pr.cgi?pr=72024 * * Proof of the overflow checking. The expressions below are * assumed to be on the rational numbers, but the word "overflow" * still has its own meaning in the C context. / still denotes * the integer (truncated) division, and // denotes the exact * division. * - First, (__gmpfr_emin - 1) / n and (__gmpfr_emax - 1) / n * cannot overflow due to the constraints on the exponents of * MPFR numbers. * - If n = -1, then n * expx = - expx, which is representable * because of the constraints on the exponents of MPFR numbers. * - If expx = 0, then n * expx = 0, which is representable. * - If n < -1 and expx > 0: * + If expx > (__gmpfr_emin - 1) / n, then * expx >= (__gmpfr_emin - 1) / n + 1 * > (__gmpfr_emin - 1) // n, * and * n * expx < __gmpfr_emin - 1, * i.e. * n * expx <= __gmpfr_emin - 2. * This corresponds to an underflow, with a null result in * the rounding-to-nearest mode. * + If expx <= (__gmpfr_emin - 1) / n, then n * expx cannot * overflow since 0 < expx <= (__gmpfr_emin - 1) / n and * 0 > n * expx >= n * ((__gmpfr_emin - 1) / n) * >= __gmpfr_emin - 1. * - If n < -1 and expx < 0: * + If expx < (__gmpfr_emax - 1) / n, then * expx <= (__gmpfr_emax - 1) / n - 1 * < (__gmpfr_emax - 1) // n, * and * n * expx > __gmpfr_emax - 1, * i.e. * n * expx >= __gmpfr_emax. * This corresponds to an overflow (2^(n * expx) has an * exponent > __gmpfr_emax). * + If expx >= (__gmpfr_emax - 1) / n, then n * expx cannot * overflow since 0 > expx >= (__gmpfr_emax - 1) / n and * 0 < n * expx <= n * ((__gmpfr_emax - 1) / n) * <= __gmpfr_emax - 1. * Note: one could use expx bounds based on MPFR_EXP_MIN and * MPFR_EXP_MAX instead of __gmpfr_emin and __gmpfr_emax. The * current bounds do not lead to noticeably slower code and * allow us to avoid a bug in Sun's compiler for Solaris/x86 * (when optimizations are enabled); known affected versions: * cc: Sun C 5.8 2005/10/13 * cc: Sun C 5.8 Patch 121016-02 2006/03/31 * cc: Sun C 5.8 Patch 121016-04 2006/10/18 */ expy = n != -1 && expx > 0 && expx > (__gmpfr_emin - 1) / n ? MPFR_EMIN_MIN - 2 /* Underflow */ : n != -1 && expx < 0 && expx < (__gmpfr_emax - 1) / n ? MPFR_EMAX_MAX /* Overflow */ : n * expx; return mpfr_set_si_2exp (y, n % 2 ? MPFR_INT_SIGN (x) : 1, expy, rnd); } /* General case */ { /* Declaration of the intermediary variable */ mpfr_t t; /* Declaration of the size variable */ mpfr_prec_t Ny; /* target precision */ mpfr_prec_t Nt; /* working precision */ mpfr_rnd_t rnd1; int size_n; int inexact; unsigned long abs_n; MPFR_SAVE_EXPO_DECL (expo); MPFR_ZIV_DECL (loop); abs_n = - (unsigned long) n; count_leading_zeros (size_n, (mp_limb_t) abs_n); size_n = GMP_NUMB_BITS - size_n; /* initial working precision */ Ny = MPFR_PREC (y); Nt = Ny + size_n + 3 + MPFR_INT_CEIL_LOG2 (Ny); MPFR_SAVE_EXPO_MARK (expo); /* initialise of intermediary variable */ mpfr_init2 (t, Nt); /* We will compute rnd(rnd1(1/x) ^ |n|), where rnd1 is the rounding toward sign(x), to avoid spurious overflow or underflow, as in mpfr_pow_z. */ rnd1 = MPFR_EXP (x) < 1 ? MPFR_RNDZ : (MPFR_SIGN (x) > 0 ? MPFR_RNDU : MPFR_RNDD); MPFR_ZIV_INIT (loop, Nt); for (;;) { MPFR_BLOCK_DECL (flags); /* compute (1/x)^|n| */ MPFR_BLOCK (flags, mpfr_ui_div (t, 1, x, rnd1)); MPFR_ASSERTD (! MPFR_UNDERFLOW (flags)); /* t = (1/x)*(1+theta) where |theta| <= 2^(-Nt) */ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags))) goto overflow; MPFR_BLOCK (flags, mpfr_pow_ui (t, t, abs_n, rnd)); /* t = (1/x)^|n|*(1+theta')^(|n|+1) where |theta'| <= 2^(-Nt). If (|n|+1)*2^(-Nt) <= 1/2, which is satisfied as soon as Nt >= bits(n)+2, then we can use Lemma \ref{lemma_graillat} from algorithms.tex, which yields x^n*(1+theta) with |theta| <= 2(|n|+1)*2^(-Nt), thus the error is bounded by 2(|n|+1) ulps <= 2^(bits(n)+2) ulps. */ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags))) { overflow: MPFR_ZIV_FREE (loop); mpfr_clear (t); MPFR_SAVE_EXPO_FREE (expo); MPFR_LOG_MSG (("overflow\n", 0)); return mpfr_overflow (y, rnd, abs_n & 1 ? MPFR_SIGN (x) : MPFR_SIGN_POS); } if (MPFR_UNLIKELY (MPFR_UNDERFLOW (flags))) { MPFR_ZIV_FREE (loop); mpfr_clear (t); MPFR_LOG_MSG (("underflow\n", 0)); if (rnd == MPFR_RNDN) { mpfr_t y2, nn; /* We cannot decide now whether the result should be rounded toward zero or away from zero. So, like in mpfr_pow_pos_z, let's use the general case of mpfr_pow in precision 2. */ MPFR_ASSERTD (mpfr_cmp_si_2exp (x, MPFR_SIGN (x), MPFR_EXP (x) - 1) != 0); mpfr_init2 (y2, 2); mpfr_init2 (nn, sizeof (long) * CHAR_BIT); inexact = mpfr_set_si (nn, n, MPFR_RNDN); MPFR_ASSERTN (inexact == 0); inexact = mpfr_pow_general (y2, x, nn, rnd, 1, (mpfr_save_expo_t *) NULL); mpfr_clear (nn); mpfr_set (y, y2, MPFR_RNDN); mpfr_clear (y2); MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_UNDERFLOW); goto end; } else { MPFR_SAVE_EXPO_FREE (expo); return mpfr_underflow (y, rnd, abs_n & 1 ? MPFR_SIGN (x) : MPFR_SIGN_POS); } } /* error estimate -- see pow function in algorithms.ps */ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - size_n - 2, Ny, rnd))) break; /* actualisation of the precision */ MPFR_ZIV_NEXT (loop, Nt); mpfr_set_prec (t, Nt); } MPFR_ZIV_FREE (loop); inexact = mpfr_set (y, t, rnd); mpfr_clear (t); end: MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (y, inexact, rnd); } } }
static void normal (void) { int inexact; mpfr_t x, y; mpfr_init (x); mpfr_init (y); /* x1 = 2^-3 */ mpfr_set_str (x, "1p-3", 2, MPFR_RNDD); mpfr_li2 (x, x, MPFR_RNDN); if (mpfr_cmp_str (x, "0x1087a7a9e42141p-55", 16, MPFR_RNDN) != 0) { printf ("Error for li2(x1)\n"); exit (1); } /* check MPFR_FAST_COMPUTE_IF_SMALL_INPUT */ mpfr_set_prec (x, 2); mpfr_set_prec (y, 20); mpfr_set_ui_2exp (x, 1, -21, MPFR_RNDN); mpfr_li2 (y, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp (y, x) == 0); mpfr_set_si_2exp (x, -1, -21, MPFR_RNDN); mpfr_li2 (y, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp (y, x) == 0); /* worst case */ /* x2 = 0x7F18EA6537E00E983196CDDC6EFAC57Fp-129 Li2(x2) = 2^-2 + 2^-6 + 2^-120 */ mpfr_set_prec (x, 128); mpfr_set_str (x, "7F18EA6537E00E983196CDDC6EFAC57Fp-129", 16, MPFR_RNDN); /* round to nearest mode and 4 bits of precision, it should be rounded to 2^-2 + 2^-5 and */ mpfr_set_prec (y, 4); inexact = mpfr_li2 (y, x, MPFR_RNDN); if (inexact != 1 || mpfr_cmp_str (y, "0.1001p-1", 2, MPFR_RNDN) != 0) { printf ("Error for li2(x2, RNDN)\n"); exit (1); } /* round toward zero mode and 5 bits of precision, it should be rounded to 2^-2 + 2^-6 */ mpfr_set_prec (y, 5); inexact = mpfr_li2 (y, x, MPFR_RNDZ); if (inexact != -1 || mpfr_cmp_str (y, "0.10001p-1", 2, MPFR_RNDN) != 0) { printf ("Error for li2(x2, RNDZ)\n"); exit (1); } /* round away from zero mode and 5 bits of precision, it should be rounded to 2^-2 + 2^-5 */ inexact = mpfr_li2 (y, x, MPFR_RNDU); if (inexact != 1 || mpfr_cmp_str (y, "0.10010p-1", 2, MPFR_RNDN) != 0) { printf ("Error for li2(x2, RNDU)\n"); exit (1); } mpfr_clear (x); mpfr_clear (y); }
static void test_2exp (void) { mpfr_t x; int res; mpfr_init2 (x, 32); mpfr_set_ui_2exp (x, 1, 0, MPFR_RNDN); if (mpfr_cmp_ui(x, 1)) ERROR("(1U,0)"); mpfr_set_ui_2exp (x, 1024, -10, MPFR_RNDN); if (mpfr_cmp_ui(x, 1)) ERROR("(1024U,-10)"); mpfr_set_ui_2exp (x, 1024, 10, MPFR_RNDN); if (mpfr_cmp_ui(x, 1024*1024)) ERROR("(1024U,+10)"); mpfr_set_si_2exp (x, -1024L * 1024L, -10, MPFR_RNDN); if (mpfr_cmp_si(x, -1024)) ERROR("(1M,-10)"); mpfr_set_ui_2exp (x, 0x92345678, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "92345678@4", 16, MPFR_RNDN)) ERROR("(x92345678U,+16)"); mpfr_set_si_2exp (x, -0x1ABCDEF0, -256, MPFR_RNDN); if (mpfr_cmp_str (x, "-1ABCDEF0@-64", 16, MPFR_RNDN)) ERROR("(-x1ABCDEF0,-256)"); mpfr_set_prec (x, 2); res = mpfr_set_si_2exp (x, 7, 10, MPFR_RNDU); if (mpfr_cmp_ui (x, 1<<13) || res <= 0) ERROR ("Prec 2 + si_2exp"); res = mpfr_set_ui_2exp (x, 7, 10, MPFR_RNDU); if (mpfr_cmp_ui (x, 1<<13) || res <= 0) ERROR ("Prec 2 + ui_2exp"); mpfr_clear_flags (); mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN); if (!mpfr_inf_p (x) || MPFR_IS_NEG (x)) ERROR ("mpfr_set_ui_2exp and overflow (bad result)"); if (!mpfr_overflow_p ()) ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)"); mpfr_clear_flags (); mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN); if (!mpfr_inf_p (x) || MPFR_IS_NEG (x)) ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)"); if (!mpfr_overflow_p ()) ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)"); mpfr_clear_flags (); mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, MPFR_RNDN); if (!mpfr_inf_p (x) || MPFR_IS_POS (x)) ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)"); if (!mpfr_overflow_p ()) ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)"); mpfr_clear (x); }
static void overflowed_sec0 (void) { mpfr_t x, y; int emax, i, inex, rnd, err = 0; mpfr_exp_t old_emax; old_emax = mpfr_get_emax (); mpfr_init2 (x, 8); mpfr_init2 (y, 8); for (emax = -1; emax <= 0; emax++) { mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); mpfr_nextbelow (y); set_emax (emax); /* 1 is not representable. */ for (i = -1; i <= 1; i++) RND_LOOP (rnd) { mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); mpfr_clear_flags (); inex = mpfr_sec (x, x, (mpfr_rnd_t) rnd); if (! mpfr_overflow_p ()) { printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" " The overflow flag is not set.\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) { if (inex >= 0) { printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" " The inexact value must be negative.\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (! mpfr_equal_p (x, y)) { printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_print_binary (x); printf (" instead of 0.11111111E%d.\n", emax); err = 1; } } else { if (inex <= 0) { printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" " The inexact value must be positive.\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) { printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_print_binary (x); printf (" instead of +Inf.\n"); err = 1; } } } set_emax (old_emax); } if (err) exit (1); mpfr_clear (x); mpfr_clear (y); }
int main (void) { mpfr_prec_t prec; mpfr_t x, y; intmax_t s; uintmax_t u; tests_start_mpfr (); for (u = MPFR_UINTMAX_MAX, prec = 0; u != 0; u /= 2, prec++) { } mpfr_init2 (x, prec + 4); mpfr_init2 (y, prec + 4); mpfr_set_ui (x, 0, MPFR_RNDN); check_sj (0, x); check_uj (0, x); mpfr_set_ui (x, 1, MPFR_RNDN); check_sj (1, x); check_uj (1, x); mpfr_neg (x, x, MPFR_RNDN); check_sj (-1, x); mpfr_set_si_2exp (x, 1, prec, MPFR_RNDN); mpfr_sub_ui (x, x, 1, MPFR_RNDN); /* UINTMAX_MAX */ mpfr_div_ui (y, x, 2, MPFR_RNDZ); mpfr_trunc (y, y); /* INTMAX_MAX */ for (s = MPFR_INTMAX_MAX; s != 0; s /= 17) { check_sj (s, y); mpfr_div_ui (y, y, 17, MPFR_RNDZ); mpfr_trunc (y, y); } mpfr_div_ui (y, x, 2, MPFR_RNDZ); mpfr_trunc (y, y); /* INTMAX_MAX */ mpfr_neg (y, y, MPFR_RNDN); if (MPFR_INTMAX_MIN + MPFR_INTMAX_MAX != 0) mpfr_sub_ui (y, y, 1, MPFR_RNDN); /* INTMAX_MIN */ for (s = MPFR_INTMAX_MIN; s != 0; s /= 17) { check_sj (s, y); mpfr_div_ui (y, y, 17, MPFR_RNDZ); mpfr_trunc (y, y); } for (u = MPFR_UINTMAX_MAX; u != 0; u /= 17) { check_uj (u, x); mpfr_div_ui (x, x, 17, MPFR_RNDZ); mpfr_trunc (x, x); } mpfr_clear (x); mpfr_clear (y); check_erange (); tests_end_mpfr (); return 0; }
static void large_arg (void) { mpfr_t x, y; unsigned int flags; mpfr_init2 (x, 88); mpfr_init2 (y, 98); mpfr_set_si_2exp (x, -1, 173, MPFR_RNDN); mpfr_clear_flags (); mpfr_erfc (y, x, MPFR_RNDN); flags = __gmpfr_flags; if (mpfr_cmp_ui (y, 2) != 0) { printf ("mpfr_erfc failed for large x (1)\n"); exit (1); } if (flags != MPFR_FLAGS_INEXACT) { printf ("mpfr_erfc sets incorrect flags for large x (1)\n"); printf ("Expected %u, got %u\n", (unsigned int) MPFR_FLAGS_INEXACT, flags); exit (1); } mpfr_set_si_2exp (x, -1, mpfr_get_emax () - 3, MPFR_RNDN); mpfr_clear_flags (); mpfr_erfc (y, x, MPFR_RNDN); flags = __gmpfr_flags; if (mpfr_cmp_ui (y, 2) != 0) { printf ("mpfr_erfc failed for large x (1b)\n"); exit (1); } if (flags != MPFR_FLAGS_INEXACT) { printf ("mpfr_erfc sets incorrect flags for large x (1b)\n"); printf ("Expected %u, got %u\n", (unsigned int) MPFR_FLAGS_INEXACT, flags); exit (1); } mpfr_set_prec (x, 33); mpfr_set_prec (y, 43); mpfr_set_str_binary (x, "1.11000101010111011000111100101001e6"); mpfr_erfc (y, x, MPFR_RNDD); mpfr_set_prec (x, 43); mpfr_set_str_binary (x, "100010011100101100001101100101011101101E-18579"); if (mpfr_cmp (x, y) != 0) { printf ("mpfr_erfc failed for large x (2)\n"); exit (1); } mpfr_set_prec (y, 43); mpfr_set_si_2exp (x, 1, 11, MPFR_RNDN); mpfr_erfc (y, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.1100000100100010101111001111010010001000110E-6051113"); if (mpfr_cmp (x, y) != 0) { printf ("mpfr_erfc failed for large x (3)\n"); exit (1); } mpfr_set_prec (x, 75); mpfr_set_prec (y, 85); mpfr_set_str_binary (x, "0.111110111111010011101011001100001010011110101010011111010010111101010001011E15"); mpfr_erfc (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) { printf ("mpfr_erfc failed for large x (3b)\n"); exit (1); } mpfr_set_prec (x, 2); mpfr_set_prec (y, 21); mpfr_set_str_binary (x, "-1.0e3"); mpfr_clear_flags (); mpfr_erfc (y, x, MPFR_RNDZ); flags = __gmpfr_flags; mpfr_set_prec (x, 21); mpfr_set_str_binary (x, "1.11111111111111111111"); if (mpfr_cmp (x, y) != 0) { printf ("mpfr_erfc failed for large x (4)\n"); exit (1); } if (flags != MPFR_FLAGS_INEXACT) { printf ("mpfr_erfc sets incorrect flags for large x (4)\n"); printf ("Expected %u, got %u\n", (unsigned int) MPFR_FLAGS_INEXACT, flags); exit (1); } mpfr_set_prec (x, 2); mpfr_set_prec (y, 31); mpfr_set_str_binary (x, "-1.0e3"); mpfr_clear_flags (); mpfr_erfc (y, x, MPFR_RNDZ); flags = __gmpfr_flags; mpfr_set_prec (x, 31); mpfr_set_str_binary (x, "1.111111111111111111111111111111"); if (mpfr_cmp (x, y) != 0) { printf ("mpfr_erfc failed for x=-8, prec=31 (5)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } if (flags != MPFR_FLAGS_INEXACT) { printf ("mpfr_erfc sets incorrect flags for large x (5)\n"); printf ("Expected %u, got %u\n", (unsigned int) MPFR_FLAGS_INEXACT, flags); exit (1); } /* Reported by Christopher Creutzig on 2007-07-10. */ mpfr_set_prec (x, 53); mpfr_set_prec (y, 53); mpfr_set_si_2exp (x, 54563, -1, MPFR_RNDN); mpfr_erfc (y, x, MPFR_RNDZ); mpfr_set_ui (x, 0, MPFR_RNDN); if (! mpfr_equal_p (y, x)) { printf ("mpfr_erfc failed for x=27281.5, prec=53 (6)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } /* same test with rounding away from zero */ mpfr_set_si_2exp (x, 54563, -1, MPFR_RNDN); mpfr_erfc (y, x, MPFR_RNDU); mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_nextabove (x); if (! mpfr_equal_p (y, x)) { printf ("mpfr_erfc failed for x=27281.5, prec=53 (7)\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } mpfr_clear (x); mpfr_clear (y); }
static void test_overflow2 (void) { mpfr_t x, y, z, r; int i, inex, rnd, err = 0; mpfr_inits2 (8, x, y, z, r, (void *) 0); MPFR_SET_POS (x); mpfr_setmin (x, mpfr_get_emax ()); /* x = 0.1@emax */ mpfr_set_si (y, -2, GMP_RNDN); /* y = -2 */ /* The intermediate multiplication x * y will overflow. */ for (i = -9; i <= 9; i++) RND_LOOP (rnd) { int inf, overflow; inf = rnd == GMP_RNDN || rnd == GMP_RNDD; overflow = inf || i <= 0; inex = mpfr_set_si_2exp (z, i, mpfr_get_emin (), GMP_RNDN); MPFR_ASSERTN (inex == 0); mpfr_clear_flags (); /* One has: x * y = -1@emax exactly (but not representable). */ inex = mpfr_fma (r, x, y, z, rnd); if (overflow ^ (mpfr_overflow_p () != 0)) { printf ("Error in test_overflow2 (i = %d, %s): wrong overflow" " flag (should be %d)\n", i, mpfr_print_rnd_mode (rnd), overflow); err = 1; } if (mpfr_nanflag_p ()) { printf ("Error in test_overflow2 (i = %d, %s): NaN flag should" " not be set\n", i, mpfr_print_rnd_mode (rnd)); err = 1; } if (mpfr_nan_p (r)) { printf ("Error in test_overflow2 (i = %d, %s): got NaN\n", i, mpfr_print_rnd_mode (rnd)); err = 1; } else if (MPFR_SIGN (r) >= 0) { printf ("Error in test_overflow2 (i = %d, %s): wrong sign " "(+ instead of -)\n", i, mpfr_print_rnd_mode (rnd)); err = 1; } else if (inf && ! mpfr_inf_p (r)) { printf ("Error in test_overflow2 (i = %d, %s): expected -Inf," " got\n", i, mpfr_print_rnd_mode (rnd)); mpfr_dump (r); err = 1; } else if (!inf && (mpfr_inf_p (r) || (mpfr_nextbelow (r), ! mpfr_inf_p (r)))) { printf ("Error in test_overflow2 (i = %d, %s): expected -MAX," " got\n", i, mpfr_print_rnd_mode (rnd)); mpfr_dump (r); err = 1; } if (inf ? inex >= 0 : inex <= 0) { printf ("Error in test_overflow2 (i = %d, %s): wrong inexact" " flag (got %d)\n", i, mpfr_print_rnd_mode (rnd), inex); err = 1; } } if (err) exit (1); mpfr_clears (x, y, z, r, (void *) 0); }
int mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd) { if (n >= 0) return mpfr_pow_ui (y, x, n, rnd); else { if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x))) { if (MPFR_IS_NAN (x)) { MPFR_SET_NAN (y); MPFR_RET_NAN; } else if (MPFR_IS_INF (x)) { MPFR_SET_ZERO (y); if (MPFR_IS_POS (x) || ((unsigned) n & 1) == 0) MPFR_SET_POS (y); else MPFR_SET_NEG (y); MPFR_RET (0); } else /* x is zero */ { MPFR_ASSERTD (MPFR_IS_ZERO (x)); MPFR_SET_INF(y); if (MPFR_IS_POS (x) || ((unsigned) n & 1) == 0) MPFR_SET_POS (y); else MPFR_SET_NEG (y); MPFR_RET(0); } } MPFR_CLEAR_FLAGS (y); /* detect exact powers: x^(-n) is exact iff x is a power of 2 */ if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), MPFR_EXP(x) - 1) == 0) { mp_exp_t expx = MPFR_EXP (x) - 1, expy; MPFR_ASSERTD (n < 0); /* Warning: n * expx may overflow! * Some systems (apparently alpha-freebsd) abort with * LONG_MIN / 1, and LONG_MIN / -1 is undefined. * Proof of the overflow checking. The expressions below are * assumed to be on the rational numbers, but the word "overflow" * still has its own meaning in the C context. / still denotes * the integer (truncated) division, and // denotes the exact * division. * - First, (__gmpfr_emin - 1) / n and (__gmpfr_emax - 1) / n * cannot overflow due to the constraints on the exponents of * MPFR numbers. * - If n = -1, then n * expx = - expx, which is representable * because of the constraints on the exponents of MPFR numbers. * - If expx = 0, then n * expx = 0, which is representable. * - If n < -1 and expx > 0: * + If expx > (__gmpfr_emin - 1) / n, then * expx >= (__gmpfr_emin - 1) / n + 1 * > (__gmpfr_emin - 1) // n, * and * n * expx < __gmpfr_emin - 1, * i.e. * n * expx <= __gmpfr_emin - 2. * This corresponds to an underflow, with a null result in * the rounding-to-nearest mode. * + If expx <= (__gmpfr_emin - 1) / n, then n * expx cannot * overflow since 0 < expx <= (__gmpfr_emin - 1) / n and * 0 > n * expx >= n * ((__gmpfr_emin - 1) / n) * >= __gmpfr_emin - 1. * - If n < -1 and expx < 0: * + If expx < (__gmpfr_emax - 1) / n, then * expx <= (__gmpfr_emax - 1) / n - 1 * < (__gmpfr_emax - 1) // n, * and * n * expx > __gmpfr_emax - 1, * i.e. * n * expx >= __gmpfr_emax. * This corresponds to an overflow (2^(n * expx) has an * exponent > __gmpfr_emax). * + If expx >= (__gmpfr_emax - 1) / n, then n * expx cannot * overflow since 0 > expx >= (__gmpfr_emax - 1) / n and * 0 < n * expx <= n * ((__gmpfr_emax - 1) / n) * <= __gmpfr_emax - 1. * Note: one could use expx bounds based on MPFR_EXP_MIN and * MPFR_EXP_MAX instead of __gmpfr_emin and __gmpfr_emax. The * current bounds do not lead to noticeably slower code and * allow us to avoid a bug in Sun's compiler for Solaris/x86 * (when optimizations are enabled). */ expy = n != -1 && expx > 0 && expx > (__gmpfr_emin - 1) / n ? MPFR_EMIN_MIN - 2 /* Underflow */ : n != -1 && expx < 0 && expx < (__gmpfr_emax - 1) / n ? MPFR_EMAX_MAX /* Overflow */ : n * expx; return mpfr_set_si_2exp (y, n % 2 ? MPFR_INT_SIGN (x) : 1, expy, rnd); } /* General case */ { /* Declaration of the intermediary variable */ mpfr_t t; /* Declaration of the size variable */ mp_prec_t Ny = MPFR_PREC (y); /* target precision */ mp_prec_t Nt; /* working precision */ mp_exp_t err; /* error */ int inexact; unsigned long abs_n; MPFR_SAVE_EXPO_DECL (expo); MPFR_ZIV_DECL (loop); abs_n = - (unsigned long) n; /* compute the precision of intermediary variable */ /* the optimal number of bits : see algorithms.tex */ Nt = Ny + 3 + MPFR_INT_CEIL_LOG2 (Ny); MPFR_SAVE_EXPO_MARK (expo); /* initialise of intermediary variable */ mpfr_init2 (t, Nt); MPFR_ZIV_INIT (loop, Nt); for (;;) { /* compute 1/(x^n), with n > 0 */ mpfr_pow_ui (t, x, abs_n, GMP_RNDN); mpfr_ui_div (t, 1, t, GMP_RNDN); /* FIXME: old code improved, but I think this is still incorrect. */ if (MPFR_UNLIKELY (MPFR_IS_ZERO (t))) { MPFR_ZIV_FREE (loop); mpfr_clear (t); MPFR_SAVE_EXPO_FREE (expo); return mpfr_underflow (y, rnd == GMP_RNDN ? GMP_RNDZ : rnd, abs_n & 1 ? MPFR_SIGN (x) : MPFR_SIGN_POS); } if (MPFR_UNLIKELY (MPFR_IS_INF (t))) { MPFR_ZIV_FREE (loop); mpfr_clear (t); MPFR_SAVE_EXPO_FREE (expo); return mpfr_overflow (y, rnd, abs_n & 1 ? MPFR_SIGN (x) : MPFR_SIGN_POS); } /* error estimate -- see pow function in algorithms.ps */ err = Nt - 3; if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd))) break; /* actualisation of the precision */ Nt += BITS_PER_MP_LIMB; mpfr_set_prec (t, Nt); } MPFR_ZIV_FREE (loop); inexact = mpfr_set (y, t, rnd); mpfr_clear (t); MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (y, inexact, rnd); } } }
static int tiny_aux (int stop, mpfr_exp_t e) { mpfr_t x, y, z; int r, s, spm, inex, err = 0; int expected_dir[2][5] = { { 1, -1, 1, -1, 1 }, { 1, 1, 1, -1, -1 } }; mpfr_exp_t saved_emax; saved_emax = mpfr_get_emax (); mpfr_init2 (x, 32); mpfr_inits2 (8, y, z, (mpfr_ptr) 0); mpfr_set_ui_2exp (x, 1, e, MPFR_RNDN); spm = 1; for (s = 0; s < 2; s++) { RND_LOOP(r) { mpfr_rnd_t rr = (mpfr_rnd_t) r; mpfr_exp_t exponent, emax; /* Exponent of the rounded value in unbounded exponent range. */ exponent = expected_dir[s][r] < 0 && s == 0 ? - e : 1 - e; for (emax = exponent - 1; emax <= exponent; emax++) { unsigned int flags, expected_flags = MPFR_FLAGS_INEXACT; int overflow, expected_inex = expected_dir[s][r]; if (emax > MPFR_EMAX_MAX) break; mpfr_set_emax (emax); mpfr_clear_flags (); inex = mpfr_gamma (y, x, rr); flags = __gmpfr_flags; mpfr_clear_flags (); mpfr_set_si_2exp (z, spm, - e, MPFR_RNDU); overflow = mpfr_overflow_p (); /* z is 1/x - euler rounded toward +inf */ if (overflow && rr == MPFR_RNDN && s == 1) expected_inex = -1; if (expected_inex < 0) mpfr_nextbelow (z); /* 1/x - euler rounded toward -inf */ if (exponent > emax) expected_flags |= MPFR_FLAGS_OVERFLOW; if (!(mpfr_equal_p (y, z) && flags == expected_flags && SAME_SIGN (inex, expected_inex))) { printf ("Error in tiny for s = %d, r = %s, emax = %" MPFR_EXP_FSPEC "d%s\n on ", s, mpfr_print_rnd_mode (rr), emax, exponent > emax ? " (overflow)" : ""); mpfr_dump (x); printf (" expected inex = %2d, ", expected_inex); mpfr_dump (z); printf (" got inex = %2d, ", SIGN (inex)); mpfr_dump (y); printf (" expected flags = %u, got %u\n", expected_flags, flags); if (stop) exit (1); err = 1; } } } mpfr_neg (x, x, MPFR_RNDN); spm = - spm; } mpfr_clears (x, y, z, (mpfr_ptr) 0); mpfr_set_emax (saved_emax); return err; }
static void check_intmax (void) { #ifdef _MPFR_H_HAVE_INTMAX_T mpfr_t x, y; int i, r; mpfr_init2 (x, sizeof (uintmax_t) * CHAR_BIT); mpfr_init2 (y, 8); RND_LOOP (r) { /* Check NAN */ mpfr_set_nan (x); if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r)) ERROR1 (52); if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (53); /* Check INF */ mpfr_set_inf (x, 1); if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r)) ERROR1 (54); if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (55); /* Check Zero */ MPFR_SET_ZERO (x); if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r)) ERROR1 (56); if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (57); /* Check positive small op */ mpfr_set_str1 (x, "1@-1"); if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r)) ERROR1 (58); if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (59); /* Check 17 */ mpfr_set_ui (x, 17, MPFR_RNDN); if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r)) ERROR1 (60); if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (61); /* Check hugest */ mpfr_set_ui_2exp (x, 42, sizeof (uintmax_t) * 32, MPFR_RNDN); if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r)) ERROR1 (62); if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (63); /* Check all other values */ mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN); mpfr_add_ui (x, x, 1, MPFR_RNDN); if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r)) ERROR1 (64); mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN); if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r)) ERROR1 (65); mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN); mpfr_add_ui (x, x, 1, MPFR_RNDN); if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (66); mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN); if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (67); mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN); if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (68); mpfr_sub_ui (x, x, 1, MPFR_RNDN); if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (69); /* Check negative op */ for (i = 1; i <= 4; i++) { int inv; mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN); mpfr_rint (y, x, (mpfr_rnd_t) r); inv = MPFR_NOTZERO (y); if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r) ^ inv) ERROR1 (70); if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r)) ERROR1 (71); } } mpfr_clear (x); mpfr_clear (y); #endif }
int main (void) { mpfr_t x, y; float f, g, infp; int i; infp = (float) DBL_POS_INF; if (infp * 0.5 != infp) { fprintf (stderr, "Error, FLT_MAX + FLT_MAX does not yield INFP\n"); fprintf (stderr, "(this is probably a compiler bug, please report)\n"); exit (1); } tests_start_mpfr (); mpfr_init2 (x, 24); mpfr_init2 (y, 24); #if !defined(MPFR_ERRDIVZERO) mpfr_set_nan (x); f = mpfr_get_flt (x, MPFR_RNDN); if (f == f) { printf ("Error for mpfr_get_flt(NaN)\n"); exit (1); } mpfr_set_flt (x, f, MPFR_RNDN); if (mpfr_nan_p (x) == 0) { printf ("Error for mpfr_set_flt(NaN)\n"); exit (1); } mpfr_set_inf (x, 1); f = mpfr_get_flt (x, MPFR_RNDN); mpfr_set_flt (x, f, MPFR_RNDN); if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) < 0) { printf ("Error for mpfr_set_flt(mpfr_get_flt(+Inf)):\n"); printf ("f=%f, expected -Inf\n", f); printf ("got "); mpfr_dump (x); exit (1); } mpfr_set_inf (x, -1); f = mpfr_get_flt (x, MPFR_RNDN); mpfr_set_flt (x, f, MPFR_RNDN); if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) > 0) { printf ("Error for mpfr_set_flt(mpfr_get_flt(-Inf)):\n"); printf ("f=%f, expected -Inf\n", f); printf ("got "); mpfr_dump (x); exit (1); } #endif mpfr_set_ui (x, 0, MPFR_RNDN); f = mpfr_get_flt (x, MPFR_RNDN); mpfr_set_flt (x, f, MPFR_RNDN); if (mpfr_zero_p (x) == 0 || MPFR_SIGN (x) < 0) { printf ("Error for mpfr_set_flt(mpfr_get_flt(+0))\n"); exit (1); } #ifdef HAVE_SIGNEDZ mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); f = mpfr_get_flt (x, MPFR_RNDN); mpfr_set_flt (x, f, MPFR_RNDN); if (mpfr_zero_p (x) == 0 || MPFR_SIGN (x) > 0) { printf ("Error for mpfr_set_flt(mpfr_get_flt(-0))\n"); exit (1); } #endif /* HAVE_SIGNEDZ */ mpfr_set_ui (x, 17, MPFR_RNDN); f = mpfr_get_flt (x, MPFR_RNDN); mpfr_set_flt (x, f, MPFR_RNDN); if (mpfr_cmp_ui (x, 17) != 0) { printf ("Error for mpfr_set_flt(mpfr_get_flt(17))\n"); printf ("expected 17\n"); printf ("got "); mpfr_dump (x); exit (1); } mpfr_set_si (x, -42, MPFR_RNDN); f = mpfr_get_flt (x, MPFR_RNDN); mpfr_set_flt (x, f, MPFR_RNDN); if (mpfr_cmp_si (x, -42) != 0) { printf ("Error for mpfr_set_flt(mpfr_get_flt(-42))\n"); printf ("expected -42\n"); printf ("got "); mpfr_dump (x); exit (1); } mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN); for (i = -126; i < 128; i++) { f = mpfr_get_flt (x, MPFR_RNDN); mpfr_set_flt (y, f, MPFR_RNDN); if (mpfr_cmp (x, y) != 0) { printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } mpfr_mul_2exp (x, x, 1, MPFR_RNDN); } mpfr_set_prec (x, 53); mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN); for (i = -126; i < 128; i++) { mpfr_nextbelow (x); f = mpfr_get_flt (x, MPFR_RNDN); mpfr_nextabove (x); mpfr_set_flt (y, f, MPFR_RNDN); if (mpfr_cmp (x, y) != 0) { printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } mpfr_mul_2exp (x, x, 1, MPFR_RNDN); } mpfr_set_prec (x, 53); mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN); for (i = -126; i < 128; i++) { mpfr_nextabove (x); f = mpfr_get_flt (x, MPFR_RNDN); mpfr_nextbelow (x); mpfr_set_flt (y, f, MPFR_RNDN); if (mpfr_cmp (x, y) != 0) { printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n"); printf ("expected "); mpfr_dump (x); printf ("got "); mpfr_dump (y); exit (1); } mpfr_mul_2exp (x, x, 1, MPFR_RNDN); } mpfr_set_si_2exp (x, 1, -150, MPFR_RNDN); g = 0.0; f = mpfr_get_flt (x, MPFR_RNDN); if (f != g) { printf ("Error for mpfr_get_flt(2^(-150),RNDN)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDZ); if (f != g) { printf ("Error for mpfr_get_flt(2^(-150),RNDZ)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDD); if (f != g) { printf ("Error for mpfr_get_flt(2^(-150),RNDD)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } g = FLT_MIN * FLT_EPSILON; f = mpfr_get_flt (x, MPFR_RNDU); if (f != g) { printf ("Error for mpfr_get_flt(2^(-150),RNDU)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDA); if (f != g) { printf ("Error for mpfr_get_flt(2^(-150),RNDA)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } mpfr_set_si_2exp (x, 1, -151, MPFR_RNDN); g = 0.0; f = mpfr_get_flt (x, MPFR_RNDN); if (f != g) { printf ("Error for mpfr_get_flt(2^(-151),RNDN)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDZ); if (f != g) { printf ("Error for mpfr_get_flt(2^(-151),RNDZ)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDD); if (f != g) { printf ("Error for mpfr_get_flt(2^(-151),RNDD)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } g = FLT_MIN * FLT_EPSILON; f = mpfr_get_flt (x, MPFR_RNDU); if (f != g) { printf ("Error for mpfr_get_flt(2^(-151),RNDU)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDA); if (f != g) { printf ("Error for mpfr_get_flt(2^(-151),RNDA)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } mpfr_set_si_2exp (x, 1, -149, MPFR_RNDN); g = FLT_MIN * FLT_EPSILON; f = mpfr_get_flt (x, MPFR_RNDN); if (f != g) { printf ("Error for mpfr_get_flt(2^(-149),RNDN)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDZ); if (f != g) { printf ("Error for mpfr_get_flt(2^(-149),RNDZ)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDD); if (f != g) { printf ("Error for mpfr_get_flt(2^(-149),RNDD)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDU); if (f != g) { printf ("Error for mpfr_get_flt(2^(-149),RNDU)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDA); if (f != g) { printf ("Error for mpfr_get_flt(2^(-149),RNDA)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN); g = FLT_MAX; f = mpfr_get_flt (x, MPFR_RNDZ); if (f != g) { printf ("Error for mpfr_get_flt(2^128,RNDZ)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDD); if (f != g) { printf ("Error for mpfr_get_flt(2^128,RNDD)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } #if !defined(MPFR_ERRDIVZERO) f = mpfr_get_flt (x, MPFR_RNDN); /* 2^128 rounds to itself with extended exponent range, we should get +Inf */ g = infp; if (f != g) { printf ("Error for mpfr_get_flt(2^128,RNDN)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDU); if (f != g) { printf ("Error for mpfr_get_flt(2^128,RNDU)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDA); if (f != g) { printf ("Error for mpfr_get_flt(2^128,RNDA)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } #endif /* corner case: take x with 25 bits just below 2^128 */ mpfr_set_prec (x, 25); mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN); mpfr_nextbelow (x); g = FLT_MAX; f = mpfr_get_flt (x, MPFR_RNDZ); if (f != g) { printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDZ)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDD); if (f != g) { printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDD)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDN); /* first round to 2^128 (even rule), thus we should get +Inf */ g = infp; if (f != g) { printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDN)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDU); if (f != g) { printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDU)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } f = mpfr_get_flt (x, MPFR_RNDA); if (f != g) { printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDA)\n"); printf ("expected %.8e, got %.8e\n", g, f); exit (1); } mpfr_clear (x); mpfr_clear (y); tests_end_mpfr (); return 0; }
int mpfr_set_si (mpfr_ptr x, long i, mpfr_rnd_t rnd_mode) { return mpfr_set_si_2exp (x, i, 0, rnd_mode); }