summaryrefslogtreecommitdiff
path: root/exp2.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2003-01-06 19:28:25 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2003-01-06 19:28:25 +0000
commit52265d509a30387d337be70b117716d6e248bf18 (patch)
tree08f27cac8df77fef15e8b1582169d5a1377b5a24 /exp2.c
parent5f8b0003bd8e01793f95d941f8d0b3e547f3cd34 (diff)
downloadmpfr-52265d509a30387d337be70b117716d6e248bf18.tar.gz
fixed infinite loop for 2^integer
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2134 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'exp2.c')
-rw-r--r--exp2.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/exp2.c b/exp2.c
index 6f93c8eec..1d2bb43ba 100644
--- a/exp2.c
+++ b/exp2.c
@@ -24,16 +24,16 @@ MA 02111-1307, USA. */
#include "mpfr.h"
#include "mpfr-impl.h"
- /* The computation of y=pow(2,z) is done by
+ /* The computation of y = 2^z is done by
- y=exp(z*log(2))=2^z
+ y = exp(z*log(2)). The result is exact iff z is an integer.
*/
int
mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
- int inexact =0;
+ int inexact;
if (MPFR_IS_NAN(x))
{
@@ -67,6 +67,19 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
if (mpfr_cmp_si_2exp (x, __gmpfr_emin - 1, 0) < 0)
return mpfr_set_underflow (y, rnd_mode, 1);
+ if (mpfr_isinteger (x)) /* we know that x >= 2^(emin-1) */
+ {
+ double xd;
+
+ if (mpfr_cmp_si_2exp (x, __mpfr_emax, 0) > 0)
+ return mpfr_set_overflow (y, rnd_mode, 1);
+
+ xd = mpfr_get_d1 (x);
+
+ mpfr_set_ui (y, 1, GMP_RNDZ);
+ return mpfr_mul_2si (y, y, (long) xd, rnd_mode);
+ }
+
/* General case */
{
/* Declaration of the intermediary variable */
@@ -114,6 +127,6 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_clear (t);
mpfr_clear (te);
}
- return inexact;
+ return inexact;
}