static void check (const char *xis, const char *xfs, const char *xs, mpfr_prec_t xip, mpfr_prec_t xfp, mpfr_prec_t xp, int expected_return, mpfr_rnd_t rnd_mode) { int inexact; mpfr_t xi, xf, x; mpfr_init2 (xi, xip); mpfr_init2 (xf, xfp); mpfr_init2 (x, xp); mpfr_set_str1 (x, xs); inexact = mpfr_modf (xi, xf, x, rnd_mode); if (mpfr_cmp_str1 (xi, xis)) { printf ("mpfr_modf failed for x=%s, rnd=%s\n", xs, mpfr_print_rnd_mode(rnd_mode)); printf ("got integer value: "); mpfr_out_str (stdout, 10, 0, xi, MPFR_RNDN); printf ("\nexpected %s\n", xis); exit (1); } if (mpfr_cmp_str1 (xf, xfs)) { printf ("mpfr_modf failed for x=%s, rnd=%s\n", xs, mpfr_print_rnd_mode(rnd_mode)); printf ("got fractional value: "); mpfr_out_str (stdout, 10, 0, xf, MPFR_RNDN); printf ("\nexpected %s\n", xfs); exit (1); } if (inexact != expected_return) { printf ("mpfr_modf failed for x=%s, rnd=%s\n", xs, mpfr_print_rnd_mode(rnd_mode)); printf ("got return value: %d, expected %d\n", inexact, expected_return); exit (1); } mpfr_clears (xi, xf, x, (mpfr_ptr) 0); }
static void check_regression (void) { mpfr_t x, y; mpfr_prec_t p; int i; p = strlen (xs) - 2 - 3; mpfr_inits2 (p, x, y, (mpfr_ptr) 0); mpfr_set_str (x, xs, 2, MPFR_RNDN); i = mpfr_sin (y, x, MPFR_RNDN); if (i >= 0 || mpfr_cmp_str (y, "0.111001110011110011110001010110011101110E-1", 2, MPFR_RNDN)) { printf ("Regression test failed (1) i=%d\ny=", i); mpfr_dump (y); exit (1); } mpfr_clears (x, y, (mpfr_ptr) 0); }
/* TODO: A test with more inputs (but can't be compared to mpfr_add). */ static void check_extreme (void) { mpfr_t u, v, w, x, y; mpfr_ptr t[2]; int i, inex1, inex2, r; t[0] = u; t[1] = v; mpfr_inits2 (32, u, v, w, x, y, (mpfr_ptr) 0); mpfr_setmin (u, mpfr_get_emax ()); mpfr_setmax (v, mpfr_get_emin ()); mpfr_setmin (w, mpfr_get_emax () - 40); RND_LOOP (r) for (i = 0; i < 2; i++) { mpfr_set_prec (x, 64); inex1 = mpfr_add (x, u, w, MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); inex1 = mpfr_prec_round (x, 32, (mpfr_rnd_t) r); inex2 = mpfr_sum (y, t, 2, (mpfr_rnd_t) r); if (!(mpfr_equal_p (x, y) && SAME_SIGN (inex1, inex2))) { printf ("Error in check_extreme (%s, i = %d)\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); printf ("Expected "); mpfr_dump (x); printf ("with inex = %d\n", inex1); printf ("Got "); mpfr_dump (y); printf ("with inex = %d\n", inex2); exit (1); } mpfr_neg (v, v, MPFR_RNDN); mpfr_neg (w, w, MPFR_RNDN); } mpfr_clears (u, v, w, x, y, (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 void check4 (const char *as, const char *bs, mpfr_rnd_t rnd_mode, const char *res) { mpfr_t ta, tb, tres; mpfr_inits2 (53, ta, tb, tres, (mpfr_ptr) 0); mpfr_set_str1 (ta, as); mpfr_set_str1 (tb, bs); mpfr_agm(tres, ta, tb, rnd_mode); if (mpfr_cmp_str1 (tres, res)) { printf ("mpfr_agm failed for a=%s, b=%s, rnd_mode=%d\n",as,bs,rnd_mode); printf ("expected result is %s, got ",res); mpfr_out_str(stdout, 10, 0, tres, MPFR_RNDN); putchar('\n'); exit (1); } mpfr_clears (ta, tb, tres, (mpfr_ptr) 0); }
static void check_large (void) { mpfr_t x, y; mpfr_init2 (x, 25000); mpfr_init2 (y, 26000); (mpfr_const_log2) (x, MPFR_RNDN); /* First one ! */ (mpfr_const_log2) (y, MPFR_RNDN); /* Then the other - cache - */ mpfr_prec_round (y, 25000, MPFR_RNDN); if (mpfr_cmp (x, y)) { printf ("const_log2: error for large prec\n"); exit (1); } /* worst-case with 15 successive ones after last bit, to exercise can_round loop */ mpfr_set_prec (x, 26249); mpfr_const_log2 (x, MPFR_RNDZ); mpfr_clears (x, y, (mpfr_ptr) 0); }
static void check4 (const char *Ns, const char *Ds, mpfr_rnd_t rnd_mode, int p, const char *Qs) { mpfr_t q, n, d; mpfr_inits2 (p, q, n, d, (mpfr_ptr) 0); mpfr_set_str1 (n, Ns); mpfr_set_str1 (d, Ds); test_div(q, n, d, rnd_mode); if (mpfr_cmp_str (q, Qs, ((p==53) ? 10 : 2), MPFR_RNDN) ) { printf ("mpfr_div failed for n=%s, d=%s, p=%d, rnd_mode=%s\n", Ns, Ds, p, mpfr_print_rnd_mode (rnd_mode)); printf ("got ");mpfr_print_binary(q); mpfr_set_str (q, Qs, ((p==53) ? 10 : 2), MPFR_RNDN); printf("\nexpected "); mpfr_print_binary(q); putchar('\n'); exit (1); } mpfr_clears (q, n, d, (mpfr_ptr) 0); }
int mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) { mpfr_t tmpa, tmpb, tmpc; int inexb, inexc, inexact, inexact2; mpfr_init2 (tmpa, MPFR_PREC (a)); mpfr_init2 (tmpb, MPFR_PREC (b)); mpfr_init2 (tmpc, MPFR_PREC (c)); inexb = mpfr_set (tmpb, b, MPFR_RNDN); MPFR_ASSERTN (inexb == 0); inexc = mpfr_set (tmpc, c, MPFR_RNDN); MPFR_ASSERTN (inexc == 0); inexact2 = mpfr_sub1 (tmpa, tmpb, tmpc, rnd_mode); inexact = mpfr_sub1sp2(a, b, c, rnd_mode); if (mpfr_cmp (tmpa, a) || inexact != inexact2) { fprintf (stderr, "sub1 & sub1sp return different values for %s\n" "Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nB = ", mpfr_print_rnd_mode (rnd_mode), (unsigned long) MPFR_PREC (a), (unsigned long) MPFR_PREC (b), (unsigned long) MPFR_PREC (c)); mpfr_fprint_binary (stderr, tmpb); fprintf (stderr, "\nC = "); mpfr_fprint_binary (stderr, tmpc); fprintf (stderr, "\nSub1 : "); mpfr_fprint_binary (stderr, tmpa); fprintf (stderr, "\nSub1sp: "); mpfr_fprint_binary (stderr, a); fprintf (stderr, "\nInexact sp = %d | Inexact = %d\n", inexact, inexact2); MPFR_ASSERTN (0); } mpfr_clears (tmpa, tmpb, tmpc, (mpfr_ptr) 0); return inexact; }
void MathUtils::GetSmoothnessBase(mpz_class& ret_base, mpz_class& N) { mpfr_t f_N, log_N, log_log_N; mpz_t base_mpz; mpz_init(base_mpz); mpfr_init(f_N); mpfr_init(log_N); mpfr_init(log_log_N); mpfr_set_z(f_N, N.get_mpz_t(), MPFR_RNDU); //f_N = N mpfr_log(log_N, f_N, MPFR_RNDU); //log_N = log(N) mpfr_log(log_log_N, log_N, MPFR_RNDU); //log_log_N = log(log(N)) mpfr_mul(f_N, log_N, log_log_N, MPFR_RNDU); //f_N = log(N) * log(log(N)) mpfr_sqrt(f_N, f_N, MPFR_RNDU); //f_N = sqrt(f_N) mpfr_div_ui(f_N, f_N, 2, MPFR_RNDU); //f_N = f_N/2 mpfr_exp(f_N, f_N, MPFR_RNDU); //f_N = e^f_N mpfr_get_z(base_mpz, f_N, MPFR_RNDU); ret_base = mpz_class(base_mpz); mpfr_clears(f_N, log_N, log_log_N, NULL); }
static void x_near_one (void) { mpfr_t x, y, z; int inex; mpfr_init2 (x, 32); mpfr_init2 (y, 4); mpfr_init2 (z, 33); mpfr_set_ui (x, 1, GMP_RNDN); mpfr_nextbelow (x); mpfr_set_ui_2exp (y, 11, -2, GMP_RNDN); inex = mpfr_pow (z, x, y, GMP_RNDN); if (mpfr_cmp_str (z, "0.111111111111111111111111111111011E0", 2, GMP_RNDN) || inex <= 0) { printf ("Failure in x_near_one, got inex = %d and\nz = ", inex); mpfr_dump (z); } mpfr_clears (x, y, z, (void *) 0); }
/* expx is the value of exp(X) rounded toward -infinity */ static void check_worst_case (const char *Xs, const char *expxs) { mpfr_t x, y; mpfr_inits2 (53, x, y, (mpfr_ptr) 0); mpfr_set_str1(x, Xs); test_exp(y, x, MPFR_RNDD); if (mpfr_cmp_str1 (y, expxs)) { printf ("exp(x) rounded toward -infinity is wrong\n"); exit(1); } mpfr_set_str1(x, Xs); test_exp(x, x, MPFR_RNDU); mpfr_nexttoinf (y); if (mpfr_cmp(x,y)) { printf ("exp(x) rounded toward +infinity is wrong\n"); exit(1); } mpfr_clears (x, y, (mpfr_ptr) 0); }
static void huge (void) { mpfr_t x, y, z; int inex; /* TODO: extend the exponent range and use mpfr_get_emax (). */ mpfr_inits2 (32, x, y, z, (mpfr_ptr) 0); mpfr_set_ui_2exp (x, 1, 1073741822, GMP_RNDN); inex = mpfr_acosh (y, x, GMP_RNDN); mpfr_set_str_binary (z, "0.10110001011100100001011111110101E30"); if (!mpfr_equal_p (y, z)) { printf ("Error in huge:\nexpected "); mpfr_dump (z); printf ("got "); mpfr_dump (y); exit (1); } MPFR_ASSERTN (inex < 0); mpfr_clears (x, y, z, (mpfr_ptr) 0); }
static bool do_mpfr_sincos (real_value *result_sin, real_value *result_cos, const real_value *arg, const real_format *format) { /* To proceed, MPFR must exactly represent the target floating point format, which only happens when the target base equals two. */ if (format->b != 2 || !real_isfinite (arg)) return false; int prec = format->p; mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN; mpfr_t m, ms, mc; mpfr_inits2 (prec, m, ms, mc, NULL); mpfr_from_real (m, arg, GMP_RNDN); mpfr_clear_flags (); bool inexact = mpfr_sin_cos (ms, mc, m, rnd); bool ok = (do_mpfr_ckconv (result_sin, ms, inexact, format) && do_mpfr_ckconv (result_cos, mc, inexact, format)); mpfr_clears (m, ms, mc, NULL); return ok; }
/* Worst case incorrectly rounded in r5573, found with the bad_cases test */ static void bad_case1 (void) { mpfr_t x, y, z; mpfr_init2 (x, 72); mpfr_inits2 (6, y, z, (mpfr_ptr) 0); mpfr_set_str (x, "1.08310518720928b30e@-120", 16, MPFR_RNDN); mpfr_set_str (z, "f.8@59", 16, MPFR_RNDN); /* z = rec_sqrt(x) rounded on 6 bits toward 0, the exact value being ~= f.bffffffffffffffffa11@59. */ mpfr_rec_sqrt (y, x, MPFR_RNDZ); if (mpfr_cmp0 (y, z) != 0) { printf ("Error in bad_case1\nexpected "); mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); printf ("\ngot "); mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); printf ("\n"); exit (1); } mpfr_clears (x, y, z, (mpfr_ptr) 0); }
/* expx is the value of exp(X) rounded towards -infinity */ static void check_worst_case (const char *Xs, const char *expxs) { mpfr_t x, y; mpfr_inits2(53, x, y, NULL); mpfr_set_str1(x, Xs); mpfr_exp(y, x, GMP_RNDD); if (mpfr_cmp_str1 (y, expxs)) { printf ("exp(x) rounded towards -infinity is wrong\n"); exit(1); } mpfr_set_str1(x, Xs); mpfr_exp(x, x, GMP_RNDU); mpfr_add_one_ulp(y, GMP_RNDN); if (mpfr_cmp(x,y)) { printf ("exp(x) rounded towards +infinity is wrong\n"); exit(1); } mpfr_clears(x,y,NULL); }
/* checks that xs+ys gives the expected result zs */ static void check (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, unsigned int px, unsigned int py, unsigned int pz, const char *zs) { mpfr_t xx,yy,zz; mpfr_init2 (xx, px); mpfr_init2 (yy, py); mpfr_init2 (zz, pz); mpfr_set_str1 (xx, xs); mpfr_set_str1 (yy, ys); test_add (zz, xx, yy, rnd_mode); if (mpfr_cmp_str1 (zz, zs) ) { printf ("expected sum is %s, got ", zs); mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); printf ("mpfr_add failed for x=%s y=%s with rnd_mode=%s\n", xs, ys, mpfr_print_rnd_mode (rnd_mode)); exit (1); } mpfr_clears (xx, yy, zz, (mpfr_ptr) 0); }
static void check_overflow (void) { mpfr_t x, y; int inex, r; mpfr_inits2 (8, x, y, (mpfr_ptr) 0); mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_setmax (x, mpfr_get_emax ()); RND_LOOP(r) { mpfr_clear_overflow (); inex = mpfr_hypot (y, x, x, (mpfr_rnd_t) r); if (!mpfr_overflow_p ()) { printf ("No overflow in check_overflow for %s%s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), ext ? ", extended exponent range" : ""); exit (1); } MPFR_ASSERTN (MPFR_IS_POS (y)); if (r == MPFR_RNDZ || r == MPFR_RNDD) { MPFR_ASSERTN (inex < 0); MPFR_ASSERTN (!mpfr_inf_p (y)); mpfr_nexttoinf (y); } else { MPFR_ASSERTN (inex > 0); } MPFR_ASSERTN (mpfr_inf_p (y)); } mpfr_clears (x, y, (mpfr_ptr) 0); }
static void dispose() { mpfr_clears(zero, one, eps, minuseps, large, (mpfr_ptr)0); int i, j; for(i=0;i < m+1;i++) { for(j=0;j < m+1;j++) { mpfr_clear(q[i][j]); } free(q[i]); } free(q); for(i=0;i < m+1;i++) { for(j=0;j < n+1;j++) { mpfr_clear(a[i][j]); } free(a[i]); } free(a); for(j=0;j < n+1;j++) { mpfr_clear(c[j]); } free(c); for(j=0;j < m+1;j++) { mpfr_clear(pivotcolumn[j]); } free(pivotcolumn); free(col); free(row); free(nonzero_row); free(inequality); }
static void check_random (mpfr_prec_t p) { mpfr_t x,y,z; int r; int i, inexact1, inexact2; mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0); for(i = 0 ; i < 500 ; i++) { mpfr_urandomb (x, RANDS); if (MPFR_IS_PURE_FP(x)) for (r = 0 ; r < MPFR_RND_MAX ; r++) { inexact1 = mpfr_mul (y, x, x, (mpfr_rnd_t) r); inexact2 = mpfr_sqr (z, x, (mpfr_rnd_t) r); if (mpfr_cmp (y, z)) error1 ((mpfr_rnd_t) r,p,x,y,z); if (inexact_sign (inexact1) != inexact_sign (inexact2)) error2 ((mpfr_rnd_t) r,p,x,y,inexact1,inexact2); } } mpfr_clears (x, y, z, (mpfr_ptr) 0); }
static void check_64(void) { mpfr_t x,y,z; mpfr_inits2 (64, x, y, z, (mpfr_ptr) 0); mpfr_set_str_binary(x, "1.00100100110110101001010010101111000001011100100101010000000000E54"); mpfr_set_str_binary(y, "1.00000000000000000000000000000000000000000000000000000000000000E584"); test_div(z, x, y, MPFR_RNDU); if (mpfr_cmp_str (z, "0.1001001001101101010010100101011110000010111001001010100000000000E-529", 2, MPFR_RNDN)) { printf("Error for tdiv for MPFR_RNDU and p=64\nx="); mpfr_print_binary(x); printf("\ny="); mpfr_print_binary(y); printf("\ngot "); mpfr_print_binary(z); printf("\nexpected 0.1001001001101101010010100101011110000010111001001010100000000000E-529\n"); exit(1); } mpfr_clears (x, y, z, (mpfr_ptr) 0); }
int mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) { mpfr_t ta, tb, tc; int inexact1, inexact2; mpfr_init2 (ta, MPFR_PREC (a)); mpfr_init2 (tb, MPFR_PREC (b)); mpfr_init2 (tc, MPFR_PREC (c)); MPFR_ASSERTN (mpfr_set (tb, b, MPFR_RNDN) == 0); MPFR_ASSERTN (mpfr_set (tc, c, MPFR_RNDN) == 0); inexact2 = mpfr_mul3 (ta, tb, tc, rnd_mode); inexact1 = mpfr_mul2 (a, b, c, rnd_mode); if (mpfr_cmp (ta, a) || inexact1*inexact2 < 0 || (inexact1*inexact2 == 0 && (inexact1|inexact2) != 0)) { fprintf (stderr, "mpfr_mul return different values for %s\n" "Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nB = ", mpfr_print_rnd_mode (rnd_mode), MPFR_PREC (a), MPFR_PREC (b), MPFR_PREC (c)); mpfr_out_str (stderr, 16, 0, tb, MPFR_RNDN); fprintf (stderr, "\nC = "); mpfr_out_str (stderr, 16, 0, tc, MPFR_RNDN); fprintf (stderr, "\nOldMul: "); mpfr_out_str (stderr, 16, 0, ta, MPFR_RNDN); fprintf (stderr, "\nNewMul: "); mpfr_out_str (stderr, 16, 0, a, MPFR_RNDN); fprintf (stderr, "\nNewInexact = %d | OldInexact = %d\n", inexact1, inexact2); MPFR_ASSERTN(0); } mpfr_clears (ta, tb, tc, (mpfr_ptr) 0); return inexact1; }
/* FastTwoSum: if EXP(x) >= EXP(y), u = o(x+y), v = o(u-x), w = o(y-v), then x + y = u + w thus if u = o(y-x), v = o(u+x), w = o(v-y), then y-x = u-w */ static void check_two_sum (mpfr_prec_t p) { unsigned int x; mpfr_t y, u, v, w; mpfr_rnd_t rnd; int inexact; mpfr_inits2 (p, y, u, v, w, (mpfr_ptr) 0); do { x = randlimb (); } while (x < 1); mpfr_urandomb (y, RANDS); rnd = MPFR_RNDN; inexact = mpfr_sub_ui (u, y, x, rnd); mpfr_add_ui (v, u, x, rnd); mpfr_sub (w, v, y, rnd); /* as u - (y-x) = w, we should have inexact and w of same sign */ if (((inexact == 0) && mpfr_cmp_ui (w, 0)) || ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) || ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0))) { printf ("Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned int) p, mpfr_print_rnd_mode (rnd)); printf ("x=%u\n", x); printf ("y="); mpfr_print_binary(y); puts (""); printf ("u="); mpfr_print_binary(u); puts (""); printf ("v="); mpfr_print_binary(v); puts (""); printf ("w="); mpfr_print_binary(w); puts (""); printf ("inexact = %d\n", inexact); exit (1); } mpfr_clears (y, u, v, w, (mpfr_ptr) 0); }
/* glibc free() error or segmentation fault when configured * with GMP 6.0.0 built with "--disable-alloca ABI=32". * GCC's address sanitizer shows a heap-buffer-overflow. * Fixed in r9369 (before the merge into the trunk). The problem was due * to the fact that mpn functions do not accept a zero size argument, and * since mpn_add_1 is here a macro in GMP, there's no assertion even when * GMP was built with assertion checking (--enable-assert). */ static void check_simple (void) { mpfr_t tab[3], r; mpfr_ptr tabp[3]; int i; mpfr_init2 (r, 16); for (i = 0; i < 3; i++) { mpfr_init2 (tab[i], 16); mpfr_set_ui (tab[i], 1, MPFR_RNDN); tabp[i] = tab[i]; } i = mpfr_sum (r, tabp, 3, MPFR_RNDN); if (mpfr_cmp_ui (r, 3) || i != 0) { printf ("Error in check_simple\n"); exit (1); } mpfr_clears (tab[0], tab[1], tab[2], r, (mpfr_ptr) 0); }
int mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) { mpfr_exp_t expx; mpfr_prec_t precy; int inexact; MPFR_SAVE_EXPO_DECL (expo); MPFR_LOG_FUNC (("x[%#R]=%R rnd=%d", x, x, rnd_mode), ("y[%#R]=%R inexact=%d", y, y, inexact)); 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)) { if (MPFR_IS_POS(x)) MPFR_SET_INF(y); else MPFR_SET_ZERO(y); MPFR_SET_POS(y); MPFR_RET(0); } else { MPFR_ASSERTD(MPFR_IS_ZERO(x)); return mpfr_set_ui (y, 1, rnd_mode); } } /* First, let's detect most overflow and underflow cases. */ { mpfr_t e, bound; /* We must extended the exponent range and save the flags now. */ MPFR_SAVE_EXPO_MARK (expo); mpfr_init2 (e, sizeof (mpfr_exp_t) * CHAR_BIT); mpfr_init2 (bound, 32); inexact = mpfr_set_exp_t (e, expo.saved_emax, MPFR_RNDN); MPFR_ASSERTD (inexact == 0); mpfr_const_log2 (bound, expo.saved_emax < 0 ? MPFR_RNDD : MPFR_RNDU); mpfr_mul (bound, bound, e, MPFR_RNDU); if (MPFR_UNLIKELY (mpfr_cmp (x, bound) >= 0)) { /* x > log(2^emax), thus exp(x) > 2^emax */ mpfr_clears (e, bound, (mpfr_ptr) 0); MPFR_SAVE_EXPO_FREE (expo); return mpfr_overflow (y, rnd_mode, 1); } inexact = mpfr_set_exp_t (e, expo.saved_emin, MPFR_RNDN); MPFR_ASSERTD (inexact == 0); inexact = mpfr_sub_ui (e, e, 2, MPFR_RNDN); MPFR_ASSERTD (inexact == 0); mpfr_const_log2 (bound, expo.saved_emin < 0 ? MPFR_RNDU : MPFR_RNDD); mpfr_mul (bound, bound, e, MPFR_RNDD); if (MPFR_UNLIKELY (mpfr_cmp (x, bound) <= 0)) { /* x < log(2^(emin - 2)), thus exp(x) < 2^(emin - 2) */ mpfr_clears (e, bound, (mpfr_ptr) 0); MPFR_SAVE_EXPO_FREE (expo); return mpfr_underflow (y, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode, 1); } /* Other overflow/underflow cases must be detected by the generic routines. */ mpfr_clears (e, bound, (mpfr_ptr) 0); MPFR_SAVE_EXPO_FREE (expo); } expx = MPFR_GET_EXP (x); precy = MPFR_PREC (y); /* if x < 2^(-precy), then exp(x) i.e. gives 1 +/- 1 ulp(1) */ if (MPFR_UNLIKELY (expx < 0 && (mpfr_uexp_t) (-expx) > precy)) { mpfr_exp_t emin = __gmpfr_emin; mpfr_exp_t emax = __gmpfr_emax; int signx = MPFR_SIGN (x); MPFR_SET_POS (y); if (MPFR_IS_NEG_SIGN (signx) && (rnd_mode == MPFR_RNDD || rnd_mode == MPFR_RNDZ)) { __gmpfr_emin = 0; __gmpfr_emax = 0; mpfr_setmax (y, 0); /* y = 1 - epsilon */ inexact = -1; } else { __gmpfr_emin = 1; __gmpfr_emax = 1; mpfr_setmin (y, 1); /* y = 1 */ if (MPFR_IS_POS_SIGN (signx) && (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA)) { mp_size_t yn; int sh; yn = 1 + (MPFR_PREC(y) - 1) / GMP_NUMB_BITS; sh = (mpfr_prec_t) yn * GMP_NUMB_BITS - MPFR_PREC(y); MPFR_MANT(y)[0] += MPFR_LIMB_ONE << sh; inexact = 1; } else inexact = -MPFR_FROM_SIGN_TO_INT(signx); } __gmpfr_emin = emin; __gmpfr_emax = emax; } else /* General case */ { if (MPFR_UNLIKELY (precy >= MPFR_EXP_THRESHOLD)) /* mpfr_exp_3 saves the exponent range and flags itself, otherwise the flag changes in mpfr_exp_3 are lost */ inexact = mpfr_exp_3 (y, x, rnd_mode); /* O(M(n) log(n)^2) */ else { MPFR_SAVE_EXPO_MARK (expo); inexact = mpfr_exp_2 (y, x, rnd_mode); /* O(n^(1/3) M(n)) */ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); MPFR_SAVE_EXPO_FREE (expo); } } return mpfr_check_range (y, inexact, rnd_mode); }
static int binary (void) { mpfr_t x; mpfr_t z; mpfr_inits2 (64, x, z, (mpfr_ptr) 0); /* special */ mpfr_set_inf (x, 1); check_sprintf (pinf_str, "%Rb", x); mpfr_set_inf (x, -1); check_sprintf (minf_str, "%Rb", x); mpfr_set_nan (x); check_sprintf (nan_str, "%Rb", x); /* regular numbers */ mpfr_set_str (x, "1110010101.1001101", 2, MPFR_RNDN); mpfr_set_ui (z, 0, MPFR_RNDN); /* simplest case: right justified */ check_sprintf (" 1.1100101011001101p+9", "%25Rb", x); check_sprintf (" 0p+0", "%25Rb", z); /* sign or space, pad with leading zeros */ check_sprintf (" 0001.1100101011001101p+9", "% 025Rb", x); check_sprintf (" 000000000000000000000p+0", "% 025Rb", z); /* sign + or -, left justified */ check_sprintf ("+1.1100101011001101p+9 ", "%+-25Rb", x); check_sprintf ("+0p+0 ", "%+-25Rb", z); /* sign or space */ check_sprintf (" 1.110p+9", "% .3RNb", x); check_sprintf (" 1.1101p+9", "% .4RNb", x); check_sprintf (" 0.0000p+0", "% .4RNb", z); /* sign + or -, decimal point, pad with leading zeros */ check_sprintf ("+00001.1p+9", "%0+#11.1RZb", x); check_sprintf ("+0001.0p+10", "%0+#11.1RNb", x); check_sprintf ("+000000.p+0", "%0+#11.0RNb", z); /* pad with leading zero */ check_sprintf ("00001.1100101011001101p+9", "%025RDb", x); /* sign or space, decimal point (unused), left justified */ check_sprintf (" 1.1p+9 ", "%- #11.1RDb", x); check_sprintf (" 1.p+9 ", "%- #11.0RDb", x); check_sprintf (" 1.p+10 ", "%- #11.0RUb", x); check_sprintf (" 1.p+9 ", "%- #11.0RZb", x); check_sprintf (" 1.p+10 ", "%- #11.0RYb", x); check_sprintf (" 1.p+10 ", "%- #11.0RNb", x); mpfr_mul_si (x, x, -1, MPFR_RNDD); mpfr_mul_si (z, z, -1, MPFR_RNDD); /* sign + or - */ check_sprintf (" -1.1p+9", "%+10.1RUb", x); check_sprintf (" -0.0p+0", "%+10.1RUb", z); /* precision 0 */ check_sprintf ("-1p+10", "%.0RNb", x); check_sprintf ("-1p+10", "%.0RDb", x); check_sprintf ("-1p+9", "%.0RUb", x); check_sprintf ("-1p+9", "%.0RZb", x); check_sprintf ("-1p+10", "%.0RYb", x); /* round to next base power */ check_sprintf ("-1.0p+10", "%.1RNb", x); check_sprintf ("-1.0p+10", "%.1RDb", x); check_sprintf ("-1.0p+10", "%.1RYb", x); /* do not round to next base power */ check_sprintf ("-1.1p+9", "%.1RUb", x); check_sprintf ("-1.1p+9", "%.1RZb", x); /* rounding bit is zero */ check_sprintf ("-1.11p+9", "%.2RNb", x); /* tie case in round to nearest mode */ check_sprintf ("-1.1100101011001101p+9", "%.16RNb", x); /* trailing zeros in fractional part */ check_sprintf ("-1.110010101100110100000000000000p+9", "%.30RNb", x); mpfr_clears (x, z, (mpfr_ptr) 0); 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 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); }
static void check_cmp (int argc, char *argv[]) { mpfr_t x, y; int n, k; mpfr_inits2 (53, x, y, (mpfr_ptr) 0); mpfr_set_ui(x, 1, MPFR_RNDN); (mpfr_abs) (x, x, MPFR_RNDN); if (mpfr_cmp_ui (x, 1)) { printf ("Error in mpfr_abs(1.0)\n"); exit (1); } mpfr_set_si(x, -1, MPFR_RNDN); mpfr_abs(x, x, MPFR_RNDN); if (mpfr_cmp_ui (x, 1)) { printf ("Error in mpfr_abs(1.0)\n"); exit (1); } mpfr_set_si(x, -1, MPFR_RNDN); mpfr_abs(x, x, MPFR_RNDN); if (mpfr_cmp_ui (x, 1)) { printf ("Error in mpfr_abs(-1.0)\n"); exit (1); } mpfr_set_inf (x, 1); mpfr_abs (x, x, MPFR_RNDN); if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0)) { printf ("Error in mpfr_abs(Inf).\n"); exit (1); } mpfr_set_inf (x, -1); mpfr_abs (x, x, MPFR_RNDN); if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0)) { printf ("Error in mpfr_abs(-Inf).\n"); exit (1); } MPFR_SET_NAN(x); mpfr_abs (x, x, MPFR_RNDN); if (!MPFR_IS_NAN(x)) { printf ("Error in mpfr_abs(NAN).\n"); exit (1); } n = (argc==1) ? 25000 : atoi(argv[1]); for (k = 1; k <= n; k++) { mpfr_rnd_t rnd; int sign = SIGN_RAND (); mpfr_urandomb (x, RANDS); MPFR_SET_SIGN (x, sign); rnd = RND_RAND (); mpfr_abs (y, x, rnd); MPFR_SET_POS (x); if (mpfr_cmp (x, y)) { printf ("Mismatch for sign=%d and x=", sign); mpfr_print_binary (x); printf ("\nResults="); mpfr_print_binary (y); putchar ('\n'); exit (1); } } mpfr_clears (x, y, (mpfr_ptr) 0); }
int main (void) { int j, k; mpfr_t x, y, z, t, y2, z2, t2; tests_start_mpfr (); mpfr_inits2 (SIZEX, x, y, z, t, y2, z2, t2, (mpfr_ptr) 0); mpfr_set_str1 (x, "0.5"); mpfr_ceil(y, x); if (mpfr_cmp_ui (y, 1)) { printf ("Error in mpfr_ceil for x=0.5: expected 1.0, got "); mpfr_print_binary(y); putchar('\n'); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_ceil(y, x); if (mpfr_cmp_ui(y,0)) { printf ("Error in mpfr_ceil for x=0.0: expected 0.0, got "); mpfr_print_binary(y); putchar('\n'); exit (1); } mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_ceil(y, x); if (mpfr_cmp_ui(y,1)) { printf ("Error in mpfr_ceil for x=1.0: expected 1.0, got "); mpfr_print_binary(y); putchar('\n'); exit (1); } for (j=0;j<1000;j++) { mpfr_urandomb (x, RANDS); MPFR_EXP (x) = 2; for (k = 2; k <= SIZEX; k++) { mpfr_set_prec(y, k); mpfr_set_prec(y2, k); mpfr_set_prec(z, k); mpfr_set_prec(z2, k); mpfr_set_prec(t, k); mpfr_set_prec(t2, k); mpfr_floor(y, x); mpfr_set(y2, x, MPFR_RNDD); mpfr_trunc(z, x); mpfr_set(z2, x, MPFR_RNDZ); mpfr_ceil(t, x); mpfr_set(t2, x, MPFR_RNDU); if (!mpfr_eq(y, y2, k)) { printf("Error in floor, x = "); mpfr_print_binary(x); printf("\n"); printf("floor(x) = "); mpfr_print_binary(y); printf("\n"); printf("round(x, RNDD) = "); mpfr_print_binary(y2); printf("\n"); exit(1); } if (!mpfr_eq(z, z2, k)) { printf("Error in trunc, x = "); mpfr_print_binary(x); printf("\n"); printf("trunc(x) = "); mpfr_print_binary(z); printf("\n"); printf("round(x, RNDZ) = "); mpfr_print_binary(z2); printf("\n"); exit(1); } if (!mpfr_eq(y, y2, k)) { printf("Error in ceil, x = "); mpfr_print_binary(x); printf("\n"); printf("ceil(x) = "); mpfr_print_binary(t); printf("\n"); printf("round(x, RNDU) = "); mpfr_print_binary(t2); printf("\n"); exit(1); } MPFR_EXP(x)++; } } mpfr_clears (x, y, z, t, y2, z2, t2, (mpfr_ptr) 0); 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); }