static void special (void) { mpfr_t x, y; mpfr_init (x); mpfr_init (y); MPFR_SET_INF(x); mpfr_set_ui (y, 1, MPFR_RNDN); mpfr_acosh (x, y, MPFR_RNDN); if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) ) { printf ("Inf flag not clears in acosh!\n"); exit (1); } if (mpfr_cmp_ui (x, 0)) { printf ("Error: mpfr_acosh(1) <> 0\n"); exit (1); } MPFR_SET_NAN(x); mpfr_acosh (x, y, MPFR_RNDN); if (MPFR_IS_NAN(x) || MPFR_IS_INF(x) ) { printf ("NAN flag not clears in acosh!\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_acosh (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_acosh(0) <> NaN\n"); exit (1); } mpfr_set_si (x, -1, MPFR_RNDN); mpfr_acosh (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_acosh(-1) <> NaN\n"); exit (1); } MPFR_SET_NAN(x); mpfr_acosh (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_acosh(NaN) <> NaN\n"); exit (1); } mpfr_set_inf (x, 1); mpfr_acosh (y, x, MPFR_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) { printf ("Error: mpfr_acosh(+Inf) <> +Inf\n"); exit (1); } mpfr_set_inf (x, -1); mpfr_acosh (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_acosh(-Inf) <> NaN\n"); exit (1); } mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_div_2exp (x, x, 1, MPFR_RNDN); mpfr_acosh (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_acosh(1/2) <> NaN\n"); exit (1); } mpfr_set_prec (x, 32); mpfr_set_prec (y, 32); mpfr_set_str_binary (x, "1.000001101011101111001011"); mpfr_acosh (y, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.111010100101101001010001101001E-2"); if (mpfr_cmp (x, y)) { printf ("Error: mpfr_acosh (1)\n"); exit (1); } mpfr_clear (x); mpfr_clear (y); }
int main (void) { mpfr_t x, u; mpf_t y, z; mp_exp_t emax; unsigned long k, pr; int r, inexact; MPFR_TEST_USE_RANDS (); tests_start_mpfr (); mpf_init (y); mpf_init (z); mpf_set_d (y, 0.0); /* check prototype of mpfr_init_set_f */ mpfr_init_set_f (x, y, GMP_RNDN); mpfr_set_prec (x, 100); mpfr_set_f (x, y, GMP_RNDN); mpf_random2 (y, 10, 0); mpfr_set_f (x, y, (mp_rnd_t) RND_RAND()); /* bug found by Jean-Pierre Merlet */ mpfr_set_prec (x, 256); mpf_set_prec (y, 256); mpfr_init2 (u, 256); mpfr_set_str (u, "7.f10872b020c49ba5e353f7ced916872b020c49ba5e353f7ced916872b020c498@2", 16, GMP_RNDN); mpf_set_str (y, "2033033E-3", 10); /* avoid 2033.033 which is locale-sensitive */ mpfr_set_f (x, y, GMP_RNDN); if (mpfr_cmp (x, u)) { printf ("mpfr_set_f failed for y=2033033E-3\n"); exit (1); } mpf_set_str (y, "-2033033E-3", 10); /* avoid -2033.033 which is locale-sensitive */ mpfr_set_f (x, y, GMP_RNDN); mpfr_neg (u, u, GMP_RNDN); if (mpfr_cmp (x, u)) { printf ("mpfr_set_f failed for y=-2033033E-3\n"); exit (1); } mpf_set_prec (y, 300); mpf_set_str (y, "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", -2); mpf_mul_2exp (y, y, 600); mpfr_set_prec (x, 300); mpfr_set_f (x, y, GMP_RNDN); if (mpfr_check (x) == 0) { printf ("Error in mpfr_set_f: corrupted result\n"); mpfr_dump (x); exit (1); } MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, 901) == 0); for (k = 1; k <= 100000; k++) { pr = 2 + (randlimb () & 255); mpf_set_prec (z, pr); mpf_random2 (z, z->_mp_prec, 0); mpfr_set_prec (x, pr); mpfr_set_f (x, z, (mp_rnd_t) 0); } /* Check for +0 */ mpfr_set_prec (x, 53); mpf_set_prec (y, 53); mpf_set_ui (y, 0); for (r = 0 ; r < GMP_RND_MAX ; r++) { int i; for (i = -1; i <= 1; i++) { if (i) mpfr_set_si (x, i, GMP_RNDN); inexact = mpfr_set_f (x, y, (mp_rnd_t) r); if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact) { printf ("mpfr_set_f(x,0) failed for %s, i = %d\n", mpfr_print_rnd_mode ((mp_rnd_t) r), i); exit (1); } } } /* coverage test */ mpf_set_prec (y, 2); mpfr_set_prec (x, 3 * mp_bits_per_limb); mpf_set_ui (y, 1); for (r = 0; r < mp_bits_per_limb; r++) { mpfr_random (x); /* to fill low limbs with random data */ inexact = mpfr_set_f (x, y, GMP_RNDN); MPFR_ASSERTN(inexact == 0 && mpfr_cmp_ui_2exp (x, 1, r) == 0); mpf_mul_2exp (y, y, 1); } mpf_set_ui (y, 1); mpf_mul_2exp (y, y, ULONG_MAX); mpfr_set_f (x, y, GMP_RNDN); mpfr_set_ui (u, 1, GMP_RNDN); mpfr_mul_2ui (u, u, ULONG_MAX, GMP_RNDN); if (!mpfr_equal_p (x, u)) { printf ("Error: mpfr_set_f (x, y, GMP_RNDN) for y = 2^ULONG_MAX\n"); exit (1); } emax = mpfr_get_emax (); /* For mpf_mul_2exp, emax must fit in an unsigned long! */ if (emax >= 0 && emax <= ULONG_MAX) { mpf_set_ui (y, 1); mpf_mul_2exp (y, y, emax); mpfr_set_f (x, y, GMP_RNDN); mpfr_set_ui_2exp (u, 1, emax, GMP_RNDN); if (!mpfr_equal_p (x, u)) { printf ("Error: mpfr_set_f (x, y, GMP_RNDN) for y = 2^emax\n"); exit (1); } } /* For mpf_mul_2exp, emax - 1 must fit in an unsigned long! */ if (emax >= 1 && emax - 1 <= ULONG_MAX) { mpf_set_ui (y, 1); mpf_mul_2exp (y, y, emax - 1); mpfr_set_f (x, y, GMP_RNDN); mpfr_set_ui_2exp (u, 1, emax - 1, GMP_RNDN); if (!mpfr_equal_p (x, u)) { printf ("Error: mpfr_set_f (x, y, GMP_RNDN) for y = 2^(emax-1)\n"); exit (1); } } mpfr_clear (x); mpfr_clear (u); mpf_clear (y); mpf_clear (z); tests_end_mpfr (); return 0; }
int main (void) { mpfr_t x; mpfr_exp_t emax; tests_start_mpfr (); mpfr_init (x); mpfr_set_nan (x); mpfr_prec_round (x, 2, MPFR_RNDN); MPFR_ASSERTN(mpfr_nan_p (x)); mpfr_set_inf (x, 1); mpfr_prec_round (x, 2, MPFR_RNDN); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); mpfr_set_inf (x, -1); mpfr_prec_round (x, 2, MPFR_RNDN); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0); mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_prec_round (x, 2, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); mpfr_prec_round (x, 2, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG(x)); emax = mpfr_get_emax (); set_emax (0); mpfr_set_prec (x, 3); mpfr_set_str_binary (x, "0.111"); mpfr_prec_round (x, 2, MPFR_RNDN); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); set_emax (emax); mpfr_set_prec (x, mp_bits_per_limb + 2); mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_nextbelow (x); mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0); mpfr_set_prec (x, 3); mpfr_set_ui (x, 5, MPFR_RNDN); mpfr_prec_round (x, 2, MPFR_RNDN); if (mpfr_cmp_ui(x, 4)) { printf ("Error in tround: got "); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf (" instead of 4\n"); exit (1); } /* check case when reallocation is needed */ mpfr_set_prec (x, 3); mpfr_set_ui (x, 5, MPFR_RNDN); /* exact */ mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN); if (mpfr_cmp_ui(x, 5)) { printf ("Error in tround: got "); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf (" instead of 5\n"); exit (1); } mpfr_clear(x); mpfr_init2 (x, 3); mpfr_set_si (x, -5, MPFR_RNDN); /* exact */ mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN); if (mpfr_cmp_si(x, -5)) { printf ("Error in tround: got "); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf (" instead of -5\n"); exit (1); } /* check case when new precision needs less limbs */ mpfr_set_prec (x, mp_bits_per_limb + 1); mpfr_set_ui (x, 5, MPFR_RNDN); /* exact */ mpfr_prec_round (x, 3, MPFR_RNDN); /* exact */ if (mpfr_cmp_ui(x, 5)) { printf ("Error in tround: got "); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf (" instead of 5\n"); exit (1); } mpfr_clear(x); tests_end_mpfr (); return 0; }
static void underflowed_cothinf (void) { mpfr_t x, y; int i, inex, rnd, err = 0; mpfr_exp_t old_emin; old_emin = mpfr_get_emin (); mpfr_init2 (x, 8); mpfr_init2 (y, 8); for (i = -1; i <= 1; i += 2) RND_LOOP (rnd) { mpfr_set_inf (x, i); mpfr_clear_flags (); set_emin (2); /* 1 is not representable. */ inex = mpfr_coth (x, x, (mpfr_rnd_t) rnd); set_emin (old_emin); if (! mpfr_underflow_p ()) { printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" " The underflow flag is not set.\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } mpfr_set_si (y, (i < 0 && (rnd == MPFR_RNDD || rnd == MPFR_RNDA)) || (i > 0 && (rnd == MPFR_RNDU || rnd == MPFR_RNDA)) ? 2 : 0, MPFR_RNDN); if (i < 0) mpfr_neg (y, y, MPFR_RNDN); if (! (mpfr_equal_p (x, y) && MPFR_MULT_SIGN (MPFR_SIGN (x), MPFR_SIGN (y)) > 0)) { printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_print_binary (x); printf (" instead of "); mpfr_print_binary (y); printf (".\n"); err = 1; } if ((rnd == MPFR_RNDD || (i > 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex >= 0) { printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" " The inexact value must be negative.\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if ((rnd == MPFR_RNDU || (i < 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex <= 0) { printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" " The inexact value must be positive.\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } } if (err) exit (1); mpfr_clear (x); mpfr_clear (y); }
int main (int argc, char *argv[]) { mpfr_t x, y; mpfr_exp_t emin, emax; tests_start_mpfr (); special_overflow (); emax_m_eps (); exp_range (); mpfr_init (x); mpfr_init (y); mpfr_set_ui (x, 4, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 16) != 0) { printf ("Error for 2^4, MPFR_RNDN\n"); exit (1); } mpfr_exp2 (y, x, MPFR_RNDD); if (mpfr_cmp_ui (y, 16) != 0) { printf ("Error for 2^4, MPFR_RNDD\n"); exit (1); } mpfr_exp2 (y, x, MPFR_RNDU); if (mpfr_cmp_ui (y, 16) != 0) { printf ("Error for 2^4, MPFR_RNDU\n"); exit (1); } mpfr_set_si (x, -4, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) { printf ("Error for 2^(-4), MPFR_RNDN\n"); exit (1); } mpfr_exp2 (y, x, MPFR_RNDD); if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) { printf ("Error for 2^(-4), MPFR_RNDD\n"); exit (1); } mpfr_exp2 (y, x, MPFR_RNDU); if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) { printf ("Error for 2^(-4), MPFR_RNDU\n"); exit (1); } mpfr_set_prec (x, 53); mpfr_set_prec (y, 53); mpfr_set_str (x, /*-1683977482443233.0 / 2199023255552.0*/ "-7.6578429909351734750089235603809357e2", 10, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (mpfr_cmp_str1 (y, "2.991959870867646566478e-231")) { printf ("Error for x=-1683977482443233/2^41\n"); exit (1); } mpfr_set_prec (x, 10); mpfr_set_prec (y, 10); /* save emin */ emin = mpfr_get_emin (); set_emin (-10); mpfr_set_si (x, -12, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) { printf ("Error for x=emin-2, RNDN\n"); printf ("Expected +0\n"); printf ("Got "); mpfr_dump (y); exit (1); } /* restore emin */ set_emin (emin); /* save emax */ emax = mpfr_get_emax (); set_emax (10); mpfr_set_ui (x, 11, MPFR_RNDN); mpfr_exp2 (y, x, MPFR_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) { printf ("Error for x=emax+1, RNDN\n"); exit (1); } /* restore emax */ set_emax (emax); MPFR_SET_INF(x); MPFR_SET_POS(x); mpfr_exp2 (y, x, MPFR_RNDN); if(!MPFR_IS_INF(y)) { printf ("evaluation of function in INF does not return INF\n"); exit (1); } MPFR_CHANGE_SIGN(x); mpfr_exp2 (y, x, MPFR_RNDN); if(!MPFR_IS_ZERO(y)) { printf ("evaluation of function in -INF does not return 0\n"); exit (1); } MPFR_SET_NAN(x); mpfr_exp2 (y, x, MPFR_RNDN); if(!MPFR_IS_NAN(y)) { printf ("evaluation of function in NaN does not return NaN\n"); exit (1); } if ((mpfr_uexp_t) 8 << 31 != 0 || mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000) { /* emax <= 10000000000 */ mpfr_set_prec (x, 40); mpfr_set_prec (y, 40); mpfr_set_str (x, "10000000000.5", 10, MPFR_RNDN); mpfr_clear_flags (); mpfr_exp2 (y, x, MPFR_RNDN); if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && mpfr_overflow_p ())) { printf ("exp2(10000000000.5) should overflow.\n"); exit (1); } } mpfr_set_prec (x, 2); mpfr_set_prec (y, 2); mpfr_set_str_binary (x, "-1.0E-26"); mpfr_exp2 (y, x, MPFR_RNDD); mpfr_set_str_binary (x, "1.1E-1"); if (mpfr_cmp (x, y)) { printf ("Error for exp(-2^(-26)) for prec=2\n"); exit (1); } test_generic (MPFR_PREC_MIN, 100, 100); mpfr_clear (x); mpfr_clear (y); overflowed_exp2_0 (); data_check ("data/exp2", mpfr_exp2, "mpfr_exp2"); tests_end_mpfr (); return 0; }
static void consistency (void) { mpfr_t x, s1, s2, c1, c2; mpfr_exp_t emin, emax; mpfr_rnd_t rnd; unsigned int flags_sin, flags_cos, flags, flags_before, flags_ref; int inex_sin, is, inex_cos, ic, inex, inex_ref; int i; emin = mpfr_get_emin (); emax = mpfr_get_emax (); for (i = 0; i <= 10000; i++) { mpfr_init2 (x, MPFR_PREC_MIN + (randlimb () % 8)); mpfr_inits2 (MPFR_PREC_MIN + (randlimb () % 8), s1, s2, c1, c2, (mpfr_ptr) 0); if (i < 8 * MPFR_RND_MAX) { int j = i / MPFR_RND_MAX; if (j & 1) mpfr_set_emin (MPFR_EMIN_MIN); mpfr_set_si (x, (j & 2) ? 1 : -1, MPFR_RNDN); mpfr_set_exp (x, mpfr_get_emin ()); rnd = (mpfr_rnd_t) (i % MPFR_RND_MAX); flags_before = 0; if (j & 4) mpfr_set_emax (-17); } else { tests_default_random (x, 256, -5, 50); rnd = RND_RAND (); flags_before = (randlimb () & 1) ? (unsigned int) (MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE) : (unsigned int) 0; } __gmpfr_flags = flags_before; inex_sin = mpfr_sin (s1, x, rnd); is = inex_sin < 0 ? 2 : inex_sin > 0 ? 1 : 0; flags_sin = __gmpfr_flags; __gmpfr_flags = flags_before; inex_cos = mpfr_cos (c1, x, rnd); ic = inex_cos < 0 ? 2 : inex_cos > 0 ? 1 : 0; flags_cos = __gmpfr_flags; __gmpfr_flags = flags_before; inex = mpfr_sin_cos (s2, c2, x, rnd); flags = __gmpfr_flags; inex_ref = is + 4 * ic; flags_ref = flags_sin | flags_cos; if (!(mpfr_equal_p (s1, s2) && mpfr_equal_p (c1, c2)) || inex != inex_ref || flags != flags_ref) { printf ("mpfr_sin_cos and mpfr_sin/mpfr_cos disagree on %s," " i = %d\nx = ", mpfr_print_rnd_mode (rnd), i); mpfr_dump (x); printf ("s1 = "); mpfr_dump (s1); printf ("s2 = "); mpfr_dump (s2); printf ("c1 = "); mpfr_dump (c1); printf ("c2 = "); mpfr_dump (c2); printf ("inex_sin = %d (s = %d), inex_cos = %d (c = %d), " "inex = %d (expected %d)\n", inex_sin, is, inex_cos, ic, inex, inex_ref); printf ("flags_sin = 0x%x, flags_cos = 0x%x, " "flags = 0x%x (expected 0x%x)\n", flags_sin, flags_cos, flags, flags_ref); exit (1); } mpfr_clears (x, s1, s2, c1, c2, (mpfr_ptr) 0); mpfr_set_emin (emin); mpfr_set_emax (emax); } }
static void test_overflow2 (void) { mpfr_t x, y, z, r; int i, inex, rnd, err = 0; mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 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, (mpfr_ptr) 0); }
void set_zero(elem &result) const { mpfr_init2(&result, R->get_precision()); mpfr_set_si(&result, 0, GMP_RNDN); }
int main (int argc, char *argv[]) { mpfr_t x, y; long n; if (argc > 1) { mpfr_init2 (x, atoi (argv[1])); mpfr_set_str (x, argv[3], 10, MPFR_RNDN); mpfr_jn (x, atoi (argv[2]), x, MPFR_RNDN); mpfr_out_str (stdout, 10, 10, x, MPFR_RNDN); printf ("\n"); mpfr_clear (x); return 0; } tests_start_mpfr (); mpfr_init (x); mpfr_init (y); /* special values */ mpfr_set_nan (x); mpfr_jn (y, 17, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_nan_p (y)); mpfr_set_inf (x, 1); /* +Inf */ mpfr_jn (y, 17, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); mpfr_set_inf (x, -1); /* -Inf */ mpfr_jn (y, 17, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */ mpfr_jn (y, 0, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(+0)=1 */ mpfr_jn (y, 17, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j17(+0)=+0 */ mpfr_jn (y, -17, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG (y)); /* j-17(+0)=-0 */ mpfr_jn (y, 42, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j42(+0)=+0 */ mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); /* -0 */ mpfr_jn (y, 0, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(-0)=1 */ mpfr_jn (y, 17, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG (y)); /* j17(-0)=-0 */ mpfr_jn (y, -17, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j-17(-0)=+0 */ mpfr_jn (y, 42, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j42(-0)=+0 */ mpfr_set_prec (x, 53); mpfr_set_prec (y, 53); mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_jn (y, 0, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=0, x=1, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_si (x, -1, MPFR_RNDN); mpfr_jn (y, 0, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=0, x=-1, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_jn (y, 1, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.0111000010100111001001111011101001011100001100011011"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=1, x=1, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_jn (y, 17, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.1100011111001010101001001001000110110000010001011E-65"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=17, x=1, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_jn (y, 42, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=42, x=1, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_jn (y, -42, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=-42, x=1, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_si (x, -1, MPFR_RNDN); mpfr_jn (y, 42, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=42, x=-1, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_si (x, -1, MPFR_RNDN); mpfr_jn (y, -42, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=-42, x=-1, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_jn (y, 4, x, MPFR_RNDN); mpfr_set_str_binary (x, "-0.0001110001011001100010100111100111100000111110111011111"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=4, x=17, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_jn (y, 16, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.0011101111100111101111010100000111111001111001001010011"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=16, x=17, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_jn (y, 256, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.11111101111100110000000010111101101011101011110001011E-894"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=256, x=17, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_jn (y, 65536, x, MPFR_RNDN); mpfr_set_str_binary (x, "100010010010011010110101100001000100011100010111011E-751747"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=65536, x=17, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_jn (y, 131072, x, MPFR_RNDN); mpfr_set_str_binary (x, "1000001001110011111001110110000010011010000001001101E-1634508"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=131072, x=17, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_jn (y, 262144, x, MPFR_RNDN); mpfr_set_str_binary (x, "1010011011000100111011001011110001000010000010111111E-3531100"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=262144, x=17, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_jn (y, 524288, x, MPFR_RNDN); mpfr_set_str_binary (x, "110000001010001111011011000011001011010100010001011E-7586426"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=524288, x=17, rnd=MPFR_RNDN\n"); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } n = LONG_MAX; /* ensures n is odd */ if (n % 2 == 0) n --; mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_jn (y, n, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.0"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=%ld, x=17, rnd=MPFR_RNDN\n", n); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_si (x, -17, MPFR_RNDN); mpfr_jn (y, n, x, MPFR_RNDN); mpfr_set_str_binary (x, "-0.0"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=%ld, x=-17, rnd=MPFR_RNDN\n", n); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_jn (y, -n, x, MPFR_RNDN); mpfr_set_str_binary (x, "-0.0"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=%ld, x=17, rnd=MPFR_RNDN\n", -n); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_si (x, -17, MPFR_RNDN); mpfr_jn (y, -n, x, MPFR_RNDN); mpfr_set_str_binary (x, "0.0"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_jn for n=%ld, x=-17, rnd=MPFR_RNDN\n", -n); printf ("Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_clear (x); mpfr_clear (y); tests_end_mpfr (); return 0; }
static PyObject * GMPy_Real_DivMod_1(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx = NULL, *tempy = NULL, *quo, *rem; PyObject *result; CHECK_CONTEXT(context); result = PyTuple_New(2); rem = GMPy_MPFR_New(0, context); quo = GMPy_MPFR_New(0, context); if (!result || !rem || !quo) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)quo); Py_XDECREF((PyObject*)rem); return NULL; } if (IS_REAL(x) && IS_REAL(y)) { tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!tempx || !tempy) { goto error; } if (mpfr_zero_p(tempy->f)) { context->ctx.divzero = 1; if (context->ctx.traps & TRAP_DIVZERO) { GMPY_DIVZERO("divmod() division by zero"); goto error; } } if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } else { mpfr_set_nan(quo->f); mpfr_set_nan(rem->f); } } else if (mpfr_inf_p(tempy->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } if (mpfr_zero_p(tempx->f)) { mpfr_set_zero(quo->f, mpfr_sgn(tempy->f)); mpfr_set_zero(rem->f, mpfr_sgn(tempy->f)); } else if ((mpfr_signbit(tempx->f)) != (mpfr_signbit(tempy->f))) { mpfr_set_si(quo->f, -1, MPFR_RNDN); mpfr_set_inf(rem->f, mpfr_sgn(tempy->f)); } else { mpfr_set_si(quo->f, 0, MPFR_RNDN); rem->rc = mpfr_set(rem->f, tempx->f, MPFR_RNDN); } } else { MPFR_Object *temp; if (!(temp = GMPy_MPFR_New(0, context))) { goto error; } mpfr_fmod(rem->f, tempx->f, tempy->f, MPFR_RNDN); mpfr_sub(temp->f, tempx->f, rem->f, MPFR_RNDN); mpfr_div(quo->f, temp->f, tempy->f, MPFR_RNDN); if (!mpfr_zero_p(rem->f)) { if ((mpfr_sgn(tempy->f) < 0) != (mpfr_sgn(rem->f) < 0)) { mpfr_add(rem->f, rem->f, tempy->f, MPFR_RNDN); mpfr_sub_ui(quo->f, quo->f, 1, MPFR_RNDN); } } else { mpfr_copysign(rem->f, rem->f, tempy->f, MPFR_RNDN); } if (!mpfr_zero_p(quo->f)) { mpfr_round(quo->f, quo->f); } else { mpfr_setsign(quo->f, quo->f, mpfr_sgn(tempx->f) * mpfr_sgn(tempy->f) - 1, MPFR_RNDN); } Py_DECREF((PyObject*)temp); } GMPY_MPFR_CHECK_RANGE(quo, context); GMPY_MPFR_CHECK_RANGE(rem, context); GMPY_MPFR_SUBNORMALIZE(quo, context); GMPY_MPFR_SUBNORMALIZE(rem, context); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return (PyObject*)result; } Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); Py_RETURN_NOTIMPLEMENTED; error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; }
static PyObject * GMPy_Real_DivMod_2(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx = NULL, *tempy = NULL, *quo = NULL, *rem = NULL; PyObject *result; CHECK_CONTEXT(context); if (!(result = PyTuple_New(2)) || !(rem = GMPy_MPFR_New(0, context)) || !(quo = GMPy_MPFR_New(0, context)) ) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)quo); Py_XDECREF((PyObject*)rem); return NULL; } if (IS_REAL(x) && IS_REAL(y)) { if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = GMPy_MPFR_From_Real(y, 1, context)) ) { goto error; } if (mpfr_zero_p(tempy->f)) { context->ctx.divzero = 1; if (context->ctx.traps & TRAP_DIVZERO) { GMPY_DIVZERO("divmod() division by zero"); goto error; } } if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } else { mpfr_set_nan(quo->f); mpfr_set_nan(rem->f); } } else if (mpfr_inf_p(tempy->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } if (mpfr_zero_p(tempx->f)) { mpfr_set_zero(quo->f, mpfr_sgn(tempy->f)); mpfr_set_zero(rem->f, mpfr_sgn(tempy->f)); } else if ((mpfr_signbit(tempx->f)) != (mpfr_signbit(tempy->f))) { mpfr_set_si(quo->f, -1, MPFR_RNDN); mpfr_set_inf(rem->f, mpfr_sgn(tempy->f)); } else { mpfr_set_si(quo->f, 0, MPFR_RNDN); rem->rc = mpfr_set(rem->f, tempx->f, MPFR_RNDN); } } else { MPQ_Object *mpqx = NULL, *mpqy = NULL, *temp_rem = NULL; MPZ_Object *temp_quo = NULL; if (!(mpqx = GMPy_MPQ_From_MPFR(tempx, context)) || !(mpqy = GMPy_MPQ_From_MPFR(tempy, context)) ) { Py_XDECREF((PyObject*)mpqx); Py_XDECREF((PyObject*)mpqy); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF(result); return NULL; } Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); temp_rem = GMPy_MPQ_New(context); temp_quo = GMPy_MPZ_New(context); if (!(temp_rem = GMPy_MPQ_New(context)) || !(temp_quo = GMPy_MPZ_New(context)) ) { Py_XDECREF((PyObject*)temp_rem); Py_XDECREF((PyObject*)temp_quo); Py_DECREF((PyObject*)mpqx); Py_DECREF((PyObject*)mpqy); Py_DECREF(result); return NULL; } mpq_div(temp_rem->q, mpqx->q, mpqy->q); mpz_fdiv_q(temp_quo->z, mpq_numref(temp_rem->q), mpq_denref(temp_rem->q)); /* Need to calculate x - quo * y. */ mpq_set_z(temp_rem->q, temp_quo->z); mpq_mul(temp_rem->q, temp_rem->q, mpqy->q); mpq_sub(temp_rem->q, mpqx->q, temp_rem->q); Py_DECREF((PyObject*)mpqx); Py_DECREF((PyObject*)mpqy); quo->rc = mpfr_set_z(quo->f, temp_quo->z, MPFR_RNDD); rem->rc = mpfr_set_q(rem->f, temp_rem->q, MPFR_RNDN); Py_DECREF((PyObject*)temp_rem); Py_DECREF((PyObject*)temp_quo); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } } Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); Py_RETURN_NOTIMPLEMENTED; error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; }
static void check_small (void) { mpfr_t x; char *s; mp_exp_t e; mp_prec_t p; mpfr_init (x); mpfr_set_prec (x, 20); mpfr_set_ui (x, 2, GMP_RNDN); mpfr_nexttozero (x); s = mpfr_get_str (NULL, &e, 4, 2, x, GMP_RNDU); if (strcmp (s, "20") || (e != 1)) { printf ("Error in mpfr_get_str: 2- rounded up with 2 digits" " in base 4\n"); exit (1); } mpfr_free_str (s); /* check n_digits=0 */ mpfr_set_prec (x, 5); mpfr_set_ui (x, 17, GMP_RNDN); s = mpfr_get_str (NULL, &e, 3, 0, x, GMP_RNDN); mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 36, 0, x, GMP_RNDN); mpfr_free_str (s); mpfr_set_prec (x, 64); mpfr_set_si (x, -1, GMP_RNDN); mpfr_div_2exp (x, x, 63, GMP_RNDN); /* x = -2^(-63) */ mpfr_add_ui (x, x, 1, GMP_RNDN); /* x = 1 - 2^(-63) */ mpfr_mul_2exp (x, x, 32, GMP_RNDN); /* x = 2^32 - 2^(-31) */ s = mpfr_get_str (NULL, &e, 3, 21, x, GMP_RNDU); if (strcmp (s, "102002022201221111211") || (e != 21)) { printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with" " 21 digits in base 3\n"); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 3, 20, x, GMP_RNDU); if (strcmp (s, "10200202220122111122") || (e != 21)) { printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with" " 20 digits in base 3\n"); exit (1); } mpfr_free_str (s); /* check corner case ret!=0, j0!=0 in mpfr_get_str_aux */ mpfr_set_prec (x, 100); mpfr_set_str_binary (x, "0.1001011111010001101110010101010101111001010111111101101101100110100011110110000101110110001011110000E-9"); s = mpfr_get_str (NULL, &e, 3, 2, x, GMP_RNDU); if (strcmp (s, "22") || (e != -6)) { printf ("Error in mpfr_get_str: 100-bit number rounded up with" " 2 digits in base 3\n"); exit (1); } mpfr_free_str (s); /* check corner case exact=0 in mpfr_get_str_aux */ mpfr_set_prec (x, 100); mpfr_set_str_binary (x, "0.1001001111101101111000101000110111111010101100000110010001111111011001101011101100001100110000000000E8"); s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDZ); if (strcmp (s, "14") || (e != 3)) { printf ("Error in mpfr_get_str: 100-bit number rounded to zero with" " 2 digits in base 10\n"); exit (1); } mpfr_free_str (s); for (p=4; p<=200; p++) { mpfr_set_prec (x, p); mpfr_set_str (x, "6.5", 10, GMP_RNDN); s = mpfr_get_str (NULL, &e, 6, 2, x, GMP_RNDN); if (strcmp (s, "10") || (e != 2)) { printf ("Error in mpfr_get_str: 6.5 rounded to nearest with" " 2 digits in base 6\n"); exit (1); } mpfr_free_str (s); mpfr_nexttoinf (x); s = mpfr_get_str (NULL, &e, 6, 2, x, GMP_RNDN); if (strcmp (s, "11") || (e != 2)) { printf ("Error in mpfr_get_str: 6.5+ rounded to nearest with" " 2 digits in base 6\ngot %se%d instead of 11e2\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str (x, "6.5", 10, GMP_RNDN); mpfr_nexttozero (x); s = mpfr_get_str (NULL, &e, 6, 2, x, GMP_RNDN); if (strcmp (s, "10") || (e != 2)) { printf ("Error in mpfr_get_str: 6.5- rounded to nearest with" " 2 digits in base 6\n"); exit (1); } mpfr_free_str (s); } mpfr_set_prec (x, 3); mpfr_set_ui (x, 7, GMP_RNDN); s = mpfr_get_str (NULL, &e, 2, 2, x, GMP_RNDU); if (strcmp (s, "10") || (e != 4)) { printf ("Error in mpfr_get_str: 7 rounded up with 2 bits should" " give 0.10e3 instead of 0.%s*2^%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* problem found by Fabrice Rouillier */ mpfr_set_prec (x, 63); mpfr_set_str (x, "5e14", 10, GMP_RNDN); s = mpfr_get_str (NULL, &e, 10, 18, x, GMP_RNDU); mpfr_free_str (s); /* bug found by Johan Vervloet */ mpfr_set_prec (x, 6); mpfr_set_str (x, "688.0", 10, GMP_RNDN); s = mpfr_get_str (NULL, &e, 2, 4, x, GMP_RNDU); if (strcmp (s, "1011") || (e != 10)) { printf ("Error in mpfr_get_str: 688 printed up to 4 bits should" " give 1.011e9\ninstead of "); mpfr_out_str (stdout, 2, 4, x, GMP_RNDU); puts (""); exit (1); } mpfr_free_str (s); mpfr_set_prec (x, 38); mpfr_set_str_binary (x, "1.0001110111110100011010100010010100110e-6"); s = mpfr_get_str (NULL, &e, 8, 10, x, GMP_RNDU); if (strcmp (s, "1073721522") || (e != -1)) { printf ("Error in mpfr_get_str (3): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_prec (x, 53); mpfr_set_str_binary (x, "0.11010111011101100010000100010101110001000000010111001E454"); s = mpfr_get_str (NULL, &e, 19, 12, x, GMP_RNDU); if (strcmp (s, "b1cgfa4gha0h") || (e != 107)) { printf ("Error in mpfr_get_str (4): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_prec (x, 145); mpfr_set_str_binary (x, "-0.1000110011000001011000010101101010110110101100101110100011111100011110011001001001010000100001000011000011000000010111011001000111101001110100110e6"); s = mpfr_get_str (NULL, &e, 4, 53, x, GMP_RNDU); if (strcmp (s, "-20303001120111222312230232203330132121021100201003003") || (e != 3)) { printf ("Error in mpfr_get_str (5): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_prec (x, 45); mpfr_set_str_binary (x, "-0.00100111010110010001011001110111010001010010010"); s = mpfr_get_str (NULL, &e, 32, 9, x, GMP_RNDN); if (strcmp (s, "-4tchctq54") || (e != 0)) { printf ("Error in mpfr_get_str (6): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* worst case found by Vincent Lefe`vre */ mpfr_set_prec (x, 53); mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E164"); s = mpfr_get_str (NULL, &e, 10, 17, x, GMP_RNDN); if (strcmp (s, "13076622631878654") || (e != 66)) { printf ("Error in mpfr_get_str (7): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10000001001001001100011101010011011011111000011000100E93"); s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDU); if (strcmp (s, "46") || e != 44) { printf ("Error in mpfr_get_str (8): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10010001111100000111001111010101001010000010111010101E55"); s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDN); if (strcmp (s, "19") || e != 33) { printf ("Error in mpfr_get_str (9): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "11011001010010111110010101101100111110111000010110110E44"); s = mpfr_get_str (NULL, &e, 10, 3, x, GMP_RNDN); if (strcmp (s, "135") || e != 30) { printf ("Error in mpfr_get_str (10): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "11101111101000001011100001111000011111101111011001100E72"); s = mpfr_get_str (NULL, &e, 10, 4, x, GMP_RNDN); if (strcmp (s, "3981") || e != 38) { printf ("Error in mpfr_get_str (11): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10011001001100100010111100001101110101001001111110000E46"); s = mpfr_get_str (NULL, &e, 10, 5, x, GMP_RNDN); if (strcmp (s, "37930") || e != 30) { printf ("Error in mpfr_get_str (12): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10001100110111001011011110011011011101100011010001011E-72"); s = mpfr_get_str (NULL, &e, 10, 6, x, GMP_RNDN); if (strcmp (s, "104950") || e != -5) { printf ("Error in mpfr_get_str (13): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10100100001011001000011001101101000110100110000010111E89"); s = mpfr_get_str (NULL, &e, 10, 7, x, GMP_RNDN); if (strcmp (s, "3575392") || e != 43) { printf ("Error in mpfr_get_str (14): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "11000011011110110010100110001010000001010011001011001E-73"); s = mpfr_get_str (NULL, &e, 10, 8, x, GMP_RNDN); if (strcmp (s, "72822386") || e != -6) { printf ("Error in mpfr_get_str (15): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10101010001101000111001100001000100011100010010001010E78"); s = mpfr_get_str (NULL, &e, 10, 9, x, GMP_RNDN); if (strcmp (s, "180992873") || e != 40) { printf ("Error in mpfr_get_str (16): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10110111001000100000001101111001100101101110011011101E91"); s = mpfr_get_str (NULL, &e, 10, 10, x, GMP_RNDN); if (strcmp (s, "1595312255") || e != 44) { printf ("Error in mpfr_get_str (17): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E93"); s = mpfr_get_str (NULL, &e, 10, 11, x, GMP_RNDN); if (strcmp (s, "54835744350") || e != 44) { printf ("Error in mpfr_get_str (18): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E92"); s = mpfr_get_str (NULL, &e, 10, 12, x, GMP_RNDN); if (strcmp (s, "274178721752") || e != 44) { printf ("Error in mpfr_get_str (19): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E91"); s = mpfr_get_str (NULL, &e, 10, 13, x, GMP_RNDN); if (strcmp (s, "1370893608762") || e != 44) { printf ("Error in mpfr_get_str (20): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10010011010110011100010010100101100011101000011111111E92"); s = mpfr_get_str (NULL, &e, 10, 14, x, GMP_RNDN); if (strcmp (s, "25672105101864") || e != 44) { printf ("Error in mpfr_get_str (21): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "100110111110110001000101110100100101101000011111001E87"); s = mpfr_get_str (NULL, &e, 10, 15, x, GMP_RNDN); if (strcmp (s, "212231308858721") || e != 42) { printf ("Error in mpfr_get_str (22): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10111010110000111000101100101111001011011100101001111E-128"); s = mpfr_get_str (NULL, &e, 10, 15, x, GMP_RNDN); if (strcmp (s, "193109287087290") || e != -22) { printf ("Error in mpfr_get_str (22b): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10001101101011010001111110000111010111010000110101010E80"); s = mpfr_get_str (NULL, &e, 10, 16, x, GMP_RNDN); if (strcmp (s, "6026241735727920") || e != 40) { printf ("Error in mpfr_get_str (23): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "100010001011101001110101000110011001001000110001001E-81"); s = mpfr_get_str (NULL, &e, 10, 17, x, GMP_RNDN); if (strcmp (s, "49741483709103481") || e != -9) { printf ("Error in mpfr_get_str (24): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "11000100001001001110111010011001111001001010110101111E-101"); s = mpfr_get_str (NULL, &e, 10, 7, x, GMP_RNDN); if (strcmp (s, "2722049") || e != -14) { printf ("Error in mpfr_get_str (25): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-135"); s = mpfr_get_str (NULL, &e, 10, 8, x, GMP_RNDN); if (strcmp (s, "20138772") || e != -24) { printf ("Error in mpfr_get_str (26): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-136"); s = mpfr_get_str (NULL, &e, 10, 9, x, GMP_RNDN); if (strcmp (s, "100693858") || e != -24) { printf ("Error in mpfr_get_str (27): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10001000001110010110001011111011111011011010000110001E-110"); s = mpfr_get_str (NULL, &e, 10, 14, x, GMP_RNDN); if (strcmp (s, "36923634350619") || e != -17) { printf ("Error in mpfr_get_str (28): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "11001100010111000111100010000110011101110001000101111E-87"); s = mpfr_get_str (NULL, &e, 10, 16, x, GMP_RNDN); if (strcmp (s, "4646636036100804") || e != -10) { printf ("Error in mpfr_get_str (29): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "10011111001111110100001001010111111011010101111111000E-99"); s = mpfr_get_str (NULL, &e, 10, 17, x, GMP_RNDN); if (strcmp (s, "88399901882446712") || e != -14) { printf ("Error in mpfr_get_str (30): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 8116315218207718*2^(-293) ~ 0.5100000000000000000015*10^(-72) */ mpfr_set_str_binary (x, "11100110101011011111011100101011101110110001111100110E-293"); s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDU); if (strcmp (s, "52") || e != -72) { printf ("Error in mpfr_get_str (31u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDD); if (strcmp (s, "51") || e != -72) { printf ("Error in mpfr_get_str (31d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 6712731423444934*2^536 ~ .151000000000000000000067*10^178 */ mpfr_set_str_binary (x, "10111110110010011000110010011111101111000111111000110E536"); s = mpfr_get_str (NULL, &e, 10, 3, x, GMP_RNDU); if (strcmp (s, "152") || e != 178) { printf ("Error in mpfr_get_str (32u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 3, x, GMP_RNDD); if (strcmp (s, "151") || e != 178) { printf ("Error in mpfr_get_str (32d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 3356365711722467*2^540 ~ .120800000000000000000054*10^179 */ mpfr_set_str_binary (x, "1011111011001001100011001001111110111100011111100011E540"); s = mpfr_get_str (NULL, &e, 10, 4, x, GMP_RNDU); if (strcmp (s, "1209") || e != 179) { printf ("Error in mpfr_get_str (33u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 4, x, GMP_RNDD); if (strcmp (s, "1208") || e != 179) { printf ("Error in mpfr_get_str (33d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 6475049196144587*2^100 ~ .8208099999999999999999988*10^46 */ mpfr_set_str_binary (x, "10111000000010000010111011111001111010100011111001011E100"); s = mpfr_get_str (NULL, &e, 10, 5, x, GMP_RNDU); if (strcmp (s, "82081") || e != 46) { printf ("Error in mpfr_get_str (34u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 5, x, GMP_RNDD); if (strcmp (s, "82080") || e != 46) { printf ("Error in mpfr_get_str (34d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 6722280709661868*2^364 ~ .25260100000000000000000012*10^126 */ mpfr_set_str_binary (x, "10111111000011110000011110001110001111010010010101100E364"); s = mpfr_get_str (NULL, &e, 10, 6, x, GMP_RNDU); if (strcmp (s, "252602") || e != 126) { printf ("Error in mpfr_get_str (35u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 6, x, GMP_RNDD); if (strcmp (s, "252601") || e != 126) { printf ("Error in mpfr_get_str (35d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 5381065484265332*2^(-455) ~ .578389299999999999999999982*10^(-121) */ mpfr_set_str_binary (x, "10011000111100000110011110000101100111110011101110100E-455"); s = mpfr_get_str (NULL, &e, 10, 7, x, GMP_RNDU); if (strcmp (s, "5783893") || e != -121) { printf ("Error in mpfr_get_str (36u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 7, x, GMP_RNDD); if (strcmp (s, "5783892") || e != -121) { printf ("Error in mpfr_get_str (36d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 8369123604277281*2^(-852) ~ .27869147000000000000000000056*10^(-240) */ mpfr_set_str_binary (x, "11101101110111010110001101111100000111010100000100001E-852"); s = mpfr_get_str (NULL, &e, 10, 8, x, GMP_RNDU); if (strcmp (s, "27869148") || e != -240) { printf ("Error in mpfr_get_str (37u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 8, x, GMP_RNDD); if (strcmp (s, "27869147") || e != -240) { printf ("Error in mpfr_get_str (37d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 7976538478610756*2^377 ~ .245540326999999999999999999982*10^130 */ mpfr_set_str_binary (x, "11100010101101001111010010110100011100000100101000100E377"); s = mpfr_get_str (NULL, &e, 10, 9, x, GMP_RNDU); if (strcmp (s, "245540327") || e != 130) { printf ("Error in mpfr_get_str (38u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 9, x, GMP_RNDD); if (strcmp (s, "245540326") || e != 130) { printf ("Error in mpfr_get_str (38d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 8942832835564782*2^(-382) ~ .9078555839000000000000000000038*10^(-99) */ mpfr_set_str_binary (x, "11111110001010111010110000110011100110001010011101110E-382"); s = mpfr_get_str (NULL, &e, 10, 10, x, GMP_RNDU); if (strcmp (s, "9078555840") || e != -99) { printf ("Error in mpfr_get_str (39u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 10, x, GMP_RNDD); if (strcmp (s, "9078555839") || e != -99) { printf ("Error in mpfr_get_str (39d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 4471416417782391*2^(-380) ~ .18157111678000000000000000000077*10^(-98) */ mpfr_set_str_binary (x, "1111111000101011101011000011001110011000101001110111E-380"); s = mpfr_get_str (NULL, &e, 10, 11, x, GMP_RNDU); if (strcmp (s, "18157111679") || e != -98) { printf ("Error in mpfr_get_str (40u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 11, x, GMP_RNDD); if (strcmp (s, "18157111678") || e != -98) { printf ("Error in mpfr_get_str (40d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 7225450889282194*2^711 ~ .778380362292999999999999999999971*10^230 */ mpfr_set_str_binary (x, "11001101010111000001001100001100110010000001010010010E711"); s = mpfr_get_str (NULL, &e, 10, 12, x, GMP_RNDU); if (strcmp (s, "778380362293") || e != 230) { printf ("Error in mpfr_get_str (41u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 12, x, GMP_RNDD); if (strcmp (s, "778380362292") || e != 230) { printf ("Error in mpfr_get_str (41d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 3612725444641097*2^713 ~ .1556760724585999999999999999999942*10^231 */ mpfr_set_str_binary (x, "1100110101011100000100110000110011001000000101001001E713"); s = mpfr_get_str (NULL, &e, 10, 13, x, GMP_RNDU); if (strcmp (s, "1556760724586") || e != 231) { printf ("Error in mpfr_get_str (42u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 13, x, GMP_RNDD); if (strcmp (s, "1556760724585") || e != 231) { printf ("Error in mpfr_get_str (42d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 6965949469487146*2^(-248) ~ .15400733123779000000000000000000016*10^(-58) */ mpfr_set_str_binary (x, "11000101111110111111001111111101001101111000000101010E-248"); s = mpfr_get_str (NULL, &e, 10, 14, x, GMP_RNDU); if (strcmp (s, "15400733123780") || e != -58) { printf ("Error in mpfr_get_str (43u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 14, x, GMP_RNDD); if (strcmp (s, "15400733123779") || e != -58) { printf ("Error in mpfr_get_str (43d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 3482974734743573*2^(-244) ~ .12320586499023200000000000000000013*10^(-57) */ mpfr_set_str_binary (x, "1100010111111011111100111111110100110111100000010101E-244"); s = mpfr_get_str (NULL, &e, 10, 15, x, GMP_RNDU); if (strcmp (s, "123205864990233") || e != -57) { printf ("Error in mpfr_get_str (44u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 15, x, GMP_RNDD); if (strcmp (s, "123205864990232") || e != -57) { printf ("Error in mpfr_get_str (44d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 7542952370752766*2^(-919) ~ .170206189963739699999999999999999974*10^(-260) */ mpfr_set_str_binary (x, "11010110011000100011001110100100111011100110011111110E-919"); s = mpfr_get_str (NULL, &e, 10, 16, x, GMP_RNDU); if (strcmp (s, "1702061899637397") || e != -260) { printf ("Error in mpfr_get_str (45u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 16, x, GMP_RNDD); if (strcmp (s, "1702061899637396") || e != -260) { printf ("Error in mpfr_get_str (45d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); /* 5592117679628511*2^165 ~ .26153245263757307000000000000000000074*10^66 */ mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E165"); s = mpfr_get_str (NULL, &e, 10, 17, x, GMP_RNDU); if (strcmp (s, "26153245263757308") || e != 66) { printf ("Error in mpfr_get_str (46u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 17, x, GMP_RNDD); if (strcmp (s, "26153245263757307") || e != 66) { printf ("Error in mpfr_get_str (46d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "11010010110111100001011010000110010000100001011011101E1223"); s = mpfr_get_str (NULL, &e, 10, 17, x, GMP_RNDN); if (strcmp (s, "10716284017294180") || e != 385) { printf ("Error in mpfr_get_str (47n): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 18, x, GMP_RNDU); if (strcmp (s, "107162840172941805") || e != 385) { printf ("Error in mpfr_get_str (47u): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 18, x, GMP_RNDD); if (strcmp (s, "107162840172941804") || e != 385) { printf ("Error in mpfr_get_str (47d): s=%s e=%d\n", s, (int) e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "11111101111011000001010100001101101000010010001111E122620"); s = mpfr_get_str (NULL, &e, 10, 17, x, GMP_RNDN); if (strcmp (s, "22183435284042374") || e != 36928) { printf ("Error in mpfr_get_str (48n): s=%s e=%ld\n", s, (long) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 18, x, GMP_RNDU); if (strcmp (s, "221834352840423736") || e != 36928) { printf ("Error in mpfr_get_str (48u): s=%s e=%ld\n", s, (long) e); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 18, x, GMP_RNDD); if (strcmp (s, "221834352840423735") || e != 36928) { printf ("Error in mpfr_get_str (48d): s=%s e=%ld\n", s, (long) e); exit (1); } mpfr_free_str (s); mpfr_set_prec (x, 45); mpfr_set_str_binary (x, "1E45"); s = mpfr_get_str (NULL, &e, 32, 9, x, GMP_RNDN); mpfr_free_str (s); mpfr_set_prec (x, 7); mpfr_set_str_binary (x, "0.1010101E10"); s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDU); mpfr_free_str (s); /* checks rounding of negative numbers */ mpfr_set_prec (x, 7); mpfr_set_str (x, "-11.5", 10, GMP_RNDN); s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDD); if (strcmp (s, "-12")) { printf ("Error in mpfr_get_str for x=-11.5 and rnd=GMP_RNDD\n" "got %s instead of -12\n", s); exit (1); } mpfr_free_str (s); s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDU); if (strcmp (s, "-11")) { printf ("Error in mpfr_get_str for x=-11.5 and rnd=GMP_RNDU\n"); exit (1); } mpfr_free_str (s); /* bug found by Jean-Pierre Merlet, produced error in mpfr_get_str */ mpfr_set_prec (x, 128); mpfr_set_str_binary (x, "0.10111001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011010E3"); s = mpfr_get_str (NULL, &e, 10, 0, x, GMP_RNDU); mpfr_free_str (s); mpfr_set_prec (x, 381); mpfr_set_str_binary (x, "0.111111111111111111111111111111111111111111111111111111111111111111101110110000100110011101101101001010111000101111000100100011110101010110101110100000010100001000110100000100011111001000010010000010001010111001011110000001110010111101100001111000101101100000010110000101100100000101010110010110001010100111001111100011100101100000100100111001100010010011110011011010110000001000010"); s = mpfr_get_str (NULL, &e, 10, 0, x, GMP_RNDD); if (e != 0) { printf ("Error in mpfr_get_str for x=0.999999..., exponent is %d" " instead of 0\n", (int) e); exit (1); } mpfr_free_str (s); mpfr_set_prec (x, 5); mpfr_set_str_binary (x, "1101.1"); /* 13.5, or (16)_7 + 1/2 */ s = mpfr_get_str (NULL, &e, 7, 2, x, GMP_RNDN); /* we are in the tie case: both surrounding numbers are (16)_7 and (20)_7: since (16)_7 = 13 is odd and (20)_7 = 14 is even, we should have s = "20" and e = 2 */ if (e != 2 || strcmp (s, "20")) { printf ("Error in mpfr_get_str for x=13.5, base 7\n"); printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, e); exit (1); } mpfr_free_str (s); /* try the same example, with input just below or above 13.5 */ mpfr_set_prec (x, 1000); mpfr_set_str_binary (x, "1101.1"); mpfr_nextabove (x); s = mpfr_get_str (NULL, &e, 7, 2, x, GMP_RNDN); if (e != 2 || strcmp (s, "20")) { printf ("Error in mpfr_get_str for x=13.5+tiny, base 7\n"); printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "1101.1"); mpfr_nextbelow (x); s = mpfr_get_str (NULL, &e, 7, 2, x, GMP_RNDN); if (e != 2 || strcmp (s, "16")) { printf ("Error in mpfr_get_str for x=13.5-tiny, base 7\n"); printf ("Expected s=16, e=2, got s=%s, e=%ld\n", s, e); exit (1); } mpfr_free_str (s); mpfr_set_prec (x, 7); mpfr_set_str_binary (x, "110000.1"); /* 48.5, or (66)_7 + 1/2 */ s = mpfr_get_str (NULL, &e, 7, 2, x, GMP_RNDN); /* we are in the tie case: both surrounding numbers are (66)_7 and (100)_7: since (66)_7 = 48 is even and (100)_7 is odd, we should hase s = "66" and e = 2 */ if (e != 2 || strcmp (s, "66")) { printf ("Error in mpfr_get_str for x=48.5, base 7\n"); printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, e); exit (1); } mpfr_free_str (s); /* try the same example, with input just below or above 48.5 */ mpfr_set_prec (x, 1000); mpfr_set_str_binary (x, "110000.1"); mpfr_nextabove (x); s = mpfr_get_str (NULL, &e, 7, 2, x, GMP_RNDN); if (e != 3 || strcmp (s, "10")) { printf ("Error in mpfr_get_str for x=48.5+tiny, base 7\n"); printf ("Expected s=10, e=3, got s=%s, e=%ld\n", s, e); exit (1); } mpfr_free_str (s); mpfr_set_str_binary (x, "110000.1"); mpfr_nextbelow (x); s = mpfr_get_str (NULL, &e, 7, 2, x, GMP_RNDN); if (e != 2 || strcmp (s, "66")) { printf ("Error in mpfr_get_str for x=48.5-tiny, base 7\n"); printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, e); exit (1); } mpfr_free_str (s); mpfr_clear (x); }
static void overflow_inv (void) { mpfr_t x, y, z; int precx; int s, t; int inex; int rnd; mpfr_init2 (y, 2); mpfr_init2 (z, 8); mpfr_set_si (y, -1, MPFR_RNDN); for (precx = 10; precx <= 100; precx += 90) { const char *sp = precx == 10 ? "overflow_inv (precx = 10)" : "overflow_inv (precx = 100)"; mpfr_init2 (x, precx); for (s = -1; s <= 1; s += 2) { inex = mpfr_set_si_2exp (x, s, - mpfr_get_emax (), MPFR_RNDN); MPFR_ASSERTN (inex == 0); for (t = 0; t <= 5; t++) { /* If precx = 10: * x = s * 2^(-emax) * (1 + t * 2^(-9)), so that * 1/x = s * 2^emax * (1 - t * 2^(-9) + eps) with eps > 0. * Values of (1/x) / 2^emax and overflow condition for x > 0: * t = 0: 1 o: always * t = 1: 0.11111111 100000000011... o: MPFR_RNDN and MPFR_RNDU * t = 2: 0.11111111 000000001111... o: MPFR_RNDU * t = 3: 0.11111110 100000100011... o: never * * If precx = 100: * t = 0: always overflow * t > 0: overflow for MPFR_RNDN and MPFR_RNDU. */ RND_LOOP (rnd) { int inf, overflow; mpfr_rnd_t rnd2; if (rnd == MPFR_RNDA) rnd2 = s < 0 ? MPFR_RNDD : MPFR_RNDU; else rnd2 = (mpfr_rnd_t) rnd; overflow = t == 0 || ((mpfr_rnd_t) rnd == MPFR_RNDN && (precx > 10 || t == 1)) || (rnd2 == (s < 0 ? MPFR_RNDD : MPFR_RNDU) && (precx > 10 || t <= 2)); inf = overflow && ((mpfr_rnd_t) rnd == MPFR_RNDN || rnd2 == (s < 0 ? MPFR_RNDD : MPFR_RNDU)); mpfr_clear_flags (); inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd); if (overflow ^ !! mpfr_overflow_p ()) { printf ("Bad overflow flag in %s\nfor mpfr_pow%s\n" "s = %d, t = %d, %s\n", sp, ext ? ", extended exponent range" : "", s, t, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); exit (1); } if (overflow && (inf ^ !! MPFR_IS_INF (z))) { printf ("Bad value in %s\nfor mpfr_pow%s\n" "s = %d, t = %d, %s\nGot ", sp, ext ? ", extended exponent range" : "", s, t, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); printf (" instead of %s value.\n", inf ? "infinite" : "finite"); exit (1); } test_others (NULL, "-1", (mpfr_rnd_t) rnd, x, y, z, inex, __gmpfr_flags, sp); } /* RND_LOOP */ mpfr_nexttoinf (x); } /* for (t = ...) */ } /* for (s = ...) */ mpfr_clear (x); } /* for (precx = ...) */ mpfr_clears (y, z, (mpfr_ptr) 0); }
static void underflow_up1 (void) { mpfr_t delta, x, y, z, z0; mpfr_exp_t n; int inex; int rnd; int i; n = mpfr_get_emin (); if (n < LONG_MIN) return; mpfr_init2 (delta, 2); inex = mpfr_set_ui_2exp (delta, 1, -2, MPFR_RNDN); MPFR_ASSERTN (inex == 0); mpfr_init2 (x, 8); inex = mpfr_set_ui (x, 2, MPFR_RNDN); MPFR_ASSERTN (inex == 0); mpfr_init2 (y, sizeof (long) * CHAR_BIT + 4); inex = mpfr_set_si (y, n, MPFR_RNDN); MPFR_ASSERTN (inex == 0); mpfr_init2 (z0, 2); mpfr_set_ui (z0, 0, MPFR_RNDN); mpfr_init2 (z, 32); for (i = 0; i <= 12; i++) { unsigned int flags = 0; char sy[16]; /* Test 2^(emin - i/4). * --> Underflow iff i > 4. * --> Zero in MPFR_RNDN iff i >= 8. */ if (i != 0 && i != 4) flags |= MPFR_FLAGS_INEXACT; if (i > 4) flags |= MPFR_FLAGS_UNDERFLOW; sprintf (sy, "emin - %d/4", i); RND_LOOP (rnd) { int zero; zero = (i > 4 && (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)) || (i >= 8 && rnd == MPFR_RNDN); mpfr_clear_flags (); inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd); cmpres (1, "2", sy, (mpfr_rnd_t) rnd, zero ? z0 : (mpfr_ptr) NULL, -1, z, inex, flags, "underflow_up1", "mpfr_pow"); test_others ("2", sy, (mpfr_rnd_t) rnd, x, y, z, inex, flags, "underflow_up1"); } inex = mpfr_sub (y, y, delta, MPFR_RNDN); MPFR_ASSERTN (inex == 0); } mpfr_clears (delta, x, y, z, z0, (mpfr_ptr) 0); }
/* Test of s * (q * 2^(n-1) - 2^k) + h + i * 2^(-2) + j * 2^(-2) * with h = -1 or 1, -1 <= i odd <= j <= 3, 2 <= q <= 3, s = -1 or 1, * prec n-k. * On a 64-bit machine: * MPFR_RNDN, tmd=2, rbit=0, sst=0, negative is checked with the inputs * -3*2^58, 2^5, -1, 2^(-2), 3*2^(-2) * MPFR_RNDN, tmd=2, rbit=0, sst=1, negative is checked with the inputs * -3*2^58, 2^5, -1, 3*2^(-2), 3*2^(-2) * * Note: This test detects an error in a result when "sq + 3" is replaced * by "sq + 2" (11th argument of the first sum_raw invocation) and the * corresponding assertion d >= 3 is removed, confirming that one cannot * decrease this proved error bound. */ static void check4 (void) { mpfr_t sum1, sum2, s1, s2, s3, s4, t[5]; mpfr_ptr p[5]; int h, i, j, k, n, q, r, s, prec, inex1, inex2; mpfr_inits2 (257, sum1, sum2, s1, s2, s3, s4, (mpfr_ptr) 0); for (i = 0; i < 5; i++) { mpfr_init2 (t[i], 2); p[i] = t[i]; } /* No GNU style for the many nested loops... */ for (k = 1; k <= 64; k++) { mpfr_set_si_2exp (t[0], -1, k, MPFR_RNDN); for (n = k + MPFR_PREC_MIN; n <= k + 65; n++) { prec = n - k; mpfr_set_prec (sum1, prec); mpfr_set_prec (sum2, prec); for (q = 2; q <= 3; q++) { mpfr_set_si_2exp (t[1], q, n - 1, MPFR_RNDN); inex1 = mpfr_add (s1, t[0], t[1], MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); for (s = -1; s <= 1; s += 2) { mpfr_neg (t[0], t[0], MPFR_RNDN); mpfr_neg (t[1], t[1], MPFR_RNDN); mpfr_neg (s1, s1, MPFR_RNDN); for (h = -1; h <= 1; h += 2) { mpfr_set_si (t[2], h, MPFR_RNDN); inex1 = mpfr_add (s2, s1, t[2], MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); for (i = -1; i <= 3; i += 2) { mpfr_set_si_2exp (t[3], i, -2, MPFR_RNDN); inex1 = mpfr_add (s3, s2, t[3], MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); for (j = i; j <= 3; j++) { mpfr_set_si_2exp (t[4], j, -2, MPFR_RNDN); inex1 = mpfr_add (s4, s3, t[4], MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); RND_LOOP (r) { inex1 = mpfr_set (sum1, s4, (mpfr_rnd_t) r); inex2 = mpfr_sum (sum2, p, 5, (mpfr_rnd_t) r); MPFR_ASSERTN (mpfr_check (sum1)); MPFR_ASSERTN (mpfr_check (sum2)); if (!(mpfr_equal_p (sum1, sum2) && SAME_SIGN (inex1, inex2))) { printf ("Error in check4 on %s, " "k = %d, n = %d (prec %d), " "q = %d, s = %d, h = %d, i = %d, j = %d\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), k, n, prec, q, s, h, i, j); printf ("Expected "); mpfr_dump (sum1); printf ("with inex = %d\n", inex1); printf ("Got "); mpfr_dump (sum2); printf ("with inex = %d\n", inex2); exit (1); } } } } } } } } } for (i = 0; i < 5; i++) mpfr_clear (t[i]); mpfr_clears (sum1, sum2, s1, s2, s3, s4, (mpfr_ptr) 0); }
static void check_parse (void) { mpfr_t x; char *s; int res; mpfr_init (x); /* Invalid data */ mpfr_set_si (x, -1, MPFR_RNDN); res = mpfr_strtofr (x, " invalid", NULL, 10, MPFR_RNDN); if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x)) { printf ("Failed parsing ' invalid' (1)\n X="); mpfr_dump (x); exit (1); } MPFR_ASSERTN (res == 0); mpfr_set_si (x, -1, MPFR_RNDN); res = mpfr_strtofr (x, " invalid", &s, 0, MPFR_RNDN); if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x) || strcmp (s, " invalid")) { printf ("Failed parsing ' invalid' (2)\n S=%s\n X=", s); mpfr_dump (x); exit (1); } MPFR_ASSERTN (res == 0); /* Check if it stops correctly */ mpfr_strtofr (x, "15*x", &s, 10, MPFR_RNDN); if (mpfr_cmp_ui (x, 15) || strcmp (s, "*x")) { printf ("Failed parsing '15*x'\n S=%s\n X=", s); mpfr_dump (x); exit (1); } /* Check for leading spaces */ mpfr_strtofr (x, " 1.5E-10 *x^2", &s, 10, MPFR_RNDN); if (mpfr_cmp_str1 (x, "1.5E-10") || strcmp (s, " *x^2")) { printf ("Failed parsing '1.5E-10*x^2'\n S=%s\n X=", s); mpfr_dump (x); exit (1); } /* Check for leading sign */ mpfr_strtofr (x, " +17.5E-42E ", &s, 10, MPFR_RNDN); if (mpfr_cmp_str1 (x, "17.5E-42") || strcmp (s, "E ")) { printf ("Failed parsing '+17.5E-42E '\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-17.5E+42E\n", &s, 10, MPFR_RNDN); if (mpfr_cmp_str1 (x, "-17.5E42") || strcmp (s, "E\n")) { printf ("Failed parsing '-17.5E+42\\n'\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* P form */ mpfr_strtofr (x, "0x42P17", &s, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '0x42P17' (base = 16)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-0X42p17", &s, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-0x42p17' (base = 16)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "42p17", &s, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '42p17' (base = 16)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-42P17", &s, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-42P17' (base = 16)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "0b1001P17", &s, 2, MPFR_RNDN); if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '0b1001P17' (base = 2)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-0B1001p17", &s, 2, MPFR_RNDN); if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-0B1001p17' (base = 2)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "1001p17", &s, 2, MPFR_RNDN); if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '1001p17' (base = 2)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-1001P17", &s, 2, MPFR_RNDN); if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-1001P17' (base = 2)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check for auto-detection of the base */ mpfr_strtofr (x, "+0x42P17", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "42P17", 16, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-42E17", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "-42E17", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-42E17'\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-42P17", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "-42", 10, MPFR_RNDN) || strcmp (s, "P17")) { printf ("Failed parsing '-42P17' (base = 0)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, " 0b0101.011@42", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, " 0b0101.011P42", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "+0x42@17", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "4.2@18", 16, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check for space inside the mantissa */ mpfr_strtofr (x, "+0x4 2@17", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 4) || strcmp(s," 2@17")) { printf ("Failed parsing '+0x4 2@17'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "+0x42 P17", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 0x42) || strcmp(s," P17")) { printf ("Failed parsing '+0x42 P17'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Space between mantissa and exponent */ mpfr_strtofr (x, " -0b0101P 17", &s, 0, MPFR_RNDN); if (mpfr_cmp_si (x, -5) || strcmp(s,"P 17")) { printf ("Failed parsing '-0b0101P 17'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check for Invalid exponent. */ mpfr_strtofr (x, " -0b0101PF17", &s, 0, MPFR_RNDN); if (mpfr_cmp_si (x, -5) || strcmp(s,"PF17")) { printf ("Failed parsing '-0b0101PF17'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* At least one digit in the mantissa. */ mpfr_strtofr (x, " .E10", &s, 0, MPFR_RNDN); if (strcmp(s," .E10")) { printf ("Failed parsing ' .E10'\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check 2 '.': 2.3.4 */ mpfr_strtofr (x, "-1.2.3E4", &s, 0, MPFR_RNDN); if (mpfr_cmp_str1 (x, "-1.2") || strcmp(s,".3E4")) { printf ("Failed parsing '-1.2.3E4'\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check for 0x and 0b */ mpfr_strtofr (x, " 0xG", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 0) || strcmp(s,"xG")) { printf ("Failed parsing ' 0xG'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, " 0b2", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 0) || strcmp(s,"b2")) { printf ("Failed parsing ' 0b2'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-0x.23@2Z33", &s, 0, MPFR_RNDN); if (mpfr_cmp_si (x, -0x23) || strcmp(s,"Z33")) { printf ("Failed parsing '-0x.23@2Z33'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, " 0x", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 0) || strcmp(s,"x")) { printf ("Failed parsing ' 0x'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_clear (x); }
static void overflowed_sin_cos0 (void) { mpfr_t x, y, z; int emax, inex, rnd, err = 0; mpfr_exp_t old_emax; old_emax = mpfr_get_emax (); mpfr_init2 (x, 8); mpfr_init2 (y, 8); mpfr_init2 (z, 8); for (emax = -1; emax <= 0; emax++) { mpfr_set_ui_2exp (z, 1, emax, MPFR_RNDN); mpfr_nextbelow (z); set_emax (emax); /* 1 is not representable. */ /* and if emax < 0, 1 - eps is not representable either. */ RND_LOOP (rnd) { mpfr_set_si (x, 0, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); mpfr_clear_flags (); inex = mpfr_sin_cos (x, y, x, (mpfr_rnd_t) rnd); if (! mpfr_overflow_p ()) { printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" " The overflow flag is not set.\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (! (mpfr_zero_p (x) && MPFR_SIGN (x) < 0)) { printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" " Got sin = ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_print_binary (x); printf (" instead of -0.\n"); err = 1; } if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) { if (inex == 0) { printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" " The inexact value must be non-zero.\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (! mpfr_equal_p (y, z)) { printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" " Got cos = ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_print_binary (y); printf (" instead of 0.11111111E%d.\n", emax); err = 1; } } else { if (inex == 0) { printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" " The inexact value must be non-zero.\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (! (mpfr_inf_p (y) && MPFR_SIGN (y) > 0)) { printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" " Got cos = ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_print_binary (y); printf (" instead of +Inf.\n"); err = 1; } } } set_emax (old_emax); } if (err) exit (1); mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); }
int main (void) { mpfr_t x; int r; mpfr_prec_t p; unsigned long k; tests_start_mpfr (); special (); mpfr_init (x); for (p = 2; p < 100; p++) { mpfr_set_prec (x, p); for (r = 0; r < MPFR_RND_MAX; r++) { mpfr_set_ui (x, 1, MPFR_RNDN); k = 2 + randlimb () % 4; /* 2 <= k <= 5 */ mpfr_root (x, x, k, (mpfr_rnd_t) r); if (mpfr_cmp_ui (x, 1)) { printf ("Error in mpfr_root(%lu) for x=1, rnd=%s\ngot ", k, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\n"); exit (1); } mpfr_set_si (x, -1, MPFR_RNDN); if (k % 2) { mpfr_root (x, x, k, (mpfr_rnd_t) r); if (mpfr_cmp_si (x, -1)) { printf ("Error in mpfr_root(%lu) for x=-1, rnd=%s\ngot ", k, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\n"); exit (1); } } if (p >= 5) { int i; for (i = -12; i <= 12; i++) { mpfr_set_ui (x, 27, MPFR_RNDN); mpfr_mul_2si (x, x, 3*i, MPFR_RNDN); mpfr_root (x, x, 3, MPFR_RNDN); if (mpfr_cmp_si_2exp (x, 3, i)) { printf ("Error in mpfr_root(3) for " "x = 27.0 * 2^(%d), rnd=%s\ngot ", 3*i, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\ninstead of 3 * 2^(%d)\n", i); exit (1); } } } } } mpfr_clear (x); test_generic_ui (2, 200, 30); tests_end_mpfr (); return 0; }
int main (int argc, char *argv[]) { mpfr_t x, y; mpfr_exp_t emin, emax; int inex, ov; tests_start_mpfr (); special_overflow (); emax_m_eps (); exp_range (); mpfr_init (x); mpfr_init (y); mpfr_set_ui (x, 4, MPFR_RNDN); mpfr_exp10 (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 10000) != 0) { printf ("Error for 10^4, MPFR_RNDN\n"); exit (1); } mpfr_exp10 (y, x, MPFR_RNDD); if (mpfr_cmp_ui (y, 10000) != 0) { printf ("Error for 10^4, MPFR_RNDD\n"); exit (1); } mpfr_exp10 (y, x, MPFR_RNDU); if (mpfr_cmp_ui (y, 10000) != 0) { printf ("Error for 10^4, MPFR_RNDU\n"); exit (1); } mpfr_set_prec (x, 10); mpfr_set_prec (y, 10); /* save emin */ emin = mpfr_get_emin (); set_emin (-11); mpfr_set_si (x, -4, MPFR_RNDN); mpfr_exp10 (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) { printf ("Error for emin = -11, x = -4, RNDN\n"); printf ("Expected +0\n"); printf ("Got "); mpfr_print_binary (y); puts (""); exit (1); } /* restore emin */ set_emin (emin); /* save emax */ emax = mpfr_get_emax (); set_emax (13); mpfr_set_ui (x, 4, MPFR_RNDN); mpfr_exp10 (y, x, MPFR_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) { printf ("Error for emax = 13, x = 4, RNDN\n"); printf ("Expected +inf\n"); printf ("Got "); mpfr_print_binary (y); puts (""); exit (1); } /* restore emax */ set_emax (emax); MPFR_SET_INF (x); MPFR_SET_POS (x); mpfr_exp10 (y, x, MPFR_RNDN); if (!MPFR_IS_INF (y)) { printf ("evaluation of function in INF does not return INF\n"); exit (1); } MPFR_CHANGE_SIGN (x); mpfr_exp10 (y, x, MPFR_RNDN); if (!MPFR_IS_ZERO (y)) { printf ("evaluation of function in -INF does not return 0\n"); exit (1); } MPFR_SET_NAN (x); mpfr_exp10 (y, x, MPFR_RNDN); if (!MPFR_IS_NAN (y)) { printf ("evaluation of function in NaN does not return NaN\n"); exit (1); } if ((mpfr_uexp_t) 8 << 31 != 0 || mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000) { /* emax <= 10000000000 */ mpfr_set_prec (x, 40); mpfr_set_prec (y, 40); mpfr_set_str (x, "3010299957", 10, MPFR_RNDN); mpfr_clear_flags (); inex = mpfr_exp10 (y, x, MPFR_RNDN); ov = mpfr_overflow_p (); if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && ov)) { printf ("Overflow error for x = 3010299957, MPFR_RNDN.\n"); mpfr_dump (y); printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); exit (1); } } test_generic (2, 100, 100); mpfr_clear (x); mpfr_clear (y); overfl_exp10_0 (); data_check ("data/exp10", mpfr_exp10, "mpfr_exp10"); tests_end_mpfr (); return 0; }
static void special (void) { mpfr_t x, y; int i; mpfr_init (x); mpfr_init (y); /* root(NaN) = NaN */ mpfr_set_nan (x); mpfr_root (y, x, 17, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: root(NaN,17) <> NaN\n"); exit (1); } /* root(+Inf) = +Inf */ mpfr_set_inf (x, 1); mpfr_root (y, x, 42, MPFR_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) { printf ("Error: root(+Inf,42) <> +Inf\n"); exit (1); } /* root(-Inf, 17) = -Inf */ mpfr_set_inf (x, -1); mpfr_root (y, x, 17, MPFR_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0) { printf ("Error: root(-Inf,17) <> -Inf\n"); exit (1); } /* root(-Inf, 42) = NaN */ mpfr_set_inf (x, -1); mpfr_root (y, x, 42, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: root(-Inf,42) <> -Inf\n"); exit (1); } /* root(+/-0) = +/-0 */ mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_root (y, x, 17, MPFR_RNDN); if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) { printf ("Error: root(+0,17) <> +0\n"); exit (1); } mpfr_neg (x, x, MPFR_RNDN); mpfr_root (y, x, 42, MPFR_RNDN); if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) { printf ("Error: root(-0,42) <> -0\n"); exit (1); } mpfr_set_prec (x, 53); mpfr_set_str (x, "8.39005285514734966412e-01", 10, MPFR_RNDN); mpfr_root (x, x, 3, MPFR_RNDN); if (mpfr_cmp_str1 (x, "9.43166207799662426048e-01")) { printf ("Error in root3 (1)\n"); printf ("expected 9.43166207799662426048e-01\n"); printf ("got "); mpfr_dump (x); exit (1); } mpfr_set_prec (x, 32); mpfr_set_prec (y, 32); mpfr_set_str_binary (x, "0.10000100001100101001001001011001"); mpfr_root (x, x, 3, MPFR_RNDN); mpfr_set_str_binary (y, "0.11001101011000100111000111111001"); if (mpfr_cmp (x, y)) { printf ("Error in root3 (2)\n"); exit (1); } mpfr_set_prec (x, 32); mpfr_set_prec (y, 32); mpfr_set_str_binary (x, "-0.1100001110110000010101011001011"); mpfr_root (x, x, 3, MPFR_RNDD); mpfr_set_str_binary (y, "-0.11101010000100100101000101011001"); if (mpfr_cmp (x, y)) { printf ("Error in root3 (3)\n"); exit (1); } mpfr_set_prec (x, 82); mpfr_set_prec (y, 27); mpfr_set_str_binary (x, "0.1010001111011101011011000111001011001101100011110110010011011011011010011001100101e-7"); mpfr_root (y, x, 3, MPFR_RNDD); mpfr_set_str_binary (x, "0.101011110001110001000100011E-2"); if (mpfr_cmp (x, y)) { printf ("Error in root3 (4)\n"); exit (1); } mpfr_set_prec (x, 204); mpfr_set_prec (y, 38); mpfr_set_str_binary (x, "0.101000000001101000000001100111111011111001110110100001111000100110100111001101100111110001110001011011010110010011100101111001111100001010010100111011101100000011011000101100010000000011000101001010001001E-5"); mpfr_root (y, x, 3, MPFR_RNDD); mpfr_set_str_binary (x, "0.10001001111010011011101000010110110010E-1"); if (mpfr_cmp (x, y)) { printf ("Error in root3 (5)\n"); exit (1); } /* Worst case found on 2006-11-25 */ mpfr_set_prec (x, 53); mpfr_set_prec (y, 53); mpfr_set_str_binary (x, "1.0100001101101101001100110001001000000101001101100011E28"); mpfr_root (y, x, 35, MPFR_RNDN); mpfr_set_str_binary (x, "1.1100000010110101100011101011000010100001101100100011E0"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_root (y, x, 35, MPFR_RNDN) for\n" "x = 1.0100001101101101001100110001001000000101001101100011E28\n" "Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } /* Worst cases found on 2006-11-26 */ mpfr_set_str_binary (x, "1.1111010011101110001111010110000101110000110110101100E17"); mpfr_root (y, x, 36, MPFR_RNDD); mpfr_set_str_binary (x, "1.0110100111010001101001010111001110010100111111000010E0"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_root (y, x, 36, MPFR_RNDD) for\n" "x = 1.1111010011101110001111010110000101110000110110101100E17\n" "Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } mpfr_set_str_binary (x, "1.1100011101101101100010110001000001110001111110010000E23"); mpfr_root (y, x, 36, MPFR_RNDU); mpfr_set_str_binary (x, "1.1001010100001110000110111111100011011101110011000100E0"); if (mpfr_cmp (x, y)) { printf ("Error in mpfr_root (y, x, 36, MPFR_RNDU) for\n" "x = 1.1100011101101101100010110001000001110001111110010000E23\n" "Expected "); mpfr_dump (x); printf ("Got "); mpfr_dump (y); exit (1); } /* Check for k = 1 */ mpfr_set_ui (x, 17, MPFR_RNDN); i = mpfr_root (y, x, 1, MPFR_RNDN); if (mpfr_cmp_ui (x, 17) || i != 0) { printf ("Error in root (17^(1/1))\n"); exit (1); } #if 0 /* Check for k == 0: For 0 <= x < 1 => +0. For x = 1 => 1. For x > 1, => +Inf. For x < 0 => NaN. */ i = mpfr_root (y, x, 0, MPFR_RNDN); if (!MPFR_IS_INF (y) || !MPFR_IS_POS (y) || i != 0) { printf ("Error in root 17^(1/0)\n"); exit (1); } mpfr_set_ui (x, 1, MPFR_RNDN); i = mpfr_root (y, x, 0, MPFR_RNDN); if (mpfr_cmp_ui (y, 1) || i != 0) { printf ("Error in root 1^(1/0)\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); i = mpfr_root (y, x, 0, MPFR_RNDN); if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y) || i != 0) { printf ("Error in root 0+^(1/0)\n"); exit (1); } MPFR_CHANGE_SIGN (x); i = mpfr_root (y, x, 0, MPFR_RNDN); if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y) || i != 0) { printf ("Error in root 0-^(1/0)\n"); exit (1); } mpfr_set_ui_2exp (x, 17, -5, MPFR_RNDD); i = mpfr_root (y, x, 0, MPFR_RNDN); if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y) || i != 0) { printf ("Error in root (17/2^5)^(1/0)\n"); exit (1); } #endif mpfr_set_ui (x, 0, MPFR_RNDN); i = mpfr_root (y, x, 0, MPFR_RNDN); if (!MPFR_IS_NAN (y) || i != 0) { printf ("Error in root 0+^(1/0)\n"); exit (1); } /* Check for k==2 */ mpfr_set_si (x, -17, MPFR_RNDD); i = mpfr_root (y, x, 2, MPFR_RNDN); if (!MPFR_IS_NAN (y) || i != 0) { printf ("Error in root (-17)^(1/2)\n"); exit (1); } mpfr_clear (x); mpfr_clear (y); }
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, (mpfr_ptr) 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, (mpfr_ptr) 0); }
int main (int argc, char *argv[]) { mpfr_t x, y; unsigned int n; int inex; tests_start_mpfr (); test_generic (2, 100, 20); mpfr_init2 (x, 53); mpfr_init2 (y, 53); /* check NaN */ mpfr_set_nan (x); inex = test_log10 (y, x, MPFR_RNDN); MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0); /* check Inf */ mpfr_set_inf (x, -1); inex = test_log10 (y, x, MPFR_RNDN); MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0); mpfr_set_inf (x, 1); inex = test_log10 (y, x, MPFR_RNDN); MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0 && inex == 0); mpfr_set_ui (x, 0, MPFR_RNDN); inex = test_log10 (x, x, MPFR_RNDN); MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0); mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); inex = test_log10 (x, x, MPFR_RNDN); MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0); /* check negative argument */ mpfr_set_si (x, -1, MPFR_RNDN); inex = test_log10 (y, x, MPFR_RNDN); MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0); /* check log10(1) = 0 */ mpfr_set_ui (x, 1, MPFR_RNDN); inex = test_log10 (y, x, MPFR_RNDN); MPFR_ASSERTN (mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y) && inex == 0); /* check log10(10^n)=n */ mpfr_set_ui (x, 1, MPFR_RNDN); for (n = 1; n <= 15; n++) { mpfr_mul_ui (x, x, 10, MPFR_RNDN); /* x = 10^n */ inex = test_log10 (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, n)) { printf ("log10(10^n) <> n for n=%u\n", n); exit (1); } MPFR_ASSERTN (inex == 0); } mpfr_clear (x); mpfr_clear (y); data_check ("data/log10", mpfr_log10, "mpfr_log10"); tests_end_mpfr (); return 0; }
int main (void) { mpfr_t x; int r; mpfr_prec_t p; tests_start_mpfr (); special (); mpfr_init (x); for (p=2; p<100; p++) { mpfr_set_prec (x, p); for (r = 0; r < MPFR_RND_MAX; r++) { mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_cbrt (x, x, (mpfr_rnd_t) r); if (mpfr_cmp_ui (x, 1)) { printf ("Error in mpfr_cbrt for x=1, rnd=%s\ngot ", mpfr_print_rnd_mode ((mpfr_rnd_t) r)); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\n"); exit (1); } mpfr_set_si (x, -1, MPFR_RNDN); mpfr_cbrt (x, x, (mpfr_rnd_t) r); if (mpfr_cmp_si (x, -1)) { printf ("Error in mpfr_cbrt for x=-1, rnd=%s\ngot ", mpfr_print_rnd_mode ((mpfr_rnd_t) r)); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\n"); exit (1); } if (p >= 5) { int i; for (i = -12; i <= 12; i++) { mpfr_set_ui (x, 27, MPFR_RNDN); mpfr_mul_2si (x, x, 3*i, MPFR_RNDN); mpfr_cbrt (x, x, MPFR_RNDN); if (mpfr_cmp_si_2exp (x, 3, i)) { printf ("Error in mpfr_cbrt for " "x = 27.0 * 2^(%d), rnd=%s\ngot ", 3*i, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\ninstead of 3 * 2^(%d)\n", i); exit (1); } } } } } mpfr_clear (x); test_generic (2, 200, 10); data_check ("data/cbrt", mpfr_cbrt, "mpfr_cbrt"); tests_end_mpfr (); 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); }
/* The computation of z = pow(x,y) is done by z = exp(y * log(x)) = x^y For the special cases, see Section F.9.4.4 of the C standard: _ pow(±0, y) = ±inf for y an odd integer < 0. _ pow(±0, y) = +inf for y < 0 and not an odd integer. _ pow(±0, y) = ±0 for y an odd integer > 0. _ pow(±0, y) = +0 for y > 0 and not an odd integer. _ pow(-1, ±inf) = 1. _ pow(+1, y) = 1 for any y, even a NaN. _ pow(x, ±0) = 1 for any x, even a NaN. _ pow(x, y) = NaN for finite x < 0 and finite non-integer y. _ pow(x, -inf) = +inf for |x| < 1. _ pow(x, -inf) = +0 for |x| > 1. _ pow(x, +inf) = +0 for |x| < 1. _ pow(x, +inf) = +inf for |x| > 1. _ pow(-inf, y) = -0 for y an odd integer < 0. _ pow(-inf, y) = +0 for y < 0 and not an odd integer. _ pow(-inf, y) = -inf for y an odd integer > 0. _ pow(-inf, y) = +inf for y > 0 and not an odd integer. _ pow(+inf, y) = +0 for y < 0. _ pow(+inf, y) = +inf for y > 0. */ int mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode) { int inexact; int cmp_x_1; int y_is_integer; MPFR_SAVE_EXPO_DECL (expo); MPFR_LOG_FUNC (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, mpfr_get_prec (y), mpfr_log_prec, y, rnd_mode), ("z[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (z), mpfr_log_prec, z, inexact)); if (MPFR_ARE_SINGULAR (x, y)) { /* pow(x, 0) returns 1 for any x, even a NaN. */ if (MPFR_UNLIKELY (MPFR_IS_ZERO (y))) return mpfr_set_ui (z, 1, rnd_mode); else if (MPFR_IS_NAN (x)) { MPFR_SET_NAN (z); MPFR_RET_NAN; } else if (MPFR_IS_NAN (y)) { /* pow(+1, NaN) returns 1. */ if (mpfr_cmp_ui (x, 1) == 0) return mpfr_set_ui (z, 1, rnd_mode); MPFR_SET_NAN (z); MPFR_RET_NAN; } else if (MPFR_IS_INF (y)) { if (MPFR_IS_INF (x)) { if (MPFR_IS_POS (y)) MPFR_SET_INF (z); else MPFR_SET_ZERO (z); MPFR_SET_POS (z); MPFR_RET (0); } else { int cmp; cmp = mpfr_cmpabs (x, __gmpfr_one) * MPFR_INT_SIGN (y); MPFR_SET_POS (z); if (cmp > 0) { /* Return +inf. */ MPFR_SET_INF (z); MPFR_RET (0); } else if (cmp < 0) { /* Return +0. */ MPFR_SET_ZERO (z); MPFR_RET (0); } else { /* Return 1. */ return mpfr_set_ui (z, 1, rnd_mode); } } } else if (MPFR_IS_INF (x)) { int negative; /* Determine the sign now, in case y and z are the same object */ negative = MPFR_IS_NEG (x) && mpfr_odd_p (y); if (MPFR_IS_POS (y)) MPFR_SET_INF (z); else MPFR_SET_ZERO (z); if (negative) MPFR_SET_NEG (z); else MPFR_SET_POS (z); MPFR_RET (0); } else { int negative; MPFR_ASSERTD (MPFR_IS_ZERO (x)); /* Determine the sign now, in case y and z are the same object */ negative = MPFR_IS_NEG(x) && mpfr_odd_p (y); if (MPFR_IS_NEG (y)) { MPFR_ASSERTD (! MPFR_IS_INF (y)); MPFR_SET_INF (z); MPFR_SET_DIVBY0 (); } else MPFR_SET_ZERO (z); if (negative) MPFR_SET_NEG (z); else MPFR_SET_POS (z); MPFR_RET (0); } } /* x^y for x < 0 and y not an integer is not defined */ y_is_integer = mpfr_integer_p (y); if (MPFR_IS_NEG (x) && ! y_is_integer) { MPFR_SET_NAN (z); MPFR_RET_NAN; } /* now the result cannot be NaN: (1) either x > 0 (2) or x < 0 and y is an integer */ cmp_x_1 = mpfr_cmpabs (x, __gmpfr_one); if (cmp_x_1 == 0) return mpfr_set_si (z, MPFR_IS_NEG (x) && mpfr_odd_p (y) ? -1 : 1, rnd_mode); /* now we have: (1) either x > 0 (2) or x < 0 and y is an integer and in addition |x| <> 1. */ /* detect overflow: an overflow is possible if (a) |x| > 1 and y > 0 (b) |x| < 1 and y < 0. FIXME: this assumes 1 is always representable. FIXME2: maybe we can test overflow and underflow simultaneously. The idea is the following: first compute an approximation to y * log2|x|, using rounding to nearest. If |x| is not too near from 1, this approximation should be accurate enough, and in most cases enable one to prove that there is no underflow nor overflow. Otherwise, it should enable one to check only underflow or overflow, instead of both cases as in the present case. */ /* fast check for cases where no overflow nor underflow is possible: if |y| <= 2^15, and -32767 < EXP(x) <= 32767, then |y*log2(x)| <= 2^15*32767 < 1073741823, thus for the default emax=1073741823 and emin=-emax there can be no overflow nor underflow */ if (__gmpfr_emax >= 1073741823 && __gmpfr_emin <= -1073741823 && MPFR_EXP(y) <= 15 && -32767 < MPFR_EXP(x) && MPFR_EXP(x) <= 32767) goto no_overflow_nor_underflow; if (cmp_x_1 * MPFR_SIGN (y) > 0) { mpfr_t t; int negative, overflow; MPFR_SAVE_EXPO_MARK (expo); mpfr_init2 (t, 53); /* we want a lower bound on y*log2|x|: (i) if x > 0, it suffices to round log2(x) toward zero, and to round y*o(log2(x)) toward zero too; (ii) if x < 0, we first compute t = o(-x), with rounding toward 1, and then follow as in case (1). */ if (MPFR_IS_POS (x)) mpfr_log2 (t, x, MPFR_RNDZ); else { mpfr_neg (t, x, (cmp_x_1 > 0) ? MPFR_RNDZ : MPFR_RNDU); mpfr_log2 (t, t, MPFR_RNDZ); } mpfr_mul (t, t, y, MPFR_RNDZ); overflow = mpfr_cmp_si (t, __gmpfr_emax) > 0; mpfr_clear (t); MPFR_SAVE_EXPO_FREE (expo); if (overflow) { MPFR_LOG_MSG (("early overflow detection\n", 0)); negative = MPFR_IS_NEG (x) && mpfr_odd_p (y); return mpfr_overflow (z, rnd_mode, negative ? -1 : 1); } } /* Basic underflow checking. One has: * - if y > 0, |x^y| < 2^(EXP(x) * y); * - if y < 0, |x^y| <= 2^((EXP(x) - 1) * y); * so that one can compute a value ebound such that |x^y| < 2^ebound. * If we have ebound <= emin - 2 (emin - 1 in directed rounding modes), * then there is an underflow and we can decide the return value. */ if (MPFR_IS_NEG (y) ? (MPFR_GET_EXP (x) > 1) : (MPFR_GET_EXP (x) < 0)) { mp_limb_t tmp_limb[MPFR_EXP_LIMB_SIZE]; mpfr_t tmp; mpfr_eexp_t ebound; int inex2; /* We must restore the flags. */ MPFR_SAVE_EXPO_MARK (expo); MPFR_TMP_INIT1 (tmp_limb, tmp, sizeof (mpfr_exp_t) * CHAR_BIT); inex2 = mpfr_set_exp_t (tmp, MPFR_GET_EXP (x), MPFR_RNDN); MPFR_ASSERTN (inex2 == 0); if (MPFR_IS_NEG (y)) { inex2 = mpfr_sub_ui (tmp, tmp, 1, MPFR_RNDN); MPFR_ASSERTN (inex2 == 0); } mpfr_mul (tmp, tmp, y, MPFR_RNDU); if (MPFR_IS_NEG (y)) mpfr_nextabove (tmp); /* tmp doesn't necessarily fit in ebound, but that doesn't matter since we get the minimum value in such a case. */ ebound = mpfr_get_exp_t (tmp, MPFR_RNDU); MPFR_SAVE_EXPO_FREE (expo); if (MPFR_UNLIKELY (ebound <= __gmpfr_emin - (rnd_mode == MPFR_RNDN ? 2 : 1))) { /* warning: mpfr_underflow rounds away from 0 for MPFR_RNDN */ MPFR_LOG_MSG (("early underflow detection\n", 0)); return mpfr_underflow (z, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode, MPFR_IS_NEG (x) && mpfr_odd_p (y) ? -1 : 1); } } no_overflow_nor_underflow: /* If y is an integer, we can use mpfr_pow_z (based on multiplications), but if y is very large (I'm not sure about the best threshold -- VL), we shouldn't use it, as it can be very slow and take a lot of memory (and even crash or make other programs crash, as several hundred of MBs may be necessary). Note that in such a case, either x = +/-2^b (this case is handled below) or x^y cannot be represented exactly in any precision supported by MPFR (the general case uses this property). */ if (y_is_integer && (MPFR_GET_EXP (y) <= 256)) { mpz_t zi; MPFR_LOG_MSG (("special code for y not too large integer\n", 0)); mpz_init (zi); mpfr_get_z (zi, y, MPFR_RNDN); inexact = mpfr_pow_z (z, x, zi, rnd_mode); mpz_clear (zi); return inexact; } /* Special case (+/-2^b)^Y which could be exact. If x is negative, then necessarily y is a large integer. */ if (mpfr_powerof2_raw (x)) { mpfr_exp_t b = MPFR_GET_EXP (x) - 1; mpfr_t tmp; int sgnx = MPFR_SIGN (x); MPFR_ASSERTN (b >= LONG_MIN && b <= LONG_MAX); /* FIXME... */ MPFR_LOG_MSG (("special case (+/-2^b)^Y\n", 0)); /* now x = +/-2^b, so x^y = (+/-1)^y*2^(b*y) is exact whenever b*y is an integer */ MPFR_SAVE_EXPO_MARK (expo); mpfr_init2 (tmp, MPFR_PREC (y) + sizeof (long) * CHAR_BIT); inexact = mpfr_mul_si (tmp, y, b, MPFR_RNDN); /* exact */ MPFR_ASSERTN (inexact == 0); /* Note: as the exponent range has been extended, an overflow is not possible (due to basic overflow and underflow checking above, as the result is ~ 2^tmp), and an underflow is not possible either because b is an integer (thus either 0 or >= 1). */ MPFR_CLEAR_FLAGS (); inexact = mpfr_exp2 (z, tmp, rnd_mode); mpfr_clear (tmp); if (sgnx < 0 && mpfr_odd_p (y)) { mpfr_neg (z, z, rnd_mode); inexact = -inexact; } /* Without the following, the overflows3 test in tpow.c fails. */ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (z, inexact, rnd_mode); } MPFR_SAVE_EXPO_MARK (expo); /* Case where y * log(x) is very small. Warning: x can be negative, in that case y is a large integer. */ { mpfr_exp_t err, expx, logt; /* We need an upper bound on the exponent of y * log(x). */ if (MPFR_IS_POS(x)) expx = cmp_x_1 > 0 ? MPFR_EXP(x) : 1 - MPFR_EXP(x); else expx = mpfr_cmp_si (x, -1) > 0 ? 1 - MPFR_EXP(x) : MPFR_EXP(x); MPFR_ASSERTD(expx >= 0); /* now |log(x)| < expx */ logt = MPFR_INT_CEIL_LOG2 (expx); /* now expx <= 2^logt */ err = MPFR_GET_EXP (y) + logt; MPFR_CLEAR_FLAGS (); MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (z, __gmpfr_one, - err, 0, (MPFR_IS_POS (y)) ^ (cmp_x_1 < 0), rnd_mode, expo, {}); } /* General case */ inexact = mpfr_pow_general (z, x, y, rnd_mode, y_is_integer, &expo); MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (z, inexact, rnd_mode); }
int mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) { mpfr_t xf; mp_limb_t xf_limb[(53 - 1) / GMP_NUMB_BITS + 1]; int inex, large; MPFR_SAVE_EXPO_DECL (expo); MPFR_LOG_FUNC (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode), ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y, inex)); 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)) /* erf(+inf) = +1, erf(-inf) = -1 */ return mpfr_set_si (y, MPFR_INT_SIGN (x), MPFR_RNDN); else /* erf(+0) = +0, erf(-0) = -0 */ { MPFR_ASSERTD (MPFR_IS_ZERO (x)); return mpfr_set (y, x, MPFR_RNDN); /* should keep the sign of x */ } } /* now x is neither NaN, Inf nor 0 */ /* first try expansion at x=0 when x is small, or asymptotic expansion where x is large */ MPFR_SAVE_EXPO_MARK (expo); /* around x=0, we have erf(x) = 2x/sqrt(Pi) (1 - x^2/3 + ...), with 1 - x^2/3 <= sqrt(Pi)*erf(x)/2/x <= 1 for x >= 0. This means that if x^2/3 < 2^(-PREC(y)-1) we can decide of the correct rounding, unless we have a worst-case for 2x/sqrt(Pi). */ if (MPFR_EXP(x) < - (mpfr_exp_t) (MPFR_PREC(y) / 2)) { /* we use 2x/sqrt(Pi) (1 - x^2/3) <= erf(x) <= 2x/sqrt(Pi) for x > 0 and 2x/sqrt(Pi) <= erf(x) <= 2x/sqrt(Pi) (1 - x^2/3) for x < 0. In both cases |2x/sqrt(Pi) (1 - x^2/3)| <= |erf(x)| <= |2x/sqrt(Pi)|. We will compute l and h such that l <= |2x/sqrt(Pi) (1 - x^2/3)| and |2x/sqrt(Pi)| <= h. If l and h round to the same value to precision PREC(y) and rounding rnd_mode, then we are done. */ mpfr_t l, h; /* lower and upper bounds for erf(x) */ int ok, inex2; mpfr_init2 (l, MPFR_PREC(y) + 17); mpfr_init2 (h, MPFR_PREC(y) + 17); /* first compute l */ mpfr_mul (l, x, x, MPFR_RNDU); mpfr_div_ui (l, l, 3, MPFR_RNDU); /* upper bound on x^2/3 */ mpfr_ui_sub (l, 1, l, MPFR_RNDZ); /* lower bound on 1 - x^2/3 */ mpfr_const_pi (h, MPFR_RNDU); /* upper bound of Pi */ mpfr_sqrt (h, h, MPFR_RNDU); /* upper bound on sqrt(Pi) */ mpfr_div (l, l, h, MPFR_RNDZ); /* lower bound on 1/sqrt(Pi) (1 - x^2/3) */ mpfr_mul_2ui (l, l, 1, MPFR_RNDZ); /* 2/sqrt(Pi) (1 - x^2/3) */ mpfr_mul (l, l, x, MPFR_RNDZ); /* |l| is a lower bound on |2x/sqrt(Pi) (1 - x^2/3)| */ /* now compute h */ mpfr_const_pi (h, MPFR_RNDD); /* lower bound on Pi */ mpfr_sqrt (h, h, MPFR_RNDD); /* lower bound on sqrt(Pi) */ mpfr_div_2ui (h, h, 1, MPFR_RNDD); /* lower bound on sqrt(Pi)/2 */ /* since sqrt(Pi)/2 < 1, the following should not underflow */ mpfr_div (h, x, h, MPFR_IS_POS(x) ? MPFR_RNDU : MPFR_RNDD); /* round l and h to precision PREC(y) */ inex = mpfr_prec_round (l, MPFR_PREC(y), rnd_mode); inex2 = mpfr_prec_round (h, MPFR_PREC(y), rnd_mode); /* Caution: we also need inex=inex2 (inex might be 0). */ ok = SAME_SIGN (inex, inex2) && mpfr_cmp (l, h) == 0; if (ok) mpfr_set (y, h, rnd_mode); mpfr_clear (l); mpfr_clear (h); if (ok) goto end; /* this test can still fail for small precision, for example for x=-0.100E-2 with a target precision of 3 bits, since the error term x^2/3 is not that small. */ } MPFR_TMP_INIT1(xf_limb, xf, 53); mpfr_div (xf, x, __gmpfr_const_log2_RNDU, MPFR_RNDZ); /* round to zero ensures we get a lower bound of |x/log(2)| */ mpfr_mul (xf, xf, x, MPFR_RNDZ); large = mpfr_cmp_ui (xf, MPFR_PREC (y) + 1) > 0; /* when x goes to infinity, we have erf(x) = 1 - 1/sqrt(Pi)/exp(x^2)/x + ... and |erf(x) - 1| <= exp(-x^2) is true for any x >= 0, thus if exp(-x^2) < 2^(-PREC(y)-1) the result is 1 or 1-epsilon. This rewrites as x^2/log(2) > p+1. */ if (MPFR_UNLIKELY (large)) /* |erf x| = 1 or 1- */ { mpfr_rnd_t rnd2 = MPFR_IS_POS (x) ? rnd_mode : MPFR_INVERT_RND(rnd_mode); if (rnd2 == MPFR_RNDN || rnd2 == MPFR_RNDU || rnd2 == MPFR_RNDA) { inex = MPFR_INT_SIGN (x); mpfr_set_si (y, inex, rnd2); } else /* round to zero */ { inex = -MPFR_INT_SIGN (x); mpfr_setmax (y, 0); /* warning: setmax keeps the old sign of y */ MPFR_SET_SAME_SIGN (y, x); } } else /* use Taylor */ { double xf2; /* FIXME: get rid of doubles/mpfr_get_d here */ xf2 = mpfr_get_d (x, MPFR_RNDN); xf2 = xf2 * xf2; /* xf2 ~ x^2 */ inex = mpfr_erf_0 (y, x, xf2, rnd_mode); } end: MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (y, inex, rnd_mode); }
static void check_cmp(int argc, char *argv[]) { mpfr_t x, y; int n, k, rnd; mpfr_inits2 (53, x, y, (void *) 0); mpfr_set_ui(x, 1, GMP_RNDN); (mpfr_abs) (x, x, GMP_RNDN); if (mpfr_cmp_ui (x, 1)) { printf ("Error in mpfr_abs(1.0)\n"); exit (1); } mpfr_set_si(x, -1, GMP_RNDN); mpfr_abs(x, x, GMP_RNDN); if (mpfr_cmp_ui (x, 1)) { printf ("Error in mpfr_abs(1.0)\n"); exit (1); } mpfr_set_si(x, -1, GMP_RNDN); mpfr_abs(x, x, GMP_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, GMP_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, GMP_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, GMP_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++) { int sign = SIGN_RAND(); mpfr_random(x); MPFR_SET_SIGN(x, sign); rnd = RND_RAND(); mpfr_abs(y, x, (mp_rnd_t) 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, (void *) 0); }
/* With N = 2 * GMP_NUMB_BITS: i * 2^N + j + k * 2^(-1) + f1 * 2^(-N) + f2 * 2^(-N), with i = -1 or 1, j = 0 or i, -1 <= k <= 1, -1 <= f1 <= 1, -1 <= f2 <= 1 ulp(exact sum) = 2^0. */ static void check2 (void) { mpfr_t sum1, sum2, s1, s2, s3, s4, t[5]; mpfr_ptr p[5]; int i, j, k, f1, f2, prec, r, inex1, inex2; #define N (2 * GMP_NUMB_BITS) mpfr_init2 (sum1, N+1); mpfr_init2 (sum2, N+1); mpfr_init2 (s1, N+1); mpfr_init2 (s2, N+2); mpfr_init2 (s3, 2*N+1); mpfr_init2 (s4, 2*N+1); for (i = 0; i < 5; i++) { mpfr_init2 (t[i], 2); p[i] = t[i]; } for (i = -1; i <= 1; i += 2) { mpfr_set_si_2exp (t[0], i, N, MPFR_RNDN); for (j = 0; j != 2*i; j += i) { mpfr_set_si (t[1], j, MPFR_RNDN); inex1 = mpfr_add (s1, t[0], t[1], MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); for (k = -1; k <= 1; k++) { mpfr_set_si_2exp (t[2], k, -1, MPFR_RNDN); inex1 = mpfr_add (s2, s1, t[2], MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); for (f1 = -1; f1 <= 1; f1++) { mpfr_set_si_2exp (t[3], f1, -N, MPFR_RNDN); inex1 = mpfr_add (s3, s2, t[3], MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); for (f2 = -1; f2 <= 1; f2++) { mpfr_set_si_2exp (t[4], f2, -N, MPFR_RNDN); inex1 = mpfr_add (s4, s3, t[4], MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); prec = mpfr_get_exp (s4); mpfr_set_prec (sum1, prec); mpfr_set_prec (sum2, prec); RND_LOOP (r) { inex1 = mpfr_set (sum1, s4, (mpfr_rnd_t) r); inex2 = mpfr_sum (sum2, p, 5, (mpfr_rnd_t) r); MPFR_ASSERTN (mpfr_check (sum1)); MPFR_ASSERTN (mpfr_check (sum2)); if (!(mpfr_equal_p (sum1, sum2) && SAME_SIGN (inex1, inex2))) { printf ("Error in check2 on %s, prec = %d, " "i = %d, j = %d, k = %d, f1 = %d, " "f2 = %d\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), prec, i, j, k, f1, f2); printf ("Expected "); mpfr_dump (sum1); printf ("with inex = %d\n", inex1); printf ("Got "); mpfr_dump (sum2); printf ("with inex = %d\n", inex2); exit (1); } } } } } } } for (i = 0; i < 5; i++) mpfr_clear (t[i]); mpfr_clears (sum1, sum2, s1, s2, s3, s4, (mpfr_ptr) 0); }
static void special (void) { mpfr_t x, y; int inex; int sign; mpfr_exp_t emin, emax; mpfr_init (x); mpfr_init (y); mpfr_set_nan (x); mpfr_lgamma (y, &sign, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error for lgamma(NaN)\n"); exit (1); } mpfr_set_inf (x, -1); mpfr_lgamma (y, &sign, x, MPFR_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, MPFR_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, MPFR_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, MPFR_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, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, MPFR_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, MPFR_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, MPFR_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, MPFR_RNDN); mpfr_lgamma (y, &sign, x, MPFR_RNDN); if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) { printf ("Error for lgamma(-1)\n"); exit (1); } mpfr_set_ui (x, 2, MPFR_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, MPFR_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, MPFR_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, MPFR_RNDN); mpfr_set_str (x, CHECK_Y1, 10, MPFR_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, MPFR_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, MPFR_RNDN); mpfr_set_str (x, CHECK_Y2, 10, MPFR_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, MPFR_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, MPFR_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, MPFR_RNDN); sign = -17; mpfr_lgamma (x, &sign, y, MPFR_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, MPFR_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, MPFR_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, MPFR_RNDN); mpfr_add_ui (x, x, 1, MPFR_RNDN); mpfr_div_2ui (x, x, 1, MPFR_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, MPFR_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, MPFR_RNDN); mpfr_sub_ui (x, x, 1, MPFR_RNDN); mpfr_div_2ui (x, x, 1, MPFR_RNDN); sign = -17; mpfr_lgamma (y, &sign, x, MPFR_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, MPFR_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, MPFR_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, MPFR_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, MPFR_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, MPFR_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, MPFR_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, MPFR_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, MPFR_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, MPFR_RNDN); mpfr_set_str_binary (x, "100101.00111101101010000000101010111010001111001101111"); MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); /* bug found by Kevin Rauch on 26 Oct 2007 */ emin = mpfr_get_emin (); emax = mpfr_get_emax (); mpfr_set_emin (-1000000000); mpfr_set_emax (1000000000); mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_lgamma (x, &sign, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_get_emin () == -1000000000); MPFR_ASSERTN(mpfr_get_emax () == 1000000000); mpfr_set_emin (emin); mpfr_set_emax (emax); /* two other bugs reported by Kevin Rauch on 27 Oct 2007 */ mpfr_set_prec (x, 128); mpfr_set_prec (y, 128); mpfr_set_str_binary (x, "0.11000110011110111111110010100110000000000000000000000000000000000000000000000000000000000000000001000011000110100100110111101010E-765689"); inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN); mpfr_set_str_binary (x, "10000001100100101111011011010000111010001001110000111010011000101001011111011111110011011010110100101111110111001001010100011101E-108"); MPFR_ASSERTN(inex < 0 && mpfr_cmp (y, x) == 0 && sign > 0); mpfr_set_prec (x, 128); mpfr_set_prec (y, 256); mpfr_set_str_binary (x, "0.1011111111111111100000111011111E-31871"); inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN); mpfr_set_prec (x, 256); mpfr_set_str (x, "AC9729B83707E6797612D0D76DAF42B1240A677FF1B6E3783FD4E53037143B1P-237", 16, MPFR_RNDN); MPFR_ASSERTN(inex < 0 && mpfr_cmp (y, x) == 0 && sign > 0); mpfr_clear (x); mpfr_clear (y); }
number::number(int v) { number_base *d = new number_base; int r = mpfr_set_si(d->val, v, GMP_RNDN); assert(r == 0); (void)r; data = d; }