summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2003-10-14 11:49:06 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2003-10-14 11:49:06 +0000
commit1fa2277c10582baa8b8402b8cf1702116ccbc560 (patch)
tree672209195ecad922dc489260098588b4dca469ad
parent51aef80e83eaf2fc76dd6be59c0549e890dccd2b (diff)
downloadmpfr-1fa2277c10582baa8b8402b8cf1702116ccbc560.tar.gz
replaced mpfr_can_round (approx, err, rnd1, GMP_RNDN, prec)
by mpfr_can_round (approx, err, rnd1, GMP_RNDZ, prec + 1) which in addition guarantees a correct inexact flag git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2492 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--acos.c3
-rw-r--r--acosh.c3
-rw-r--r--agm.c7
-rw-r--r--asin.c3
-rw-r--r--asinh.c3
-rw-r--r--atan.c6
-rw-r--r--atanh.c7
-rw-r--r--const_euler.c8
-rw-r--r--const_log2.c26
-rw-r--r--const_pi.c35
-rw-r--r--cos.c2
-rw-r--r--cosh.c56
-rw-r--r--erf.c13
-rw-r--r--exp2.c29
-rw-r--r--expm1.c9
-rw-r--r--factorial.c12
-rw-r--r--gamma.c10
-rw-r--r--hypot.c3
-rw-r--r--log.c13
-rw-r--r--log10.c3
-rw-r--r--log1p.c38
-rw-r--r--log2.c42
-rw-r--r--pow.c3
-rw-r--r--pow_si.c21
-rw-r--r--pow_ui.c25
-rw-r--r--sin.c3
-rw-r--r--sinh.c52
-rw-r--r--sqrt.c2
-rw-r--r--tan.c3
-rw-r--r--tanh.c59
-rw-r--r--ui_pow_ui.c4
-rw-r--r--zeta.c23
32 files changed, 298 insertions, 228 deletions
diff --git a/acos.c b/acos.c
index 1210f2c49..093734b65 100644
--- a/acos.c
+++ b/acos.c
@@ -108,7 +108,8 @@ mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_div_2ui (tmp, tmp, 1, GMP_RNDN);
mpfr_sub (arcc, tmp, arcc, GMP_RNDN);
- if (mpfr_can_round (arcc, realprec, GMP_RNDN, rnd_mode, MPFR_PREC(acos)))
+ if (mpfr_can_round (arcc, realprec, GMP_RNDN, GMP_RNDZ,
+ MPFR_PREC(acos) + (rnd_mode == GMP_RNDN)))
{
inexact = mpfr_set (acos, arcc, rnd_mode);
good = 1;
diff --git a/acosh.c b/acosh.c
index 5a1c83404..20539a81f 100644
--- a/acosh.c
+++ b/acosh.c
@@ -108,7 +108,8 @@ mpfr_acosh (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode)
/* actualisation of the precision */
Nt += 10;
}
- while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ny));
+ while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN)));
inexact = mpfr_set (y, t, rnd_mode);
diff --git a/agm.c b/agm.c
index aeab2702e..f96c8340b 100644
--- a/agm.c
+++ b/agm.c
@@ -145,13 +145,14 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode)
while (mpfr_cmp2(u, v, &eq) != 0 && eq <= p - 2);
/* Roundability of the result */
- can_round=mpfr_can_round(v,p-err-3,GMP_RNDN,rnd_mode,q);
+ can_round = mpfr_can_round (v, p - err - 3, GMP_RNDN, GMP_RNDZ,
+ q + (rnd_mode == GMP_RNDN));
if (can_round)
- go_on=0;
+ go_on = 0;
else {
- go_on=1;
+ go_on = 1;
p+=5;
s=(p-1)/BITS_PER_MP_LIMB+1;
MPFR_INIT(up, u, p, s);
diff --git a/asin.c b/asin.c
index 555f9d7d5..b0567480f 100644
--- a/asin.c
+++ b/asin.c
@@ -108,7 +108,8 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_sqrt (tmp, tmp, GMP_RNDN);
mpfr_div (tmp, x, tmp, GMP_RNDN);
mpfr_atan (arcs, tmp, GMP_RNDN);
- if (mpfr_can_round (arcs, realprec, GMP_RNDN, rnd_mode, MPFR_PREC(asin)))
+ if (mpfr_can_round (arcs, realprec, GMP_RNDN, GMP_RNDZ,
+ MPFR_PREC(asin) + (rnd_mode == GMP_RNDN)))
{
inexact = mpfr_set (asin, arcs, rnd_mode);
good = 1;
diff --git a/asinh.c b/asinh.c
index 93830d2d7..2a110787a 100644
--- a/asinh.c
+++ b/asinh.c
@@ -102,7 +102,8 @@ mpfr_asinh (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
/* actualisation of the precision */
Nt += 10;
}
- while ((err < 0) || (!mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ny)
+ while ((err < 0) || (!mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN))
|| MPFR_IS_ZERO(t)));
mpfr_restore_emin_emax ();
diff --git a/atan.c b/atan.c
index de7e30b05..890432b3a 100644
--- a/atan.c
+++ b/atan.c
@@ -222,10 +222,10 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode)
MPFR_CHANGE_SIGN(arctgt);
}
- if (mpfr_can_round (arctgt, realprec, GMP_RNDN, rnd_mode,
- MPFR_PREC (arctangent)))
+ if (mpfr_can_round (arctgt, realprec, GMP_RNDN, GMP_RNDZ,
+ MPFR_PREC (arctangent) + (rnd_mode == GMP_RNDN)))
{
- inexact = mpfr_set(arctangent, arctgt, rnd_mode);
+ inexact = mpfr_set (arctangent, arctgt, rnd_mode);
good = 1;
realprec += 1;
}
diff --git a/atanh.c b/atanh.c
index 58041f157..ffe0a84bb 100644
--- a/atanh.c
+++ b/atanh.c
@@ -122,13 +122,14 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode)
Nt += 10;
}
- while ((err < 0) ||
- (!mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny) || MPFR_IS_ZERO(t)));
+ while ((err < 0) || (!mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN))
+ || MPFR_IS_ZERO(t)));
if(flag_neg)
MPFR_CHANGE_SIGN(t);
- inexact = mpfr_set(y,t,rnd_mode);
+ inexact = mpfr_set (y, t, rnd_mode);
mpfr_clear(t);
mpfr_clear(ti);
diff --git a/const_euler.c b/const_euler.c
index 0334f328b..97930751c 100644
--- a/const_euler.c
+++ b/const_euler.c
@@ -36,6 +36,7 @@ mpfr_const_euler (mpfr_t x, mp_rnd_t rnd)
mp_prec_t prec = MPFR_PREC(x), m, log2m;
mpfr_t y, z;
unsigned long n;
+ int inexact;
log2m = __gmpfr_ceil_log2 ((double) prec);
m = prec + log2m;
@@ -60,14 +61,15 @@ mpfr_const_euler (mpfr_t x, mp_rnd_t rnd)
mpfr_const_euler_R (z, n);
mpfr_sub (y, y, z, GMP_RNDN);
}
- while (!mpfr_can_round (y, m - 3, GMP_RNDN, rnd, prec));
+ while (!mpfr_can_round (y, m - 3, GMP_RNDN, GMP_RNDZ,
+ prec + (rnd == GMP_RNDN)));
- mpfr_set (x, y, rnd);
+ inexact = mpfr_set (x, y, rnd);
mpfr_clear (y);
mpfr_clear (z);
- return 1; /* always inexact */
+ return inexact; /* always inexact */
}
/* computes S(n) = sum(n^k*(-1)^(k-1)/k!/k, k=1..ceil(4.319136566 * n))
diff --git a/const_log2.c b/const_log2.c
index 61155b003..9e5761203 100644
--- a/const_log2.c
+++ b/const_log2.c
@@ -63,6 +63,7 @@ mpfr_const_aux_log2 (mpfr_ptr mylog, mp_rnd_t rnd_mode)
int logn;
mp_prec_t prec_i_want = MPFR_PREC(mylog);
mp_prec_t prec_x;
+ int inexact;
mpz_init(cst);
logn = __gmpfr_ceil_log2 ((double) MPFR_PREC(mylog));
@@ -93,17 +94,20 @@ mpfr_const_aux_log2 (mpfr_ptr mylog, mp_rnd_t rnd_mode)
mpfr_clear(tmp1);
mpfr_clear(tmp2);
mpfr_clear(tmp3);
- if (mpfr_can_round(result, prec_x, GMP_RNDD, rnd_mode, prec_i_want)){
- mpfr_set(mylog, result, rnd_mode);
- good = 1;
- } else
+ if (mpfr_can_round (result, prec_x, GMP_RNDD, GMP_RNDZ,
+ prec_i_want + (rnd_mode == GMP_RNDN)))
+ {
+ inexact = mpfr_set (mylog, result, rnd_mode);
+ good = 1;
+ }
+ else
{
prec_x += logn;
}
- mpfr_clear(result);
+ mpfr_clear (result);
}
- mpz_clear(cst);
- return 0;
+ mpz_clear (cst);
+ return inexact;
}
/* Cross-over point from nai"ve Taylor series to binary splitting,
@@ -129,6 +133,7 @@ mpfr_const_log2 (mpfr_ptr x, mp_rnd_t rnd_mode)
{
mp_prec_t N, k, precx;
mpz_t s, t, u;
+ int inexact;
precx = MPFR_PREC(x);
MPFR_CLEAR_FLAGS(x);
@@ -138,7 +143,7 @@ mpfr_const_log2 (mpfr_ptr x, mp_rnd_t rnd_mode)
{
if ((rnd_mode == __mpfr_const_log2_rnd) ||
mpfr_can_round (__mpfr_const_log2, __gmpfr_const_log2_prec - 1,
- __mpfr_const_log2_rnd, rnd_mode, precx))
+ __mpfr_const_log2_rnd, GMP_RNDZ, precx + (rnd_mode == GMP_RNDN)))
{
return mpfr_set (x, __mpfr_const_log2, rnd_mode);
}
@@ -172,7 +177,7 @@ mpfr_const_log2 (mpfr_ptr x, mp_rnd_t rnd_mode)
mpz_clear (u);
}
else /* use binary splitting method */
- mpfr_const_aux_log2(x, rnd_mode);
+ inexact = mpfr_const_aux_log2 (x, rnd_mode);
/* store computed value */
if (__gmpfr_const_log2_prec == 0)
@@ -183,5 +188,6 @@ mpfr_const_log2 (mpfr_ptr x, mp_rnd_t rnd_mode)
mpfr_set (__mpfr_const_log2, x, rnd_mode);
__gmpfr_const_log2_prec = precx;
__mpfr_const_log2_rnd = rnd_mode;
- return 1;
+
+ return inexact;
}
diff --git a/const_pi.c b/const_pi.c
index 62d5d72c8..e97bc02f6 100644
--- a/const_pi.c
+++ b/const_pi.c
@@ -51,6 +51,7 @@ mpfr_pi_machin3 (mpfr_ptr mylog, mp_rnd_t rnd_mode)
int good = 0;
mpfr_t tmp1, tmp2, result,tmp3,tmp4,tmp5,tmp6;
mpz_t cst;
+ int inex;
MPFR_CLEAR_FLAGS(mylog);
logn = __gmpfr_ceil_log2 ((double) MPFR_PREC(mylog));
@@ -105,20 +106,20 @@ mpfr_pi_machin3 (mpfr_ptr mylog, mp_rnd_t rnd_mode)
mpfr_clear(tmp4);
mpfr_clear(tmp5);
mpfr_clear(tmp6);
- if (mpfr_can_round(result, prec_x - 5, GMP_RNDD, rnd_mode, prec_i_want))
+ if (mpfr_can_round (result, prec_x - 5, GMP_RNDD, GMP_RNDZ,
+ prec_i_want + (rnd_mode == GMP_RNDN)))
{
- mpfr_set(mylog, result, rnd_mode);
- mpfr_clear(result);
+ inex = mpfr_set (mylog, result, rnd_mode);
good = 1;
}
else
{
- mpfr_clear(result);
prec_x += logn;
}
+ mpfr_clear (result);
}
- mpz_clear(cst);
- return 0;
+ mpz_clear (cst);
+ return inex;
}
/*
@@ -161,6 +162,7 @@ mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
int N, oldN, n, prec;
mpz_t pi, num, den, d3, d2, tmp;
mpfr_t y;
+ int inex;
prec=MPFR_PREC(x);
@@ -168,9 +170,10 @@ mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
if ((prec==__gmpfr_const_pi_prec && rnd_mode==__mpfr_const_pi_rnd) ||
(prec<=__gmpfr_const_pi_prec &&
mpfr_can_round(__mpfr_const_pi, __gmpfr_const_pi_prec,
- __mpfr_const_pi_rnd, rnd_mode, prec)))
+ __mpfr_const_pi_rnd, GMP_RNDZ,
+ prec + (rnd_mode == GMP_RNDN))))
{
- return mpfr_set(x, __mpfr_const_pi, rnd_mode);
+ return mpfr_set (x, __mpfr_const_pi, rnd_mode);
}
if (prec < 20000)
@@ -215,11 +218,11 @@ mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
mpz_fdiv_q(tmp, tmp, den);
mpz_add(pi, pi, tmp);
}
- mpfr_set_z(x, pi, rnd_mode);
- mpfr_init2(y, mpfr_get_prec(x));
- mpz_add_ui(pi, pi, N+1);
- mpfr_set_z(y, pi, rnd_mode);
- if (mpfr_cmp(x, y) != 0)
+ mpfr_set_z (x, pi, rnd_mode);
+ mpfr_init2 (y, mpfr_get_prec(x));
+ mpz_add_ui (pi, pi, N+1);
+ mpfr_set_z (y, pi, rnd_mode);
+ if (mpfr_cmp (x, y) != 0)
{
fprintf(stderr, "does not converge\n");
exit(1);
@@ -234,7 +237,8 @@ mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
mpfr_clear(y);
}
else
- mpfr_pi_machin3(x, rnd_mode);
+ inex = mpfr_pi_machin3 (x, rnd_mode);
+
/* store computed value */
if (__gmpfr_const_pi_prec==0)
mpfr_init2(__mpfr_const_pi, prec);
@@ -243,5 +247,6 @@ mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
mpfr_set(__mpfr_const_pi, x, rnd_mode);
__gmpfr_const_pi_prec=prec;
__mpfr_const_pi_rnd=rnd_mode;
- return 1;
+
+ return inex;
}
diff --git a/cos.c b/cos.c
index 7203f351f..5efc382b6 100644
--- a/cos.c
+++ b/cos.c
@@ -78,7 +78,7 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
/* now the error is bounded by 2^(k-m) = 2^(EXP(s)-err) */
l = mpfr_can_round (s, MPFR_GET_EXP (s) + m - k,
- GMP_RNDN, rnd_mode, precy);
+ GMP_RNDN, GMP_RNDZ, precy + (rnd_mode == GMP_RNDN));
if (l == 0)
{
diff --git a/cosh.c b/cosh.c
index 98a40913d..c76f67285 100644
--- a/cosh.c
+++ b/cosh.c
@@ -75,47 +75,51 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode)
long int err; /* Precision of error */
/* compute the precision of intermediary variable */
- Nt=MAX(Nx,Ny);
+ Nt = MAX(Nx, Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt=Nt+3+__gmpfr_ceil_log2(Nt);
+ Nt = Nt + 3 + __gmpfr_ceil_log2 (Nt);
/* initialise of intermediary variable */
- mpfr_init(t);
- mpfr_init(te);
- mpfr_init(ti);
+ mpfr_init (t);
+ mpfr_init (te);
+ mpfr_init (ti);
/* First computation of cosh */
- do {
+ do
+ {
- /* reactualisation of the precision */
+ /* reactualisation of the precision */
- mpfr_set_prec(t,Nt);
- mpfr_set_prec(te,Nt);
- mpfr_set_prec(ti,Nt);
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
+ mpfr_set_prec (ti, Nt);
- /* compute cosh */
- mpfr_exp(te,x,GMP_RNDD); /* exp(x) */
- mpfr_ui_div(ti,1,te,GMP_RNDU); /* 1/exp(x) */
- mpfr_add(t,te,ti,GMP_RNDN); /* exp(x) + 1/exp(x)*/
- mpfr_div_2ui(t,t,1,GMP_RNDN); /* 1/2(exp(x) + 1/exp(x))*/
+ /* compute cosh */
+ mpfr_exp (te, x, GMP_RNDD); /* exp(x) */
+ mpfr_ui_div (ti, 1, te, GMP_RNDU); /* 1/exp(x) */
+ mpfr_add (t, te, ti, GMP_RNDN); /* exp(x) + 1/exp(x)*/
+ mpfr_div_2ui (t, t, 1, GMP_RNDN); /* 1/2(exp(x) + 1/exp(x))*/
- /* estimation of the error */
- err=Nt-3;
+ /* estimation of the error */
+ err = Nt - 3;
- /* actualisation of the precision */
- Nt += 10;
+ /* actualisation of the precision */
+ Nt += 10;
- } while ((err <0) || !mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny));
+ }
+ while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN)));
- inexact = mpfr_set(y,t,rnd_mode);
+ inexact = mpfr_set (y, t, rnd_mode);
- mpfr_clear(t);
- mpfr_clear(ti);
- mpfr_clear(te);
+ mpfr_clear (t);
+ mpfr_clear (ti);
+ mpfr_clear (te);
}
- mpfr_clear(x);
- return inexact;
+ mpfr_clear (x);
+
+ return inexact;
}
diff --git a/erf.c b/erf.c
index b13ef47ec..600e0a6d9 100644
--- a/erf.c
+++ b/erf.c
@@ -42,6 +42,7 @@ mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
int sign_x;
mp_rnd_t rnd2;
double n = (double) MPFR_PREC(y);
+ int inex;
if (MPFR_IS_NAN(x))
{
@@ -88,13 +89,13 @@ mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
}
else /* use Taylor */
{
- mpfr_erf_0 (y, x, rnd2);
+ inex = mpfr_erf_0 (y, x, rnd2);
}
if (sign_x < 0)
MPFR_CHANGE_SIGN(y);
- return 1;
+ return inex;
}
/* return x*2^e */
@@ -132,6 +133,7 @@ mpfr_erf_0 (mpfr_ptr res, mpfr_srcptr x, mp_rnd_t rnd_mode)
unsigned int k;
long log2tauk;
int ok;
+ int inex;
n = MPFR_PREC(res); /* target precision */
xf = mpfr_get_d (x, GMP_RNDN);
@@ -189,7 +191,8 @@ mpfr_erf_0 (mpfr_ptr res, mpfr_srcptr x, mp_rnd_t rnd_mode)
tauk = 4.0 * tauk + 11.0; /* final ulp-error on s */
log2tauk = __gmpfr_ceil_log2 (tauk);
- ok = mpfr_can_round (s, m - log2tauk, GMP_RNDN, rnd_mode, n);
+ ok = mpfr_can_round (s, m - log2tauk, GMP_RNDN, GMP_RNDZ,
+ n + (rnd_mode == GMP_RNDN));
if (ok == 0)
{
@@ -199,14 +202,14 @@ mpfr_erf_0 (mpfr_ptr res, mpfr_srcptr x, mp_rnd_t rnd_mode)
}
while (ok == 0);
- mpfr_set (res, s, rnd_mode);
+ inex = mpfr_set (res, s, rnd_mode);
mpfr_clear (y);
mpfr_clear (t);
mpfr_clear (u);
mpfr_clear (s);
- return 1;
+ return inex;
}
#if 0
diff --git a/exp2.c b/exp2.c
index e3cad2745..3afbc803e 100644
--- a/exp2.c
+++ b/exp2.c
@@ -113,24 +113,27 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_init (te);
/* First computation */
- do {
+ do
+ {
- /* reactualisation of the precision */
- mpfr_set_prec (t, Nt);
- mpfr_set_prec (te, Nt);
+ /* reactualisation of the precision */
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
- /* compute exp(x*ln(2))*/
- mpfr_const_log2 (t, GMP_RNDU); /* ln(2) */
- mpfr_mul (te, x, t, GMP_RNDU); /* x*ln(2) */
- mpfr_exp (t, te, GMP_RNDN); /* exp(x*ln(2))*/
+ /* compute exp(x*ln(2))*/
+ mpfr_const_log2 (t, GMP_RNDU); /* ln(2) */
+ mpfr_mul (te, x, t, GMP_RNDU); /* x*ln(2) */
+ mpfr_exp (t, te, GMP_RNDN); /* exp(x*ln(2))*/
- /* estimate of the error -- see pow function in algorithms.ps*/
- err = Nt - (MPFR_GET_EXP (te) + 2);
+ /* estimate of the error -- see pow function in algorithms.ps*/
+ err = Nt - (MPFR_GET_EXP (te) + 2);
- /* actualisation of the precision */
- Nt += __gmpfr_isqrt (Nt) + 10;
+ /* actualisation of the precision */
+ Nt += __gmpfr_isqrt (Nt) + 10;
- } while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ny));
+ }
+ while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN)));
inexact = mpfr_set (y, t, rnd_mode);
diff --git a/expm1.c b/expm1.c
index 0de5dc867..4d8039ccc 100644
--- a/expm1.c
+++ b/expm1.c
@@ -104,12 +104,13 @@ mpfr_expm1 (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode)
/* actualisation of the precision */
Nt += 10;
}
- while ((err <0) || !mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny));
+ while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN)));
- inexact = mpfr_set(y,t,rnd_mode);
+ inexact = mpfr_set (y, t, rnd_mode);
- mpfr_clear(t);
- mpfr_clear(te);
+ mpfr_clear (t);
+ mpfr_clear (te);
}
return inexact;
diff --git a/factorial.c b/factorial.c
index d4f1992b9..4ee38414b 100644
--- a/factorial.c
+++ b/factorial.c
@@ -76,26 +76,26 @@ mpfr_fac_ui (mpfr_ptr y, unsigned long int x , mp_rnd_t rnd_mode)
err = Nt - 1 - (int) __gmpfr_ceil_log2 ((double) Nt);
- round = !inexact || mpfr_can_round (t,err,GMP_RNDZ,rnd_mode,Ny);
+ round = !inexact || mpfr_can_round (t, err, GMP_RNDZ, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN));
if (round)
{
round = mpfr_set (y, t, rnd_mode);
if (inexact == 0)
inexact = round;
- boucle=0;
+ boucle = 0;
}
else
{
- Nt=Nt+10;
+ Nt = Nt + 10;
/*initialise of intermediary variable */
- mpfr_set_prec(t, Nt);
+ mpfr_set_prec (t, Nt);
}
}
- mpfr_clear(t);
+ mpfr_clear (t);
return inexact;
-
}
}
diff --git a/gamma.c b/gamma.c
index 9a4e456dd..5da283b02 100644
--- a/gamma.c
+++ b/gamma.c
@@ -47,7 +47,6 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_t the_pi;
mpfr_t GammaTrial;
mpfr_t tmp, tmp2;
-
mp_prec_t Prec;
mp_prec_t prec_gamma;
mp_prec_t prec_nec;
@@ -58,6 +57,7 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
int compared;
int k;
int sign;
+ int inex;
/* Trivial cases */
if (MPFR_IS_NAN(x))
@@ -194,10 +194,10 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_out_str (stdout, 10, 0, GammaTrial, GMP_RNDD);
printf ("\n");
#endif
- if (mpfr_can_round (GammaTrial, realprec, GMP_RNDD, rnd_mode,
- MPFR_PREC(gamma)))
+ if (mpfr_can_round (GammaTrial, realprec, GMP_RNDD, GMP_RNDZ,
+ MPFR_PREC(gamma) + (rnd_mode == GMP_RNDN)))
{
- mpfr_set (gamma, GammaTrial, rnd_mode);
+ inex = mpfr_set (gamma, GammaTrial, rnd_mode);
good = 1;
}
else
@@ -216,5 +216,5 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_clear (xp);
- return 1; /* inexact result */
+ return inex; /* inexact result */
}
diff --git a/hypot.c b/hypot.c
index b65e7af3b..10cc75f06 100644
--- a/hypot.c
+++ b/hypot.c
@@ -151,7 +151,8 @@ mpfr_hypot (mpfr_ptr z, mpfr_srcptr x , mpfr_srcptr y , mp_rnd_t rnd_mode)
not_exact = 1;
}
- while (not_exact && mpfr_can_round (t, Nt - 2, GMP_RNDZ, rnd_mode, Nz) == 0);
+ while (not_exact && !mpfr_can_round (t, Nt - 2, GMP_RNDN, GMP_RNDZ,
+ Nz + (rnd_mode == GMP_RNDN)));
inexact = mpfr_mul_2ui (z, t, sh, rnd_mode);
diff --git a/log.c b/log.c
index e21f4704d..9904ab08f 100644
--- a/log.c
+++ b/log.c
@@ -159,13 +159,12 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode)
/* we have 7 ulps of error from the above roundings,
4 ulps from the 4/s^2 second order term,
plus the canceled bits */
- if (mpfr_can_round (cst, p - cancel - 4, GMP_RNDN, rnd_mode, q) == 1) {
- inexact = mpfr_set (r, cst, rnd_mode);
-#ifdef DEBUG
- printf("result="); mpfr_print_binary(r); putchar('\n');
-#endif
- go_on=0;
- }
+ if (mpfr_can_round (cst, p - cancel - 4, GMP_RNDN, GMP_RNDZ,
+ q + (rnd_mode == GMP_RNDN)) == 1)
+ {
+ inexact = mpfr_set (r, cst, rnd_mode);
+ go_on = 0;
+ }
/* else we increase the precision */
else {
p += BITS_PER_MP_LIMB + cancel;
diff --git a/log10.c b/log10.c
index 19d39e5cb..68d483889 100644
--- a/log10.c
+++ b/log10.c
@@ -124,7 +124,8 @@ mpfr_log10 (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode)
/* estimation of the error */
err = Nt - 4;
- ok = mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ny);
+ ok = mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN));
/* log10(10^n) is exact */
if ((MPFR_SIGN(t) > 0) && mpfr_integer_p (t))
diff --git a/log1p.c b/log1p.c
index a913fe026..7bd641f7a 100644
--- a/log1p.c
+++ b/log1p.c
@@ -95,35 +95,37 @@ mpfr_log1p (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
long int err; /* Precision of error */
/* compute the precision of intermediary variable */
- Nt=MAX(Nx,Ny);
+ Nt = MAX(Nx,Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt=Nt+5+__gmpfr_ceil_log2(Nt);
+ Nt = Nt + 5 + __gmpfr_ceil_log2 (Nt);
/* initialise of intermediary variable */
- mpfr_init(t);
+ mpfr_init (t);
/* First computation of cosh */
- do {
-
- /* reactualisation of the precision */
- mpfr_set_prec(t, Nt);
+ do
+ {
+ /* reactualisation of the precision */
+ mpfr_set_prec (t, Nt);
- /* compute log1p */
- mpfr_add_ui (t, x, 1, GMP_RNDN); /* 1+x */
- mpfr_log (t, t, GMP_RNDN); /* log(1+x)*/
-
- /* estimation of the error */
- /*err=Nt-(__gmpfr_ceil_log2(1+pow(2,1-MPFR_GET_EXP(t))));*/
- err = Nt - (MAX (1 - MPFR_GET_EXP (t), 0) + 1);
+ /* compute log1p */
+ mpfr_add_ui (t, x, 1, GMP_RNDN); /* 1+x */
+ mpfr_log (t, t, GMP_RNDN); /* log(1+x)*/
- /* actualisation of the precision */
- Nt += 10;
+ /* estimation of the error */
+ /*err=Nt-(__gmpfr_ceil_log2(1+pow(2,1-MPFR_GET_EXP(t))));*/
+ err = Nt - (MAX (1 - MPFR_GET_EXP (t), 0) + 1);
- } while ((err<0) || !mpfr_can_round(t, err, GMP_RNDN, rnd_mode, Ny));
+ /* actualisation of the precision */
+ Nt += 10;
+ }
+ while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN)));
inexact = mpfr_set (y, t, rnd_mode);
- mpfr_clear(t);
+ mpfr_clear (t);
}
+
return inexact;
}
diff --git a/log2.c b/log2.c
index 483171c8b..0daf41ff7 100644
--- a/log2.c
+++ b/log2.c
@@ -113,29 +113,31 @@ mpfr_log2 (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode)
/* First computation of log2 */
- do {
-
- /* reactualisation of the precision */
- mpfr_set_prec(t,Nt);
- mpfr_set_prec(tt,Nt);
+ do
+ {
+ /* reactualisation of the precision */
+ mpfr_set_prec(t,Nt);
+ mpfr_set_prec(tt,Nt);
- /* compute log2 */
- mpfr_const_log2(t,GMP_RNDD); /* log(2) */
- mpfr_log(tt,a,GMP_RNDN); /* log(a) */
- mpfr_div(t,tt,t,GMP_RNDN); /* log(a)/log(2) */
-
-
- /* estimation of the error */
- err=Nt-3;
-
- /* actualisation of the precision */
- Nt += 10;
- } while ((err<0) || !mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny));
+ /* compute log2 */
+ mpfr_const_log2(t,GMP_RNDD); /* log(2) */
+ mpfr_log(tt,a,GMP_RNDN); /* log(a) */
+ mpfr_div(t,tt,t,GMP_RNDN); /* log(a)/log(2) */
+
+ /* estimation of the error */
+ err=Nt-3;
+
+ /* actualisation of the precision */
+ Nt += 10;
+ }
+ while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN)));
- inexact = mpfr_set(r,t,rnd_mode);
+ inexact = mpfr_set (r, t, rnd_mode);
- mpfr_clear(t);
- mpfr_clear(tt);
+ mpfr_clear (t);
+ mpfr_clear (tt);
}
+
return inexact;
}
diff --git a/pow.c b/pow.c
index 7c965f632..27244593c 100644
--- a/pow.c
+++ b/pow.c
@@ -349,7 +349,8 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
/* actualisation of the precision */
Nt += 10;
- ok = mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Nz);
+ ok = mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Nz + (rnd_mode == GMP_RNDN));
/* check exact power */
if (ok == 0 && loop == 1)
diff --git a/pow_si.c b/pow_si.c
index f7de052c6..df49f48c5 100644
--- a/pow_si.c
+++ b/pow_si.c
@@ -47,7 +47,7 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
MPFR_CLEAR_NAN(y);
if (n == 0)
- return mpfr_set_ui(y, 1, GMP_RNDN);
+ return mpfr_set_ui (y, 1, GMP_RNDN);
if (MPFR_IS_INF(x))
{
@@ -71,6 +71,14 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
MPFR_CLEAR_INF(y);
+ /* detect exact powers: x^(-n) is exact iff x is a power of 2 */
+ if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), MPFR_EXP(x) - 1) == 0)
+ {
+ mpfr_set_si (y, (n % 2) ? MPFR_SIGN(x) : 1, rnd_mode);
+ MPFR_EXP(y) += n * (MPFR_EXP(x) - 1);
+ return 0;
+ }
+
n = -n;
/* General case */
@@ -87,15 +95,15 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
int inexact;
/* compute the precision of intermediary variable */
- Nt=MAX(Nx,Ny);
+ Nt = MAX(Nx,Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt=Nt+3+__gmpfr_ceil_log2(Nt);
+ Nt = Nt + 3 + __gmpfr_ceil_log2 (Nt);
mpfr_save_emin_emax ();
/* initialise of intermediary variable */
- mpfr_init(t);
- mpfr_init(ti);
+ mpfr_init (t);
+ mpfr_init (ti);
do
{
@@ -113,7 +121,8 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
/* actualisation of the precision */
Nt += 10;
}
- while (err < 0 || !mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ny));
+ while (err < 0 || !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN)));
inexact = mpfr_set (y, t, rnd_mode);
mpfr_clear (t);
diff --git a/pow_ui.c b/pow_ui.c
index bbce707a1..aa8db2020 100644
--- a/pow_ui.c
+++ b/pow_ui.c
@@ -44,7 +44,7 @@ mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned long int n, mp_rnd_t rnd)
MPFR_CLEAR_NAN(x);
- if (n == 0) /* x^0 = 1 for any x */
+ if (n == 0) /* y^0 = 1 for any y */
{
/* The return mpfr_set_ui is important as 1 isn't necessarily
in the exponent range. */
@@ -64,6 +64,12 @@ mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned long int n, mp_rnd_t rnd)
MPFR_CLEAR_INF(x);
+ if (MPFR_IS_ZERO(y)) /* 0^n = 0 for any n */
+ {
+ MPFR_SET_ZERO(x);
+ MPFR_RET(0);
+ }
+
mpfr_save_emin_emax ();
mpfr_init (res);
@@ -88,16 +94,23 @@ mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned long int n, mp_rnd_t rnd)
if (mpfr_mul (res, res, y, rnd1))
inexact = 1;
}
+
+ /* check underflow */
+ if (MPFR_EXP(res) <= (double) __gmpfr_emin)
+ {
+ mpfr_clear (res);
+ mpfr_restore_emin_emax ();
+ return mpfr_set_underflow (x, rnd, (n % 2) ? MPFR_SIGN(y) : 1);
+ }
+
err = prec - err;
if (err < 0)
err = 0;
}
- while (inexact &&
- mpfr_can_round (res, err, MPFR_SIGN(res) > 0 ? GMP_RNDU : GMP_RNDD,
- rnd, MPFR_PREC(x)) == 0);
+ while (inexact && !mpfr_can_round (res, err, GMP_RNDN, GMP_RNDZ,
+ MPFR_PREC(x) + (rnd == GMP_RNDN)));
- if (mpfr_set (x, res, rnd))
- inexact = 1;
+ inexact = mpfr_set (x, res, rnd);
mpfr_clear (res);
mpfr_restore_emin_emax ();
return mpfr_check_range (x, inexact, rnd);
diff --git a/sin.c b/sin.c
index 10cb004e4..97df89fa6 100644
--- a/sin.c
+++ b/sin.c
@@ -124,7 +124,8 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
/* the absolute error on c is at most 2^(e-m) = 2^(EXP(c)-err) */
e = MPFR_GET_EXP (c) + m - e;
- ok = (e >= 0) && mpfr_can_round (c, e, GMP_RNDN, rnd_mode, precy);
+ ok = (e >= 0) && mpfr_can_round (c, e, GMP_RNDN, GMP_RNDZ,
+ precy + (rnd_mode == GMP_RNDN));
if (ok == 0)
{
diff --git a/sinh.c b/sinh.c
index bfe415433..da5495a3d 100644
--- a/sinh.c
+++ b/sinh.c
@@ -94,39 +94,41 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode)
mpfr_init (ti);
/* First computation of sinh */
- do {
+ do
+ {
- /* reactualisation of the precision */
+ /* reactualisation of the precision */
- mpfr_set_prec (t, Nt);
- mpfr_set_prec (te, Nt);
- mpfr_set_prec (ti, Nt);
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
+ mpfr_set_prec (ti, Nt);
- /* compute sinh */
- mpfr_exp (te, x, GMP_RNDD); /* exp(x) */
- mpfr_ui_div (ti, 1, te, GMP_RNDU); /* 1/exp(x) */
- mpfr_sub (t, te, ti, GMP_RNDN); /* exp(x) - 1/exp(x) */
- mpfr_div_2ui (t, t, 1, GMP_RNDN); /* 1/2(exp(x) - 1/exp(x)) */
+ /* compute sinh */
+ mpfr_exp (te, x, GMP_RNDD); /* exp(x) */
+ mpfr_ui_div (ti, 1, te, GMP_RNDU); /* 1/exp(x) */
+ mpfr_sub (t, te, ti, GMP_RNDN); /* exp(x) - 1/exp(x) */
+ mpfr_div_2ui (t, t, 1, GMP_RNDN); /* 1/2(exp(x) - 1/exp(x)) */
- /* it may be that t is zero (in fact, it can only occur when te=1,
- and thus ti=1 too) */
+ /* it may be that t is zero (in fact, it can only occur when te=1,
+ and thus ti=1 too) */
- if (MPFR_IS_ZERO(t))
- err = -1;
- else
- {
- /* calculation of the error */
- d = MPFR_GET_EXP (te) - MPFR_GET_EXP (t) + 2;
+ if (MPFR_IS_ZERO(t))
+ err = -1;
+ else
+ {
+ /* calculation of the error */
+ d = MPFR_GET_EXP (te) - MPFR_GET_EXP (t) + 2;
- /* error estimate */
- /* err = Nt-(__gmpfr_ceil_log2(1+pow(2,d)));*/
- err = Nt - (MAX(d,0) + 1);
- }
+ /* error estimate */
+ /* err = Nt-(__gmpfr_ceil_log2(1+pow(2,d)));*/
+ err = Nt - (MAX(d,0) + 1);
+ }
- /* actualisation of the precision */
- Nt += 10;
+ /* actualisation of the precision */
+ Nt += 10;
- } while ((err < 0) || !mpfr_can_round(t, err, GMP_RNDN, rnd_mode, Ny));
+ } while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN)));
if (flag_neg == 1)
MPFR_CHANGE_SIGN(t);
diff --git a/sqrt.c b/sqrt.c
index 4ddac2fd1..a8483cd3e 100644
--- a/sqrt.c
+++ b/sqrt.c
@@ -170,7 +170,7 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
printf ("(inexact = %lu)\n", q_limb);
#endif
- can_round = mpfr_can_round_raw(rp, rrsize, 1, err,
+ can_round = mpfr_can_round_raw (rp, rrsize, 1, err,
GMP_RNDZ, rnd_mode, MPFR_PREC(r));
/* If we used all the limbs of both the dividend and the divisor,
diff --git a/tan.c b/tan.c
index eeec06743..c93275a5b 100644
--- a/tan.c
+++ b/tan.c
@@ -56,7 +56,8 @@ mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
mpfr_sin_cos (s, c, x, GMP_RNDN); /* err <= 1/2 ulp on s and c */
mpfr_div (c, s, c, GMP_RNDN); /* err <= 2 ulps */
- ok = mpfr_can_round (c, m - 1, GMP_RNDN, rnd_mode, precy);
+ ok = mpfr_can_round (c, m - 1, GMP_RNDN, GMP_RNDZ,
+ precy + (rnd_mode == GMP_RNDN));
if (ok == 0)
{
diff --git a/tanh.c b/tanh.c
index 20dc76720..885419bce 100644
--- a/tanh.c
+++ b/tanh.c
@@ -106,45 +106,48 @@ mpfr_tanh (y, xt, rnd_mode)
/* First computation of cosh */
- do {
+ do
+ {
- /* reactualisation of the precision */
- mpfr_set_prec(t,Nt);
- mpfr_set_prec(te,Nt);
- mpfr_set_prec(ta,Nt);
- mpfr_set_prec(tb,Nt);
+ /* reactualisation of the precision */
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
+ mpfr_set_prec (ta, Nt);
+ mpfr_set_prec (tb, Nt);
- /* compute tanh */
- mpfr_mul_2ui(te,x,1,GMP_RNDN); /* 2x */
- mpfr_exp(te,te,GMP_RNDN); /* exp(2x) */
- mpfr_add_ui(ta,te,1,GMP_RNDD); /* exp(2x) + 1*/
- mpfr_sub_ui(tb,te,1,GMP_RNDU); /* exp(2x) - 1*/
- mpfr_div(t,tb,ta,GMP_RNDN); /* (exp(2x)-1)/(exp(2x)+1)*/
+ /* compute tanh */
+ mpfr_mul_2ui (te, x, 1, GMP_RNDN); /* 2x */
+ mpfr_exp (te, te, GMP_RNDN); /* exp(2x) */
+ mpfr_add_ui (ta, te, 1, GMP_RNDD); /* exp(2x) + 1*/
+ mpfr_sub_ui (tb, te, 1, GMP_RNDU); /* exp(2x) - 1*/
+ mpfr_div (t, tb, ta, GMP_RNDN); /* (exp(2x)-1)/(exp(2x)+1)*/
- /* calculation of the error*/
- d = MPFR_GET_EXP (te) - MPFR_GET_EXP (t);
+ /* calculation of the error*/
+ d = MPFR_GET_EXP (te) - MPFR_GET_EXP (t);
- /* estimation of the error */
- /*err = Nt-(__gmpfr_ceil_log2(7+pow(2,d+1)));*/
- err = Nt-(MAX(d+1,3)+1);
+ /* estimation of the error */
+ /*err = Nt-(__gmpfr_ceil_log2(7+pow(2,d+1)));*/
+ err = Nt - (MAX(d + 1, 3) + 1);
- /* actualisation of the precision */
- Nt += 10;
+ /* actualisation of the precision */
+ Nt += 10;
- } while ((err <0)||!mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny));
+ }
+ while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ,
+ Ny + (rnd_mode == GMP_RNDN)));
if (flag_neg==1)
- MPFR_CHANGE_SIGN(t);
+ MPFR_CHANGE_SIGN(t);
- inexact = mpfr_set(y,t,rnd_mode);
- mpfr_clear(t);
- mpfr_clear(te);
- mpfr_clear(ta);
- mpfr_clear(tb);
+ inexact = mpfr_set (y, t, rnd_mode);
+ mpfr_clear (t);
+ mpfr_clear (te);
+ mpfr_clear (ta);
+ mpfr_clear (tb);
}
- mpfr_clear(x);
- return inexact;
+ mpfr_clear (x);
+ return inexact;
}
diff --git a/ui_pow_ui.c b/ui_pow_ui.c
index b8a512fb4..c8954e927 100644
--- a/ui_pow_ui.c
+++ b/ui_pow_ui.c
@@ -72,8 +72,8 @@ mpfr_ui_pow_ui (mpfr_ptr x, unsigned long int y, unsigned long int n,
if (err < 0)
err = 0;
}
- while (inexact && (mpfr_can_round (res, err,
- MPFR_SIGN(res) > 0 ? GMP_RNDU : GMP_RNDD, rnd, MPFR_PREC(x)) == 0));
+ while (inexact && !mpfr_can_round (res, err, GMP_RNDN, GMP_RNDZ,
+ MPFR_PREC(x) + (rnd == GMP_RNDN)));
if (mpfr_set (x, res, rnd))
inexact = 1;
diff --git a/zeta.c b/zeta.c
index 08a12c68a..f35268a25 100644
--- a/zeta.c
+++ b/zeta.c
@@ -32,7 +32,6 @@ MA 02111-1307, USA. */
void mpfr_zeta_part_b _PROTO ((mpfr_t, mpfr_srcptr, int, int, mpfr_t *));
void mpfr_zeta_c _PROTO ((int, mpfr_t *));
void mpfr_zeta_part_a _PROTO ((mpfr_t, mpfr_srcptr, int));
-void mpfr_zeta_pos _PROTO ((mpfr_t, mpfr_srcptr, mp_rnd_t));
/*
Parameters:
@@ -157,7 +156,7 @@ mpfr_zeta_part_a (mpfr_t sum, mpfr_srcptr s, int n)
Assumes s is neither NaN nor Infinite.
Output: z - Zeta(s) rounded to the precision of z with direction rnd_mode
*/
-void
+static int
mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
{
int p, n, l, dint, add, d, can_round;
@@ -165,6 +164,7 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
mpfr_t a,b,c,z_pre,f,g,s1;
mpfr_t *tc1;
mp_prec_t precz, precs;
+ int inex;
precz = mpfr_get_prec (z);
precs = mpfr_get_prec (s);
@@ -192,6 +192,7 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
if (MPFR_IS_ZERO (s1))
{
mpfr_set_inf (z, 1);
+ inex = 0;
goto clear_and_return;
}
else if (MPFR_GET_EXP (s1) <= -(d-3)/2)
@@ -285,7 +286,8 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
printf ("\nZeta(s) before rounding=");
mpfr_print_binary (z_pre);
#endif
- can_round = mpfr_can_round (z_pre, d - 3, GMP_RNDN, rnd_mode, precz);
+ can_round = mpfr_can_round (z_pre, d - 3, GMP_RNDN, GMP_RNDZ,
+ precz + (rnd_mode == GMP_RNDN));
if (can_round)
{
#ifdef DEBUG
@@ -302,7 +304,7 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
}
while (can_round == 0);
- mpfr_set (z, z_pre, rnd_mode);
+ inex = mpfr_set (z, z_pre, rnd_mode);
#ifdef DEBUG
printf ("\nZeta(s) after rounding=");
mpfr_print_binary (z);
@@ -316,6 +318,8 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
mpfr_clear (f);
mpfr_clear (g);
mpfr_clear (s1);
+
+ return inex;
}
int
@@ -326,6 +330,7 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
long add;
mpfr_t z_pre, s1, s2, y, sfrac, sint, p;
mp_prec_t precz, prec1, precs, precs1;
+ int inex;
if (mpfr_nan_p (s))
{
@@ -377,7 +382,7 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
prec1 = precz + add; /* Note that prec1 is still incremented by 10 at the first entry of loop below */
prec1 = MAX(prec1, precs1);
if (MPFR_SIGN (s) != -1 && MPFR_GET_EXP (s) >= 0) /* Case s >= 1/2 */
- mpfr_zeta_pos (z, s, rnd_mode);
+ inex = mpfr_zeta_pos (z, s, rnd_mode);
else
{
mpfr_init2(z_pre, MPFR_PREC_MIN);
@@ -422,11 +427,11 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
mpfr_pow (y, y, s1, GMP_RNDN);
mpfr_mul (z_pre, z_pre, y, GMP_RNDN);
mpfr_mul_2ui (z_pre, z_pre, 1, GMP_RNDN);
- can_round = mpfr_can_round (z_pre, prec1 - add, GMP_RNDN,
- rnd_mode, precz);
+ can_round = mpfr_can_round (z_pre, prec1 - add, GMP_RNDN, GMP_RNDZ,
+ precz + (rnd_mode == GMP_RNDN));
}
while (can_round == 0);
- mpfr_set (z, z_pre, rnd_mode);
+ inex = mpfr_set (z, z_pre, rnd_mode);
mpfr_clear(z_pre);
mpfr_clear(s1);
mpfr_clear(y);
@@ -434,5 +439,5 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mp_rnd_t rnd_mode)
mpfr_clear(sint);
mpfr_clear(sfrac);
}
- return 1;
+ return inex;
}