static void test1 (void) { mpfr_t x, y, z, a; int res1, res2; mpfr_init2 (x, 32); mpfr_init2 (y, 65); mpfr_init2 (z, 17); mpfr_init2 (a, 17); mpfr_set_str_binary (x, "-0.101110001001011011011e-9"); mpfr_ui_pow (y, 7, x, MPFR_RNDN); mpfr_set_prec (x, 40); mpfr_set_str_binary (x, "-0.1100101100101111011001010010110011110110E-1"); mpfr_set_prec (y, 74); mpfr_ui_pow (y, 8, x, MPFR_RNDN); mpfr_set_prec (x, 74); mpfr_set_str_binary (x, "0.11100000010100111101000011111011011010011000011000101011010011010101000011E-1"); if (mpfr_cmp (x, y)) { printf ("Error for input of 40 bits, output of 74 bits\n"); exit (1); } /* Check for ui_pow_ui */ mpfr_ui_pow_ui (x, 0, 1, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS (x)); mpfr_ui_pow_ui (x, 0, 4, MPFR_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS (x)); res1 = mpfr_ui_pow_ui (z, 17, 42, MPFR_RNDD); mpfr_set_ui (x, 17, MPFR_RNDN); mpfr_set_ui (y, 42, MPFR_RNDN); res2 = mpfr_pow (a, x, y, MPFR_RNDD); if (mpfr_cmp (z, a) || res1 != res2) { printf ("Error for ui_pow_ui for 17^42\n" "Inexact1 = %d Inexact2 = %d\n", res1, res2); mpfr_dump (z); mpfr_dump (a); exit (1); } mpfr_set_prec (x, 2); mpfr_ui_pow_ui (x, 65537, 65535, MPFR_RNDN); if (mpfr_cmp_str (x, "0.11E1048562", 2, MPFR_RNDN) != 0) { printf ("Error for ui_pow_ui for 65537 ^65535 with 2 bits of precision\n"); mpfr_dump (x); exit (1); } mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); mpfr_clear (a); }
/* Input: s - a floating-point number n - an integer Output: sum - a floating-point number approximating sum(1/i^s, i=1..n-1) */ static void mpfr_zeta_part_a (mpfr_t sum, mpfr_srcptr s, int n) { mpfr_t u, s1; int i; MPFR_GROUP_DECL (group); MPFR_GROUP_INIT_2 (group, MPFR_PREC (sum), u, s1); mpfr_neg (s1, s, GMP_RNDN); mpfr_ui_pow (u, n, s1, GMP_RNDN); mpfr_div_2ui (u, u, 1, GMP_RNDN); mpfr_set (sum, u, GMP_RNDN); for (i=n-1; i>1; i--) { mpfr_ui_pow (u, i, s1, GMP_RNDN); mpfr_add (sum, sum, u, GMP_RNDN); } mpfr_add (sum, sum, __gmpfr_one, GMP_RNDN); MPFR_GROUP_CLEAR (group); }
/* Parameters: s - the input floating-point number n, p - parameters from the algorithm tc - an array of p floating-point numbers tc[1]..tc[p] Output: b is the result, i.e. sum(tc[i]*product((s+2j)*(s+2j-1)/n^2,j=1..i-1), i=1..p)*s*n^(-s-1) */ static void mpfr_zeta_part_b (mpfr_t b, mpfr_srcptr s, int n, int p, mpfr_t *tc) { mpfr_t s1, d, u; unsigned long n2; int l, t; MPFR_GROUP_DECL (group); if (p == 0) { MPFR_SET_ZERO (b); MPFR_SET_POS (b); return; } n2 = n * n; MPFR_GROUP_INIT_3 (group, MPFR_PREC (b), s1, d, u); /* t equals 2p-2, 2p-3, ... ; s1 equals s+t */ t = 2 * p - 2; mpfr_set (d, tc[p], GMP_RNDN); for (l = 1; l < p; l++) { mpfr_add_ui (s1, s, t, GMP_RNDN); /* s + (2p-2l) */ mpfr_mul (d, d, s1, GMP_RNDN); t = t - 1; mpfr_add_ui (s1, s, t, GMP_RNDN); /* s + (2p-2l-1) */ mpfr_mul (d, d, s1, GMP_RNDN); t = t - 1; mpfr_div_ui (d, d, n2, GMP_RNDN); mpfr_add (d, d, tc[p-l], GMP_RNDN); /* since s is positive and the tc[i] have alternate signs, the following is unlikely */ if (MPFR_UNLIKELY (mpfr_cmpabs (d, tc[p-l]) > 0)) mpfr_set (d, tc[p-l], GMP_RNDN); } mpfr_mul (d, d, s, GMP_RNDN); mpfr_add (s1, s, __gmpfr_one, GMP_RNDN); mpfr_neg (s1, s1, GMP_RNDN); mpfr_ui_pow (u, n, s1, GMP_RNDN); mpfr_mul (b, d, u, GMP_RNDN); MPFR_GROUP_CLEAR (group); }
static void check1 (mpfr_ptr x, mpfr_prec_t prec, unsigned long nt, mpfr_rnd_t rnd) { mpfr_t y, z, t; int inexact, compare, compare2; mpfr_prec_t yprec; mpfr_exp_t err; yprec = prec + 10; mpfr_init (y); mpfr_init (z); mpfr_init (t); mpfr_set_prec (y, yprec); mpfr_set_prec (z, prec); mpfr_set_prec (t, prec); compare = mpfr_ui_pow (y, nt, x, rnd); err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec; if (mpfr_can_round (y, err, rnd, rnd, prec)) { mpfr_set (t, y, rnd); inexact = mpfr_ui_pow (z, nt, x, rnd); if (mpfr_cmp (t, z)) { printf ("results differ for x="); mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); printf (" n=%lu", nt); printf (" prec=%u rnd_mode=%s\n", (unsigned) prec, mpfr_print_rnd_mode (rnd)); printf ("got "); mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); puts (""); printf ("expected "); mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); puts (""); printf ("approx "); mpfr_print_binary (y); puts (""); exit (1); } compare2 = mpfr_cmp (t, y); /* if rounding to nearest, cannot know the sign of t - f(x) because of composed rounding: y = o(f(x)) and t = o(y) */ if ((rnd != MPFR_RNDN) && (compare * compare2 >= 0)) compare = compare + compare2; else compare = inexact; /* cannot determine sign(t-f(x)) */ if (((inexact == 0) && (compare != 0)) || ((inexact > 0) && (compare <= 0)) || ((inexact < 0) && (compare >= 0))) { printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n", mpfr_print_rnd_mode (rnd), compare, inexact); printf ("x="); mpfr_print_binary (x); puts (""); printf ("y="); mpfr_print_binary (y); puts (""); printf ("t="); mpfr_print_binary (t); puts (""); exit (1); } } mpfr_clear (y); mpfr_clear (z); mpfr_clear (t); }
int main (int argc, char *argv[]) { mpfr_t x, y; unsigned long int n; tests_start_mpfr (); mpfr_init (x); mpfr_init (y); n = randlimb (); MPFR_SET_INF(x); mpfr_ui_pow (y, n, 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_ui_pow (y, n, x, MPFR_RNDN); if(!MPFR_IS_ZERO(y)) { printf ("evaluation of function in -INF does not return 0"); exit (1); } MPFR_SET_NAN(x); mpfr_ui_pow (y, n, x, MPFR_RNDN); if(!MPFR_IS_NAN(y)) { printf ("evaluation of function in NAN does not return NAN"); exit (1); } test1 (); { mpfr_t z, t; mpfr_prec_t prec; mpfr_rnd_t rnd; unsigned int n; mpfr_prec_t p0=2, p1=100; unsigned int N=20; mpfr_init2 (z, 38); mpfr_init2 (t, 6); /* check exact power */ mpfr_set_str_binary (t, "0.110000E5"); mpfr_ui_pow (z, 3, t, MPFR_RNDN); mpfr_set_prec (x, 2); mpfr_set_prec (y, 2); mpfr_set_str (x, "-0.5", 10, MPFR_RNDZ); mpfr_ui_pow (y, 4, x, MPFR_RNDD); if (mpfr_cmp_ui_2exp(y, 1, -1)) { fprintf (stderr, "Error for 4^(-0.5), prec=2, MPFR_RNDD\n"); fprintf (stderr, "expected 0.5, got "); mpfr_out_str (stderr, 2, 0, y, MPFR_RNDN); fprintf (stderr, "\n"); exit (1); } /* problem found by Kevin on spe175.testdrive.compaq.com (03 Sep 2003), ia64 under HP-UX */ mpfr_set_prec (x, 2); mpfr_set_prec (y, 2); mpfr_set_str (x, "0.5", 10, MPFR_RNDN); mpfr_ui_pow (y, 398441521, x, MPFR_RNDN); if (mpfr_cmp_ui_2exp(y, 1, 14)) { fprintf (stderr, "Error for 398441521^(0.5), prec=2, MPFR_RNDN\n"); fprintf (stderr, "expected 1.0e14, got "); mpfr_out_str (stderr, 2, 0, y, MPFR_RNDN); fprintf (stderr, "\n"); exit (1); } mpfr_clear (z); mpfr_clear (t); mpfr_set_prec (x, 2); mpfr_set_str (x, "0.5", 10, MPFR_RNDN); check1 (x, 2, 398441521, MPFR_RNDN); /* 398441521 = 19961^2 */ /* generic test */ for (prec = p0; prec <= p1; prec++) { mpfr_set_prec (x, prec); for (n=0; n<N; n++) { int nt; nt = randlimb () & INT_MAX; mpfr_urandomb (x, RANDS); rnd = RND_RAND (); check1 (x, prec, nt, rnd); } } } mpfr_clear (x); mpfr_clear (y); tests_end_mpfr (); return 0; }
/* Input: s - a floating-point number >= 1/2. rnd_mode - a rounding mode. Assumes s is neither NaN nor Infinite. Output: z - Zeta(s) rounded to the precision of z with direction rnd_mode */ static int mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode) { mpfr_t b, c, z_pre, f, s1; double beta, sd, dnep; mpfr_t *tc1; mp_prec_t precz, precs, d, dint; int p, n, l, add; int inex; MPFR_GROUP_DECL (group); MPFR_ZIV_DECL (loop); MPFR_ASSERTD (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0); precz = MPFR_PREC (z); precs = MPFR_PREC (s); /* Zeta(x) = 1+1/2^x+1/3^x+1/4^x+1/5^x+O(1/6^x) so with 2^(EXP(x)-1) <= x < 2^EXP(x) So for x > 2^3, k^x > k^8, so 2/k^x < 2/k^8 Zeta(x) = 1 + 1/2^x*(1+(2/3)^x+(2/4)^x+...) = 1 + 1/2^x*(1+sum((2/k)^x,k=3..infinity)) <= 1 + 1/2^x*(1+sum((2/k)^8,k=3..infinity)) And sum((2/k)^8,k=3..infinity) = -257+128*Pi^8/4725 ~= 0.0438035 So Zeta(x) <= 1 + 1/2^x*2 for x >= 8 The error is < 2^(-x+1) <= 2^(-2^(EXP(x)-1)+1) */ if (MPFR_GET_EXP (s) > 3) { mp_exp_t err; err = MPFR_GET_EXP (s) - 1; if (err > (mp_exp_t) (sizeof (mp_exp_t)*CHAR_BIT-2)) err = MPFR_EMAX_MAX; else err = ((mp_exp_t)1) << err; err = 1 - (-err+1); /* GET_EXP(one) - (-err+1) = err :) */ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, err, 0, 1, rnd_mode, {}); } d = precz + MPFR_INT_CEIL_LOG2(precz) + 10; /* we want that s1 = s-1 is exact, i.e. we should have PREC(s1) >= EXP(s) */ dint = (mpfr_uexp_t) MPFR_GET_EXP (s); mpfr_init2 (s1, MAX (precs, dint)); inex = mpfr_sub (s1, s, __gmpfr_one, GMP_RNDN); MPFR_ASSERTD (inex == 0); /* case s=1 */ if (MPFR_IS_ZERO (s1)) { MPFR_SET_INF (z); MPFR_SET_POS (z); MPFR_ASSERTD (inex == 0); goto clear_and_return; } MPFR_GROUP_INIT_4 (group, MPFR_PREC_MIN, b, c, z_pre, f); MPFR_ZIV_INIT (loop, d); for (;;) { /* Principal loop: we compute, in z_pre, an approximation of Zeta(s), that we send to can_round */ if (MPFR_GET_EXP (s1) <= -(mp_exp_t) ((mpfr_prec_t) (d-3)/2)) /* Branch 1: when s-1 is very small, one uses the approximation Zeta(s)=1/(s-1)+gamma, where gamma is Euler's constant */ { dint = MAX (d + 3, precs); MPFR_TRACE (printf ("branch 1\ninternal precision=%d\n", dint)); MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f); mpfr_div (z_pre, __gmpfr_one, s1, GMP_RNDN); mpfr_const_euler (f, GMP_RNDN); mpfr_add (z_pre, z_pre, f, GMP_RNDN); } else /* Branch 2 */ { size_t size; MPFR_TRACE (printf ("branch 2\n")); /* Computation of parameters n, p and working precision */ dnep = (double) d * LOG2; sd = mpfr_get_d (s, GMP_RNDN); /* beta = dnep + 0.61 + sd * log (6.2832 / sd); but a larger value is ok */ #define LOG6dot2832 1.83787940484160805532 beta = dnep + 0.61 + sd * (LOG6dot2832 - LOG2 * __gmpfr_floor_log2 (sd)); if (beta <= 0.0) { p = 0; /* n = 1 + (int) (exp ((dnep - LOG2) / sd)); */ n = 1 + (int) __gmpfr_ceil_exp2 ((d - 1.0) / sd); } else { p = 1 + (int) beta / 2; n = 1 + (int) ((sd + 2.0 * (double) p - 1.0) / 6.2832); } MPFR_TRACE (printf ("\nn=%d\np=%d\n",n,p)); /* add = 4 + floor(1.5 * log(d) / log (2)). We should have add >= 10, which is always fulfilled since d = precz + 11 >= 12, thus ceil(log2(d)) >= 4 */ add = 4 + (3 * MPFR_INT_CEIL_LOG2 (d)) / 2; MPFR_ASSERTD(add >= 10); dint = d + add; if (dint < precs) dint = precs; MPFR_TRACE (printf("internal precision=%d\n",dint)); size = (p + 1) * sizeof(mpfr_t); tc1 = (mpfr_t*) (*__gmp_allocate_func) (size); for (l=1; l<=p; l++) mpfr_init2 (tc1[l], dint); MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f); MPFR_TRACE (printf ("precision of z =%d\n", precz)); /* Computation of the coefficients c_k */ mpfr_zeta_c (p, tc1); /* Computation of the 3 parts of the fonction Zeta. */ mpfr_zeta_part_a (z_pre, s, n); mpfr_zeta_part_b (b, s, n, p, tc1); /* s1 = s-1 is already computed above */ mpfr_div (c, __gmpfr_one, s1, GMP_RNDN); mpfr_ui_pow (f, n, s1, GMP_RNDN); mpfr_div (c, c, f, GMP_RNDN); MPFR_TRACE (MPFR_DUMP (c)); mpfr_add (z_pre, z_pre, c, GMP_RNDN); mpfr_add (z_pre, z_pre, b, GMP_RNDN); for (l=1; l<=p; l++) mpfr_clear (tc1[l]); (*__gmp_free_func) (tc1, size); /* End branch 2 */ } MPFR_TRACE (MPFR_DUMP (z_pre)); if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, d-3, precz, rnd_mode))) break; MPFR_ZIV_NEXT (loop, d); } MPFR_ZIV_FREE (loop); inex = mpfr_set (z, z_pre, rnd_mode); MPFR_GROUP_CLEAR (group); clear_and_return: mpfr_clear (s1); return inex; }
/* Compare the result (z1,inex1) of mpfr_pow with all flags cleared with those of mpfr_pow with all flags set and of the other power functions. Arguments x and y are the input values; sx and sy are their string representations (sx may be null); rnd contains the rounding mode; s is a string containing the function that called test_others. */ static void test_others (const void *sx, const char *sy, mpfr_rnd_t rnd, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z1, int inex1, unsigned int flags, const char *s) { mpfr_t z2; int inex2; int spx = sx != NULL; if (!spx) sx = x; mpfr_init2 (z2, mpfr_get_prec (z1)); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_pow (z2, x, y, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_pow, flags set"); /* If y is an integer that fits in an unsigned long and is not -0, we can test mpfr_pow_ui. */ if (MPFR_IS_POS (y) && mpfr_integer_p (y) && mpfr_fits_ulong_p (y, MPFR_RNDN)) { unsigned long yy = mpfr_get_ui (y, MPFR_RNDN); mpfr_clear_flags (); inex2 = mpfr_pow_ui (z2, x, yy, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_pow_ui, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_pow_ui (z2, x, yy, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_pow_ui, flags set"); /* If x is an integer that fits in an unsigned long and is not -0, we can also test mpfr_ui_pow_ui. */ if (MPFR_IS_POS (x) && mpfr_integer_p (x) && mpfr_fits_ulong_p (x, MPFR_RNDN)) { unsigned long xx = mpfr_get_ui (x, MPFR_RNDN); mpfr_clear_flags (); inex2 = mpfr_ui_pow_ui (z2, xx, yy, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_ui_pow_ui, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_ui_pow_ui (z2, xx, yy, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_ui_pow_ui, flags set"); } } /* If y is an integer but not -0 and not huge, we can test mpfr_pow_z, and possibly mpfr_pow_si (and possibly mpfr_ui_div). */ if (MPFR_IS_ZERO (y) ? MPFR_IS_POS (y) : (mpfr_integer_p (y) && MPFR_GET_EXP (y) < 256)) { mpz_t yyy; /* If y fits in a long, we can test mpfr_pow_si. */ if (mpfr_fits_slong_p (y, MPFR_RNDN)) { long yy = mpfr_get_si (y, MPFR_RNDN); mpfr_clear_flags (); inex2 = mpfr_pow_si (z2, x, yy, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_pow_si, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_pow_si (z2, x, yy, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_pow_si, flags set"); /* If y = -1, we can test mpfr_ui_div. */ if (yy == -1) { mpfr_clear_flags (); inex2 = mpfr_ui_div (z2, 1, x, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_ui_div, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_ui_div (z2, 1, x, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_ui_div, flags set"); } /* If y = 2, we can test mpfr_sqr. */ if (yy == 2) { mpfr_clear_flags (); inex2 = mpfr_sqr (z2, x, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_sqr, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_sqr (z2, x, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_sqr, flags set"); } } /* Test mpfr_pow_z. */ mpz_init (yyy); mpfr_get_z (yyy, y, MPFR_RNDN); mpfr_clear_flags (); inex2 = mpfr_pow_z (z2, x, yyy, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_pow_z, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_pow_z (z2, x, yyy, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_pow_z, flags set"); mpz_clear (yyy); } /* If y = 0.5, we can test mpfr_sqrt, except if x is -0 or -Inf (because the rule for mpfr_pow on these special values is different). */ if (MPFR_IS_PURE_FP (y) && mpfr_cmp_str1 (y, "0.5") == 0 && ! ((MPFR_IS_ZERO (x) || MPFR_IS_INF (x)) && MPFR_IS_NEG (x))) { mpfr_clear_flags (); inex2 = mpfr_sqrt (z2, x, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_sqrt, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_sqrt (z2, x, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_sqrt, flags set"); } #if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) /* If y = -0.5, we can test mpfr_rec_sqrt, except if x = -Inf (because the rule for mpfr_pow on -Inf is different). */ if (MPFR_IS_PURE_FP (y) && mpfr_cmp_str1 (y, "-0.5") == 0 && ! (MPFR_IS_INF (x) && MPFR_IS_NEG (x))) { mpfr_clear_flags (); inex2 = mpfr_rec_sqrt (z2, x, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_rec_sqrt, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_rec_sqrt (z2, x, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_rec_sqrt, flags set"); } #endif /* If x is an integer that fits in an unsigned long and is not -0, we can test mpfr_ui_pow. */ if (MPFR_IS_POS (x) && mpfr_integer_p (x) && mpfr_fits_ulong_p (x, MPFR_RNDN)) { unsigned long xx = mpfr_get_ui (x, MPFR_RNDN); mpfr_clear_flags (); inex2 = mpfr_ui_pow (z2, xx, y, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_ui_pow, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_ui_pow (z2, xx, y, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_ui_pow, flags set"); /* If x = 2, we can test mpfr_exp2. */ if (xx == 2) { mpfr_clear_flags (); inex2 = mpfr_exp2 (z2, y, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_exp2, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_exp2 (z2, y, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_exp2, flags set"); } /* If x = 10, we can test mpfr_exp10. */ if (xx == 10) { mpfr_clear_flags (); inex2 = mpfr_exp10 (z2, y, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, s, "mpfr_exp10, flags cleared"); __gmpfr_flags = MPFR_FLAGS_ALL; inex2 = mpfr_exp10 (z2, y, rnd); cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, s, "mpfr_exp10, flags set"); } } mpfr_clear (z2); }
int mpfr_exp10 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) { return mpfr_ui_pow (y, 10, x, rnd_mode); }
SeedValue seed_mpfr_pow (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException * exception) { mpfr_rnd_t rnd; mpfr_ptr rop, op1, op2; gint ret; glong iop; gulong uiop1, uiop2; seed_mpfr_t argt1, argt2; /* only want 1 double argument. alternatively, could accept 2, add those, and set from the result*/ CHECK_ARG_COUNT("mpfr.pow", 3); rop = seed_object_get_private(this_object); rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception); argt1 = seed_mpfr_arg_type(ctx, args[0], exception); argt2 = seed_mpfr_arg_type(ctx, args[1], exception); if ( (argt1 & argt2) == SEED_MPFR_MPFR ) { /* both mpfr_t */ op1 = seed_object_get_private(args[0]); op2 = seed_object_get_private(args[1]); ret = mpfr_pow(rop, op1, op2, rnd); } else if ( (argt1 | argt2) == (SEED_MPFR_MPFR | SEED_MPFR_DOUBLE) ) { /* a double and an mpfr_t. Figure out the order */ /* FIXME: is this switching ui and si bad? si_pow doesn't exist, and it's all from double anyway */ if ( argt1 == SEED_MPFR_MPFR ) { op1 = seed_object_get_private(args[0]); iop = seed_value_to_long(ctx, args[1], exception); ret = mpfr_pow_si(rop, op1, iop, rnd); } else { uiop1 = seed_value_to_ulong(ctx, args[0], exception); op2 = seed_object_get_private(args[1]); ret = mpfr_ui_pow(rop, uiop1, op2, rnd); } } else if ( (argt1 & argt2) == SEED_MPFR_DOUBLE ) { /* pretend both ui */ uiop1 = seed_value_to_ulong(ctx, args[0], exception); uiop2 = seed_value_to_ulong(ctx, args[1], exception); ret = mpfr_ui_pow_ui(rop, uiop1, uiop2, rnd); } else { TYPE_EXCEPTION("mpfr.pow", "int or unsigned int and mpfr_t"); } return seed_value_from_int(ctx, ret, exception); }