static void check_random (mpfr_prec_t p) { mpfr_t a1,b,c,a2; int r; int i, inexact1, inexact2; mpfr_inits2 (p, a1, b, c, a2, (mpfr_ptr) 0); for (i = 0 ; i < 500 ; i++) { mpfr_urandomb (b, RANDS); mpfr_urandomb (c, RANDS); if (MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c)) { if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c)) mpfr_swap(b, c); if (MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c)) for (r = 0 ; r < MPFR_RND_MAX ; r++) { inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r); inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r); if (mpfr_cmp(a1, a2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; } } } mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0); }
/* test a random division of p+extra bits divided by p+extra bits, with quotient of p bits only, where the p+extra bit approximation of the quotient is very near a rounding frontier. */ static void test_bad_aux (mpfr_prec_t p, mpfr_prec_t extra) { mpfr_t u, v, w, q0, q; mpfr_init2 (u, p + extra); mpfr_init2 (v, p + extra); mpfr_init2 (w, p + extra); mpfr_init2 (q0, p); mpfr_init2 (q, p); do mpfr_urandomb (q0, RANDS); while (mpfr_zero_p (q0)); do mpfr_urandomb (v, RANDS); while (mpfr_zero_p (v)); mpfr_set (w, q0, MPFR_RNDN); /* exact */ mpfr_nextabove (w); /* now w > q0 */ mpfr_mul (u, v, w, MPFR_RNDU); /* thus u > v*q0 */ mpfr_div (q, u, v, MPFR_RNDU); /* should have q > q0 */ MPFR_ASSERTN (mpfr_cmp (q, q0) > 0); mpfr_div (q, u, v, MPFR_RNDZ); /* should have q = q0 */ MPFR_ASSERTN (mpfr_cmp (q, q0) == 0); mpfr_set (w, q0, MPFR_RNDN); /* exact */ mpfr_nextbelow (w); /* now w < q0 */ mpfr_mul (u, v, w, MPFR_RNDZ); /* thus u < v*q0 */ mpfr_div (q, u, v, MPFR_RNDZ); /* should have q < q0 */ MPFR_ASSERTN (mpfr_cmp (q, q0) < 0); mpfr_div (q, u, v, MPFR_RNDU); /* should have q = q0 */ MPFR_ASSERTN (mpfr_cmp (q, q0) == 0); mpfr_clear (u); mpfr_clear (v); mpfr_clear (w); mpfr_clear (q0); mpfr_clear (q); }
static void check_random (mpfr_prec_t p) { mpfr_t x,y,z,x2; int r; int i, inexact1, inexact2; mpfr_inits2 (p, x, y, z, x2, (mpfr_ptr) 0); for (i = 0 ; i < 500 ; i++) { mpfr_urandomb (y, RANDS); mpfr_urandomb (z, RANDS); if (MPFR_IS_PURE_FP(y) && MPFR_IS_PURE_FP(z)) for(r = 0 ; r < GMP_RND_MAX ; r++) { inexact1 = mpfr_sub1(x2, y, z, (mp_rnd_t) r); inexact2 = mpfr_sub1sp(x, y, z, (mp_rnd_t) r); if (mpfr_cmp(x, x2)) STD_ERROR; if (inexact1 != inexact2) STD_ERROR2; } } mpfr_clears (x, y, z, x2, (mpfr_ptr) 0); }
static void cmp_tests (void) { mpfr_t x, y; long i; mpfr_inits (x, y, (mpfr_ptr) 0); for (i = 0; i < 80000; i++) { mpfr_prec_t precx, precy; int signx, signy, cmp; unsigned int cmpbool = 0; precx = (randlimb () % 17) * 11 + MPFR_PREC_MIN; precy = (randlimb () % 17) * 11 + MPFR_PREC_MIN; mpfr_set_prec (x, precx); mpfr_set_prec (y, precy); mpfr_urandomb (x, RANDS); mpfr_urandomb (y, RANDS); signx = randlimb () & 1; signy = randlimb () % 256 ? signx : 1 - signx; /* signy = signx most of the time (most interesting case) */ if (signx) mpfr_neg (x, x, MPFR_RNDN); if (signy) mpfr_neg (y, y, MPFR_RNDN); if (i <= 1) mpfr_set_nan (x); if (i == 0 || i == 2) mpfr_set_nan (y); if (mpfr_greater_p (x, y)) cmpbool |= 0x01; if (mpfr_greaterequal_p (x, y)) cmpbool |= 0x02; if (mpfr_less_p (x, y)) cmpbool |= 0x04; if (mpfr_lessequal_p (x, y)) cmpbool |= 0x08; if (mpfr_lessgreater_p (x, y)) cmpbool |= 0x10; if (mpfr_equal_p (x, y)) cmpbool |= 0x20; if (mpfr_unordered_p (x, y)) cmpbool |= 0x40; if ((i <= 2 && cmpbool != 0x40) || (i > 2 && (cmp = mpfr_cmp (x, y), (cmp == 0 && cmpbool != 0x2a) || (cmp < 0 && cmpbool != 0x1c) || (cmp > 0 && cmpbool != 0x13)))) { printf ("Error in cmp_tests for\nx = "); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf (" and\ny = "); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); printf ("\n"); exit (1); } } mpfr_clears (x, y, (mpfr_ptr) 0); }
static void test_sum (mpfr_prec_t f, unsigned long n) { mpfr_t sum, real_sum, real_non_rounded; mpfr_t *tab; unsigned long i; int rnd_mode; /* Init */ tab = (mpfr_t *) (*__gmp_allocate_func) (n * sizeof(mpfr_t)); for (i = 0; i < n; i++) mpfr_init2 (tab[i], f); mpfr_inits2 (f, sum, real_sum, real_non_rounded, (mpfr_ptr) 0); /* First Uniform */ for (i = 0; i < n; i++) mpfr_urandomb (tab[i], RANDS); algo_exact (real_non_rounded, tab, n, f); for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++) { sum_tab (sum, tab, n, (mpfr_rnd_t) rnd_mode); mpfr_set (real_sum, real_non_rounded, (mpfr_rnd_t) rnd_mode); if (mpfr_cmp (real_sum, sum) != 0) { printf ("mpfr_sum incorrect.\n"); mpfr_dump (real_sum); mpfr_dump (sum); exit (1); } } /* Then non uniform */ for (i = 0; i < n; i++) { mpfr_urandomb (tab[i], RANDS); if (! mpfr_zero_p (tab[i])) mpfr_set_exp (tab[i], randlimb () % 1000); } algo_exact (real_non_rounded, tab, n, f); for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++) { sum_tab (sum, tab, n, (mpfr_rnd_t) rnd_mode); mpfr_set (real_sum, real_non_rounded, (mpfr_rnd_t) rnd_mode); if (mpfr_cmp (real_sum, sum) != 0) { printf ("mpfr_sum incorrect.\n"); mpfr_dump (real_sum); mpfr_dump (sum); exit (1); } } /* Clear stuff */ for (i = 0; i < n; i++) mpfr_clear (tab[i]); mpfr_clears (sum, real_sum, real_non_rounded, (mpfr_ptr) 0); (*__gmp_free_func) (tab, n * sizeof(mpfr_t)); }
/* Bug in mpfr_divhigh_n_basecase when all limbs of q (except the most significant one) are B-1 where B=2^GMP_NUMB_BITS. Since we truncate the divisor at each step, it might happen at some point that (np[n-1],np[n-2]) > (d1,d0), and not only the equality. Reported by Ricky Farr <https://sympa.inria.fr/sympa/arc/mpfr/2015-10/msg00023.html> To get a failure, a MPFR_DIVHIGH_TAB entry below the MPFR_DIV_THRESHOLD limit must have a value 0. With most mparam.h files, this cannot occur. To make the bug appear, one can configure MPFR with -DMPFR_TUNE_COVERAGE. */ static void test_20151023 (void) { mpfr_prec_t p; mpfr_t n, d, q, q0; int inex, i; for (p = GMP_NUMB_BITS; p <= 2000; p++) { mpfr_init2 (n, 2*p); mpfr_init2 (d, p); mpfr_init2 (q, p); mpfr_init2 (q0, GMP_NUMB_BITS); /* generate a random divisor of p bits */ mpfr_urandomb (d, RANDS); /* generate a random quotient of GMP_NUMB_BITS bits */ mpfr_urandomb (q0, RANDS); /* zero-pad the quotient to p bits */ inex = mpfr_prec_round (q0, p, MPFR_RNDN); MPFR_ASSERTN(inex == 0); for (i = 0; i < 3; i++) { /* i=0: try with the original quotient xxx000...000 i=1: try with the original quotient minus one ulp i=2: try with the original quotient plus one ulp */ if (i == 1) mpfr_nextbelow (q0); else if (i == 2) { mpfr_nextabove (q0); mpfr_nextabove (q0); } inex = mpfr_mul (n, d, q0, MPFR_RNDN); MPFR_ASSERTN(inex == 0); mpfr_nextabove (n); mpfr_div (q, n, d, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp (q, q0) == 0); inex = mpfr_mul (n, d, q0, MPFR_RNDN); MPFR_ASSERTN(inex == 0); mpfr_nextbelow (n); mpfr_div (q, n, d, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp (q, q0) == 0); } mpfr_clear (n); mpfr_clear (d); mpfr_clear (q); mpfr_clear (q0); } }
/* if u = o(x-y), v = o(u-x), w = o(v+y), then x-y = u-w */ static void check_two_sum (mpfr_prec_t p) { mpfr_t x, y, u, v, w; mpfr_rnd_t rnd; int inexact; mpfr_init2 (x, p); mpfr_init2 (y, p); mpfr_init2 (u, p); mpfr_init2 (v, p); mpfr_init2 (w, p); mpfr_urandomb (x, RANDS); mpfr_urandomb (y, RANDS); if (mpfr_cmpabs (x, y) < 0) mpfr_swap (x, y); rnd = MPFR_RNDN; inexact = test_sub (u, x, y, rnd); test_sub (v, u, x, rnd); mpfr_add (w, v, y, rnd); /* as u = (x-y) - w, we should have inexact and w of opposite signs */ 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)p, mpfr_print_rnd_mode (rnd)); printf ("x="); mpfr_print_binary(x); puts (""); 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_clear (x); mpfr_clear (y); mpfr_clear (u); mpfr_clear (v); mpfr_clear (w); }
/* pos is 512 times the proportion of negative numbers. If pos=256, half of the numbers are negative. If pos=0, all generated numbers are positive. */ void tests_default_random (mpfr_ptr x, int pos, mpfr_exp_t emin, mpfr_exp_t emax, int always_scale) { MPFR_ASSERTN (emin <= emax); MPFR_ASSERTN (emin >= MPFR_EMIN_MIN); MPFR_ASSERTN (emax <= MPFR_EMAX_MAX); /* but it isn't required that emin and emax are in the current exponent range (see below), so that underflow/overflow checks can be done on 64-bit machines without a manual change of the exponent range (well, this is a bit ugly...). */ mpfr_urandomb (x, RANDS); if (MPFR_IS_PURE_FP (x) && (emin >= 1 || always_scale || (randlimb () & 1))) { mpfr_exp_t e; e = emin + (mpfr_exp_t) (randlimb () % (emax - emin + 1)); /* Note: There should be no overflow here because both terms are between MPFR_EMIN_MIN and MPFR_EMAX_MAX. */ MPFR_ASSERTD (e >= emin && e <= emax); if (mpfr_set_exp (x, e)) { /* The random number doesn't fit in the current exponent range. In this case, test the function in the extended exponent range, which should be restored by the caller. */ mpfr_set_emin (MPFR_EMIN_MIN); mpfr_set_emax (MPFR_EMAX_MAX); mpfr_set_exp (x, e); } } if (randlimb () % 512 < pos) mpfr_neg (x, x, MPFR_RNDN); }
static void eq_tests (void) { mpfr_t x, y; long i; mpfr_inits (x, y, (mpfr_ptr) 0); for (i = 0; i < 20000; i++) { mpfr_prec_t precx; precx = (randlimb () % 17) * 11 + MPFR_PREC_MIN; mpfr_set_prec (x, precx); mpfr_set_prec (y, precx + (randlimb () % 64)); mpfr_urandomb (x, RANDS); if (randlimb () & 1) mpfr_neg (x, x, MPFR_RNDN); mpfr_set (y, x, MPFR_RNDN); /* exact -> x = y */ if (mpfr_greater_p (x, y) || !mpfr_greaterequal_p (x, y) || mpfr_less_p (x, y) || !mpfr_lessequal_p (x, y) || mpfr_lessgreater_p (x, y) || !mpfr_equal_p (x, y) || mpfr_unordered_p (x, y)) { printf ("Error in eq_tests for x = "); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\n"); exit (1); } } mpfr_clears (x, y, (mpfr_ptr) 0); }
int main (void) { int i, base; mpfr_t x; mpfr_prec_t p; mpfr_exp_t e; mpfr_init (x); printf ("struct dymmy_test { \n" " mpfr_prec_t prec; \n" " int base; \n" " const char *str; \n" " const char *binstr; \n" " } RefTable[] = { \n"); for (i = 0 ; i < MAX_NUM ; i++) { p = randomab(2, 180); base = randomab (2, 30); e = randomab (-1<<15, 1<<15); mpfr_set_prec (x, p); mpfr_urandomb (x, RANDS); mpfr_mul_2si (x, x, e, MPFR_RNDN); printf("{%lu, %d,\n\"", p, base); mpfr_out_str (stdout, base, p, x, MPFR_RNDN); printf ("\",\n\""); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\"}%c\n", i == MAX_NUM-1 ? ' ' : ',' ); } printf("};\n"); mpfr_clear (x); }
/* * call-seq: * rand_state.mpfr_urandomb() * * From the MPFR Manual: * * Generate a uniformly distributed random float in the interval 0 <= rop < 1. */ VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self) { MP_RANDSTATE *self_val; MP_FLOAT *res_val; VALUE res; unsigned long prec = 0; if (argc > 1) rb_raise (rb_eArgError, "wrong # of arguments(%d for 0 or 1)", argc); mprandstate_get_struct (self,self_val); if (argc == 1) { if (FIXNUM_P (argv[0])) { if (FIX2INT (argv[0]) >= 0) prec = FIX2INT (argv[0]); else rb_raise (rb_eRangeError, "prec must be non-negative"); } else { rb_raise (rb_eTypeError, "prec must be a Fixnum"); } } mpf_make_struct (res, res_val); if (prec == 0) { mpf_init (res_val); } else { mpf_init2 (res_val, prec); } mpfr_urandomb (res_val, self_val); return res; }
/* pos is 512 times the proportion of negative numbers. If pos=256, half of the numbers are negative. If pos=0, all generated numbers are positive. */ void tests_default_random (mpfr_ptr x, int pos, mpfr_exp_t emin, mpfr_exp_t emax) { MPFR_ASSERTN (emin <= emax); MPFR_ASSERTN (emin >= MPFR_EMIN_MIN); MPFR_ASSERTN (emax <= MPFR_EMAX_MAX); /* but it isn't required that emin and emax are in the current exponent range (see below), so that underflow/overflow checks can be done on 64-bit machines. */ mpfr_urandomb (x, RANDS); if (MPFR_IS_PURE_FP (x) && (emin >= 1 || (randlimb () & 1))) { mpfr_exp_t e; e = MPFR_GET_EXP (x) + (emin + (long) (randlimb () % (emax - emin + 1))); /* Note: There should be no overflow here because both terms are between MPFR_EMIN_MIN and MPFR_EMAX_MAX, but the sum e isn't necessarily between MPFR_EMIN_MIN and MPFR_EMAX_MAX. */ if (mpfr_set_exp (x, e)) { /* The random number doesn't fit in the current exponent range. In this case, test the function in the extended exponent range, which should be restored by the caller. */ mpfr_set_emin (MPFR_EMIN_MIN); mpfr_set_emax (MPFR_EMAX_MAX); mpfr_set_exp (x, e); } } if (randlimb () % 512 < pos) mpfr_neg (x, x, MPFR_RNDN); }
/* check that mpfr_sin_cos and test_mpfr_sincos_fast agree */ static void test_mpfr_sincos_fast (void) { mpfr_t x, y, z, yref, zref, h; mpfr_prec_t p = 1000; int i, inex, inexref; mpfr_rnd_t r; mpfr_init2 (x, p); mpfr_init2 (y, p); mpfr_init2 (z, p); mpfr_init2 (yref, p); mpfr_init2 (zref, p); mpfr_init2 (h, p); mpfr_set_ui (x, 0, MPFR_RNDN); /* we generate a random value x, compute sin(x) and cos(x) with both mpfr_sin_cos and mpfr_sincos_fast, and check the values and the flags agree */ for (i = 0; i < 100; i++) { mpfr_urandomb (h, RANDS); mpfr_add (x, x, h, MPFR_RNDN); r = RND_RAND (); inexref = mpfr_sin_cos (yref, zref, x, r); inex = mpfr_sincos_fast (y, z, x, r); if (mpfr_cmp (y, yref)) { printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n"); printf ("x="); mpfr_dump (x); printf ("rnd=%s\n", mpfr_print_rnd_mode (r)); printf ("yref="); mpfr_dump (yref); printf ("y="); mpfr_dump (y); exit (1); } if (mpfr_cmp (z, zref)) { printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n"); printf ("x="); mpfr_dump (x); printf ("rnd=%s\n", mpfr_print_rnd_mode (r)); printf ("zref="); mpfr_dump (zref); printf ("z="); mpfr_dump (z); exit (1); } if (inex != inexref) { printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n"); printf ("x="); mpfr_dump (x); printf ("rnd=%s\n", mpfr_print_rnd_mode (r)); printf ("inexref=%d inex=%d\n", inexref, inex); exit (1); } } mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); mpfr_clear (yref); mpfr_clear (zref); mpfr_clear (h); }
static void consistency (void) { mpfr_t x, y, z1, z2; int i; mpfr_inits (x, y, z1, z2, (mpfr_ptr) 0); for (i = 0; i < 10000; i++) { mpfr_rnd_t rnd; mpfr_prec_t px, py, pz, p; int inex1, inex2; rnd = RND_RAND (); px = (randlimb () % 256) + 2; py = (randlimb () % 128) + 2; pz = (randlimb () % 256) + 2; mpfr_set_prec (x, px); mpfr_set_prec (y, py); mpfr_set_prec (z1, pz); mpfr_set_prec (z2, pz); mpfr_urandomb (x, RANDS); do mpfr_urandomb (y, RANDS); while (mpfr_zero_p (y)); inex1 = mpfr_div (z1, x, y, rnd); MPFR_ASSERTN (!MPFR_IS_NAN (z1)); p = MAX (MAX (px, py), pz); if (mpfr_prec_round (x, p, MPFR_RNDN) != 0 || mpfr_prec_round (y, p, MPFR_RNDN) != 0) { printf ("mpfr_prec_round error for i = %d\n", i); exit (1); } inex2 = mpfr_div (z2, x, y, rnd); MPFR_ASSERTN (!MPFR_IS_NAN (z2)); if (inex1 != inex2 || mpfr_cmp (z1, z2) != 0) { printf ("Consistency error for i = %d\n", i); exit (1); } } mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); }
void fmpq_poly_sample_D1(fmpq_poly_t f, int n, mpfr_prec_t prec, gmp_randstate_t state) { mpfr_t u1; mpfr_init2(u1, prec); mpfr_t u2; mpfr_init2(u2, prec); mpfr_t z1; mpfr_init2(z1, prec); mpfr_t z2; mpfr_init2(z2, prec); mpfr_t pi2; mpfr_init2(pi2, prec); mpfr_const_pi(pi2, MPFR_RNDN); mpfr_mul_si(pi2, pi2, 2, MPFR_RNDN); mpf_t tmp_f; mpq_t tmp_q; mpf_init(tmp_f); mpq_init(tmp_q); assert(n%2==0); for(long i=0; i<n; i+=2) { mpfr_urandomb(u1, state); mpfr_urandomb(u2, state); mpfr_log(u1, u1, MPFR_RNDN); mpfr_mul_si(u1, u1, -2, MPFR_RNDN); mpfr_sqrt(u1, u1, MPFR_RNDN); mpfr_mul(u2, pi2, u2, MPFR_RNDN); mpfr_cos(z1, u2, MPFR_RNDN); mpfr_mul(z1, z1, u1, MPFR_RNDN); //z1 = sqrt(-2*log(u1)) * cos(2*pi*u2) mpfr_sin(z2, u2, MPFR_RNDN); mpfr_mul(z2, z2, u1, MPFR_RNDN); //z1 = sqrt(-2*log(u1)) * sin(2*pi*U2) mpfr_get_f(tmp_f, z1, MPFR_RNDN); mpq_set_f(tmp_q, tmp_f); fmpq_poly_set_coeff_mpq(f, i, tmp_q); mpfr_get_f(tmp_f, z2, MPFR_RNDN); mpq_set_f(tmp_q, tmp_f); fmpq_poly_set_coeff_mpq(f, i+1, tmp_q); } mpf_clear(tmp_f); mpq_clear(tmp_q); mpfr_clear(pi2); mpfr_clear(u1); mpfr_clear(u2); mpfr_clear(z1); mpfr_clear(z2); }
/* worst cases communicated by Jean-Michel Muller and Vincent Lefevre */ static int check_worst_cases (void) { mpfr_t x; mpfr_t y; mpfr_init(x); mpfr_set_prec (x, 53); check_worst_case("4.44089209850062517562e-16", "1.00000000000000022204"); check_worst_case("6.39488462184069720009e-14", "1.00000000000006372680"); check_worst_case("1.84741111297455401935e-12", "1.00000000000184718907"); check_worst_case("1.76177628026265550074e-10", "1.00000000017617751702"); check3("1.76177628026265550074e-10", MPFR_RNDN, "1.00000000017617773906"); check_worst_case("7.54175277499595900852e-10", "1.00000000075417516676"); check3("7.54175277499595900852e-10", MPFR_RNDN, "1.00000000075417538881"); /* bug found by Vincent Lefe`vre on December 8, 1999 */ check3("-5.42410311287441459172e+02", MPFR_RNDN, "2.7176584868845723e-236"); /* further cases communicated by Vincent Lefe`vre on January 27, 2000 */ check3("-1.32920285897904911589e-10", MPFR_RNDN, "0.999999999867079769622"); check3("-1.44037948245738330735e-10", MPFR_RNDN, "0.9999999998559621072757"); check3("-1.66795910430705305937e-10", MPFR_RNDZ, "0.9999999998332040895832"); check3("-1.64310953745426656203e-10", MPFR_RNDN, "0.9999999998356891017792"); check3("-1.38323574826034659172e-10", MPFR_RNDZ, "0.9999999998616764251835"); check3("-1.23621668465115401498e-10", MPFR_RNDZ, "0.9999999998763783315425"); mpfr_set_prec (x, 601); mpfr_set_str (x, "0.88b6ba510e10450edc258748bc9dfdd466f21b47ed264cdf24aa8f64af1f3fad9ec2301d43c0743f534b5aa20091ff6d352df458ef1ba519811ef6f5b11853534fd8fa32764a0a6d2d0dd20@0", 16, MPFR_RNDZ); mpfr_init2 (y, 601); mpfr_exp_2 (y, x, MPFR_RNDD); mpfr_exp_3 (x, x, MPFR_RNDD); if (mpfr_cmp (x, y)) { printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=601\n"); printf ("mpfr_exp_2 gives "); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); printf ("\nmpfr_exp_3 gives "); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\n"); exit (1); } mpfr_set_prec (x, 13001); mpfr_set_prec (y, 13001); mpfr_urandomb (x, RANDS); mpfr_exp_3 (y, x, MPFR_RNDN); mpfr_exp_2 (x, x, MPFR_RNDN); if (mpfr_cmp (x, y)) { printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=13001\n"); exit (1); } mpfr_clear (x); mpfr_clear (y); return 0; }
static void check_inexact (void) { mpfr_t x, y, z; mp_prec_t px, py; int inexact, cmp; unsigned long int u; int rnd; mpfr_init (x); mpfr_init (y); mpfr_init (z); for (px=2; px<300; px++) { mpfr_set_prec (x, px); do { mpfr_urandomb (x, RANDS); } while (mpfr_cmp_ui (x, 0) == 0); u = randlimb (); for (py=2; py<300; py++) { mpfr_set_prec (y, py); mpfr_set_prec (z, py + px); for (rnd = 0; rnd < GMP_RND_MAX; rnd++) { inexact = mpfr_ui_div (y, u, x, (mp_rnd_t) rnd); if (mpfr_mul (z, y, x, (mp_rnd_t) rnd)) { printf ("z <- y * x should be exact\n"); exit (1); } cmp = mpfr_cmp_ui (z, u); if (((inexact == 0) && (cmp != 0)) || ((inexact > 0) && (cmp <= 0)) || ((inexact < 0) && (cmp >= 0))) { printf ("Wrong inexact flag for u=%lu, rnd=%s\n", u, mpfr_print_rnd_mode ((mp_rnd_t) rnd)); printf ("expected %d, got %d\n", cmp, inexact); printf ("x="); mpfr_print_binary (x); puts (""); printf ("y="); mpfr_print_binary (y); puts (""); printf ("y*x="); mpfr_print_binary (z); puts (""); exit (1); } } } } mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); }
static void check_inexact (void) { mpfr_t x, y, z; mpfr_prec_t px, py; int inexact, cmp; unsigned long int u; int rnd; mpfr_init (x); mpfr_init (y); mpfr_init (z); for (px=2; px<300; px++) { mpfr_set_prec (x, px); mpfr_urandomb (x, RANDS); do { u = randlimb (); } while (u == 0); for (py=2; py<300; py++) { mpfr_set_prec (y, py); mpfr_set_prec (z, py + mp_bits_per_limb); for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) { inexact = mpfr_div_ui (y, x, u, (mpfr_rnd_t) rnd); if (mpfr_mul_ui (z, y, u, (mpfr_rnd_t) rnd)) { printf ("z <- y * u should be exact for u=%lu\n", u); printf ("y="); mpfr_print_binary (y); puts (""); printf ("z="); mpfr_print_binary (z); puts (""); exit (1); } cmp = mpfr_cmp (z, x); if (((inexact == 0) && (cmp != 0)) || ((inexact > 0) && (cmp <= 0)) || ((inexact < 0) && (cmp >= 0))) { printf ("Wrong inexact flag for u=%lu, rnd=%s\n", u, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); printf ("x="); mpfr_print_binary (x); puts (""); printf ("y="); mpfr_print_binary (y); puts (""); exit (1); } } } } mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); }
static void test_cmp_f (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax) { mpfr_t x, z; mpf_t y; mpfr_prec_t p; int res1, res2; int n; mpfr_init (x); mpfr_init2 (z, pmax+GMP_NUMB_BITS); mpf_init2 (y, MPFR_PREC_MIN); /* check the erange flag when x is NaN */ mpfr_set_nan (x); mpf_set_ui (y, 17); mpfr_clear_erangeflag (); res1 = mpfr_cmp_f (x, y); if (res1 != 0 || mpfr_erangeflag_p () == 0) { printf ("Error for mpfr_cmp_f (NaN, 17)\n"); printf ("Return value: expected 0, got %d\n", res1); printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ()); exit (1); } for(p=pmin ; p < pmax ; p+=3) { mpfr_set_prec (x, p); mpf_set_prec (y, p); for ( n = 0; n < nmax ; n++) { mpfr_urandomb (x, RANDS); mpf_urandomb (y, RANDS, p); if (!MPFR_IS_SINGULAR (x)) { mpfr_set_f (z, y, MPFR_RNDN); mpfr_sub (z, x, z, MPFR_RNDN); res1 = mpfr_sgn (z); res2 = mpfr_cmp_f (x, y); if (res1 != res2) { printf("Error for mpfr_cmp_f: res=%d sub gives %d\n", res2, res1); exit (1); } } } } mpf_clear (y); mpfr_clear (x); mpfr_clear (z); }
/* Return a random number of MPFR object. */ static VALUE r_gmprandstate_mpfr_urandomb2(int argc, VALUE *argv, VALUE self) { MP_RANDSTATE *ptr_self; MPFR *ptr_return; VALUE val_ret; mp_prec_t prec; prec = r_mpfr_prec_from_optional_argument(0, 1, argc, argv); mprandstate_get_struct(self, ptr_self); r_mpfr_make_struct_init2(val_ret, ptr_return, prec); mpfr_urandomb(ptr_return, ptr_self); return val_ret; }
static int synge_rand(synge_t to, synge_t number, mpfr_rnd_t round) { /* A = rand() -- 0 <= rand() < 1 */ synge_t random; mpfr_init2(random, SYNGE_PRECISION); mpfr_urandomb(random, synge_state); /* rand(B) = rand() * B -- where 0 <= rand() < 1 */ mpfr_mul(to, random, number, round); /* free memory */ mpfr_clears(random, NULL); return 0; } /* synge_rand() */
static void set_special (mpfr_ptr x, unsigned int select) { MPFR_ASSERTN (select < SPECIAL_MAX); switch (select) { case 0: MPFR_SET_NAN (x); break; case 1: MPFR_SET_INF (x); MPFR_SET_POS (x); break; case 2: MPFR_SET_INF (x); MPFR_SET_NEG (x); break; case 3: MPFR_SET_ZERO (x); MPFR_SET_POS (x); break; case 4: MPFR_SET_ZERO (x); MPFR_SET_NEG (x); break; case 5: mpfr_set_str_binary (x, "1"); break; case 6: mpfr_set_str_binary (x, "-1"); break; case 7: mpfr_set_str_binary (x, "1e-1"); break; case 8: mpfr_set_str_binary (x, "1e+1"); break; case 9: mpfr_const_pi (x, MPFR_RNDN); break; case 10: mpfr_const_pi (x, MPFR_RNDN); MPFR_SET_EXP (x, MPFR_GET_EXP (x)-1); break; default: mpfr_urandomb (x, RANDS); if (randlimb () & 1) mpfr_neg (x, x, MPFR_RNDN); break; } }
static void check_inexact (void) { mpfr_prec_t p, q; mpfr_t x, y, absx; int rnd; int inexact, cmp; mpfr_init (x); mpfr_init (y); mpfr_init (absx); for (p=2; p<500; p++) { mpfr_set_prec (x, p); mpfr_set_prec (absx, p); mpfr_urandomb (x, RANDS); if (randlimb () % 2) { mpfr_set (absx, x, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); } else mpfr_set (absx, x, MPFR_RNDN); for (q=2; q<2*p; q++) { mpfr_set_prec (y, q); RND_LOOP (rnd) { inexact = mpfr_abs (y, x, (mpfr_rnd_t) rnd); cmp = mpfr_cmp (y, absx); if (((inexact == 0) && (cmp != 0)) || ((inexact > 0) && (cmp <= 0)) || ((inexact < 0) && (cmp >= 0))) { printf ("Wrong inexact flag: expected %d, got %d\n", cmp, inexact); printf ("x="); mpfr_dump (x); printf ("absx="); mpfr_dump (absx); printf ("y="); mpfr_dump (y); exit (1); } } } } mpfr_clear (x); mpfr_clear (y); mpfr_clear (absx); }
/* check that -1 <= x/sqrt(x^2+s*y^2) <= 1 for rounding to nearest or up with s = 0 and s = 1 */ static void test_property1 (mpfr_prec_t p, mpfr_rnd_t r, int s) { mpfr_t x, y, z, t; mpfr_init2 (x, p); mpfr_init2 (y, p); mpfr_init2 (z, p); mpfr_init2 (t, p); mpfr_urandomb (x, RANDS); mpfr_mul (z, x, x, r); if (s) { mpfr_urandomb (y, RANDS); mpfr_mul (t, y, y, r); mpfr_add (z, z, t, r); } mpfr_sqrt (z, z, r); mpfr_div (z, x, z, r); /* Note: if both x and y are 0, z is NAN, but the test below will be false. So, everything is fine. */ if (mpfr_cmp_si (z, -1) < 0 || mpfr_cmp_ui (z, 1) > 0) { printf ("Error, -1 <= x/sqrt(x^2+y^2) <= 1 does not hold for r=%s\n", mpfr_print_rnd_mode (r)); printf ("x="); mpfr_dump (x); printf ("y="); mpfr_dump (y); printf ("got "); mpfr_dump (z); exit (1); } mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); mpfr_clear (t); }
/* Problem reported by Carl Witty: check mpfr_urandomb give similar results on 32-bit and 64-bit machines. We assume the default GMP random generator does not depend on the machine word size, not on the GMP version. */ static void bug20100914 (void) { mpfr_t x; gmp_randstate_t s; #if __MPFR_GMP(4,2,0) # define C1 "0.895943" # define C2 "0.848824" #else # define C1 "0.479652" # define C2 "0.648529" #endif gmp_randinit_default (s); gmp_randseed_ui (s, 42); mpfr_init2 (x, 17); mpfr_urandomb (x, s); if (mpfr_cmp_str1 (x, C1) != 0) { printf ("Error in bug20100914, expected " C1 ", got "); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf ("\n"); exit (1); } mpfr_urandomb (x, s); if (mpfr_cmp_str1 (x, C2) != 0) { printf ("Error in bug20100914, expected " C2 ", got "); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf ("\n"); exit (1); } mpfr_clear (x); gmp_randclear (s); }
static void pow_int (mpfr_rnd_t rnd) { mpfr_t ref1, ref2, ref3; mpfr_t res1; int i; #ifdef DEBUG printf("pow_int\n"); #endif mpfr_inits2 ((randlimb () % 200) + MPFR_PREC_MIN, ref1, ref2, res1, (mpfr_ptr) 0); mpfr_init2 (ref3, 1005); for (i = 0; i <= 15; i++) { mpfr_urandomb (ref2, RANDS); if (i & 1) mpfr_neg (ref2, ref2, MPFR_RNDN); mpfr_set_ui (ref3, 20, MPFR_RNDN); /* We need to test huge integers because different algorithms/codes are used for not-too-large integers (mpfr_pow_z) and for general cases, in particular huge integers (mpfr_pow_general). [r7606] */ if (i & 2) mpfr_mul_2ui (ref3, ref3, 1000, MPFR_RNDN); if (i & 4) mpfr_add_ui (ref3, ref3, 1, MPFR_RNDN); /* odd integer */ /* reference call: pow(a, b, c) */ mpfr_pow (ref1, ref2, ref3, rnd); /* pow(a, a, c) */ mpfr_set (res1, ref2, rnd); /* exact operation */ mpfr_pow (res1, res1, ref3, rnd); if (mpfr_compare (res1, ref1)) { printf ("Error for pow_int(a, a, c) for "); DISP("a=",ref2); DISP2(", c=",ref3); printf ("expected "); mpfr_print_binary (ref1); puts (""); printf ("got "); mpfr_print_binary (res1); puts (""); exit (1); } } mpfr_clears (ref1, ref2, ref3, res1, (mpfr_ptr) 0); }
static void check_sgn(void) { mpfr_t x; int i, s1, s2; mpfr_init(x); for(i = 0 ; i < 100 ; i++) { mpfr_urandomb (x, RANDS); if (i&1) { MPFR_SET_POS(x); s2 = 1; } else { MPFR_SET_NEG(x); s2 = -1; } s1 = mpfr_sgn(x); if (s1 < -1 || s1 > 1) { printf("Error for sgn: out of range.\n"); goto lexit; } else if (MPFR_IS_NAN(x) || MPFR_IS_ZERO(x)) { if (s1 != 0) { printf("Error for sgn: Nan or Zero should return 0.\n"); goto lexit; } } else if (s1 != s2) { printf("Error for sgn. Return %d instead of %d.\n", s1, s2); goto lexit; } } mpfr_clear(x); return; lexit: mpfr_clear(x); exit(1); }
static void compare_exp2_exp3 (mpfr_prec_t p0, mpfr_prec_t p1) { mpfr_t x, y, z; mpfr_prec_t prec; mpfr_rnd_t rnd; mpfr_init (x); mpfr_init (y); mpfr_init (z); for (prec = p0; prec <= p1; prec ++) { mpfr_set_prec (x, prec); mpfr_set_prec (y, prec); mpfr_set_prec (z, prec); do mpfr_urandomb (x, RANDS); while (MPFR_IS_ZERO (x)); /* 0 is handled by mpfr_exp only */ rnd = RND_RAND (); mpfr_exp_2 (y, x, rnd); mpfr_exp_3 (z, x, rnd); if (mpfr_cmp (y,z)) { printf ("mpfr_exp_2 and mpfr_exp_3 disagree for rnd=%s and\nx=", mpfr_print_rnd_mode (rnd)); mpfr_print_binary (x); puts (""); printf ("mpfr_exp_2 gives "); mpfr_print_binary (y); puts (""); printf ("mpfr_exp_3 gives "); mpfr_print_binary (z); puts (""); exit (1); } } mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); }
static void test_cmp_f (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax) { mpfr_t x, z; mpf_t y; mpfr_prec_t p; int res1, res2; int n; mpfr_init (x); mpfr_init2 (z, pmax+GMP_NUMB_BITS); mpf_init2 (y, MPFR_PREC_MIN); for(p=pmin ; p < pmax ; p+=3) { mpfr_set_prec (x, p); mpf_set_prec (y, p); for ( n = 0; n < nmax ; n++) { mpfr_urandomb (x, RANDS); mpf_urandomb (y, RANDS, p); if (!MPFR_IS_SINGULAR (x)) { mpfr_set_f (z, y, MPFR_RNDN); mpfr_sub (z, x, z, MPFR_RNDN); res1 = mpfr_sgn (z); res2 = mpfr_cmp_f (x, y); if (res1 != res2) { printf("Error for mpfr_cmp_f: res=%d sub gives %d\n", res2, res1); exit (1); } } } } mpf_clear (y); mpfr_clear (x); mpfr_clear (z); }
/* Test the sorting function */ static void test_sort (mpfr_prec_t f, unsigned long n) { mpfr_t *tab; mpfr_ptr *tabtmp; mpfr_srcptr *perm; unsigned long i; /* Init stuff */ tab = (mpfr_t *) (*__gmp_allocate_func) (n * sizeof (mpfr_t)); for (i = 0; i < n; i++) mpfr_init2 (tab[i], f); tabtmp = (mpfr_ptr *) (*__gmp_allocate_func) (n * sizeof(mpfr_ptr)); perm = (mpfr_srcptr *) (*__gmp_allocate_func) (n * sizeof(mpfr_srcptr)); for (i = 0; i < n; i++) { mpfr_urandomb (tab[i], RANDS); tabtmp[i] = tab[i]; } mpfr_sum_sort ((mpfr_srcptr *)tabtmp, n, perm); if (check_is_sorted (n, perm) == 0) { printf ("mpfr_sum_sort incorrect.\n"); for (i = 0; i < n; i++) mpfr_dump (perm[i]); exit (1); } /* Clear stuff */ for (i = 0; i < n; i++) mpfr_clear (tab[i]); (*__gmp_free_func) (tab, n * sizeof (mpfr_t)); (*__gmp_free_func) (tabtmp, n * sizeof(mpfr_ptr)); (*__gmp_free_func) (perm, n * sizeof(mpfr_srcptr)); }