diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2008-09-06 10:19:10 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2008-09-06 10:19:10 +0000 |
commit | 163a504e69d32e38605bb88607e9ba063a7ccf4a (patch) | |
tree | 87d61cedecddadeed97b75e46978629f7b9e11b5 /pow.c | |
parent | aa7e0ea4304899beff3c7cf5735f1967465124f5 (diff) | |
download | mpfr-163a504e69d32e38605bb88607e9ba063a7ccf4a.tar.gz |
pow.c: fixed bug20080904 (from tpow_z.c).
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@5620 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'pow.c')
-rw-r--r-- | pow.c | 32 |
1 files changed, 16 insertions, 16 deletions
@@ -167,7 +167,7 @@ mpfr_pow_general (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, /* Declaration of the size variable */ mp_prec_t Nz = MPFR_PREC(z); /* target precision */ mp_prec_t Nt; /* working precision */ - mp_exp_t err, exp_te; /* error */ + mp_exp_t err; /* error */ MPFR_ZIV_DECL (ziv_loop); @@ -209,7 +209,21 @@ mpfr_pow_general (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, MPFR_LOG_MSG (("t = y * ln|x| - k * ln(2)\n", 0)); MPFR_LOG_VAR (t); } - exp_te = MPFR_GET_EXP (t); /* FIXME: May overflow */ + /* estimate of the error -- see pow function in algorithms.tex. + The error on t is at most 1/2 + 3*2^(EXP(t)+1) ulps, which is + <= 2^(EXP(t)+3) for EXP(t) >= -1, and <= 2 ulps for EXP(t) <= -2. + Additional error if k_no_zero: treal = t * errk, with + 1 - |k| * 2^(-Nt) <= exp(-|k| * 2^(-Nt)) <= errk <= 1, + i.e., additional absolute error <= 2^(EXP(k)+EXP(t)-Nt). + Total error <= 2^err1 + 2^err2 <= 2^(max(err1,err2)+1). */ + err = MPFR_NOTZERO (t) && MPFR_GET_EXP (t) >= -1 ? + MPFR_GET_EXP (t) + 3 : 1; + if (k_non_zero) + { + if (MPFR_GET_EXP (k) > err) + err = MPFR_GET_EXP (k); + err++; + } MPFR_BLOCK (flags1, mpfr_exp (t, t, GMP_RNDN)); /* exp(y*ln|x|)*/ /* We need to test */ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (t) || MPFR_UNDERFLOW (flags1))) @@ -271,20 +285,6 @@ mpfr_pow_general (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, /* |y| < 2^Ntmin, therefore |k| < 2^Nt. */ continue; } - /* estimate of the error -- see pow function in algorithms.tex. - The error on t is at most 1/2 + 3*2^(exp_te+1) ulps, which is - <= 2^(exp_te+3) for exp_te >= -1, and <= 2 ulps for exp_te <= -2. - Additional error if k_no_zero: treal = t * errk, with - 1 - |k| * 2^(-Nt) <= exp(-|k| * 2^(-Nt)) <= errk <= 1, - i.e., additional absolute error <= 2^(EXP(k)+EXP(t)-Nt). - Total error <= 2^err1 + 2^err2 <= 2^(max(err1,err2)+1). */ - err = exp_te >= -1 ? exp_te + 3 : 1; - if (k_non_zero) - { - if (MPFR_GET_EXP (k) > err) - err = MPFR_GET_EXP (k); - err++; - } if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - err, Nz, rnd_mode))) { inexact = mpfr_set (z, t, rnd_mode); |