summaryrefslogtreecommitdiff
path: root/exp_2.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2006-11-19 21:27:33 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2006-11-19 21:27:33 +0000
commitfafeeb62e6bfd9fe05fa6bd2ff008f9808adb378 (patch)
tree73cc872aa5c754ddcc4b91dd7bd07a24caed158c /exp_2.c
parent689e8e9280941fcaa299b7e40d2eefae6cf3a762 (diff)
downloadmpfr-fafeeb62e6bfd9fe05fa6bd2ff008f9808adb378.tar.gz
replaced double by mpfr_t (problem on 64-bit machines)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@4240 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'exp_2.c')
-rw-r--r--exp_2.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/exp_2.c b/exp_2.c
index c3a67ec4d..6a22cc899 100644
--- a/exp_2.c
+++ b/exp_2.c
@@ -82,7 +82,6 @@ mpz_normalize2 (mpz_t rop, mpz_t z, mp_exp_t expz, mp_exp_t target)
int
mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
- double d;
long n;
unsigned long K, k, l, err; /* FIXME: Which type ? */
int error_r;
@@ -96,10 +95,15 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
precy = MPFR_PREC(y);
- d = mpfr_get_d1 (x) / LOG2;
- /* FIXME: d may be too large if one decides to change mp_exp_t */
- MPFR_ASSERTN (d >= LONG_MIN && d <= LONG_MAX);
- n = (long) d;
+ /* Warning: we cannot use the 'double' type here, since on 64-bit machines
+ x may be as large as 2^62*log(2) without overflow, and then x/log(2)
+ is about 2^62: not every integer of that size can be represented as a
+ 'double', thus the argument reduction would fail. */
+ mpfr_init2 (r, sizeof (long) * CHAR_BIT);
+ mpfr_const_log2 (r, GMP_RNDZ);
+ mpfr_div (r, x, r, GMP_RNDN);
+ n = mpfr_get_si (r, GMP_RNDN);
+ mpfr_clear (r);
MPFR_LOG_MSG (("d(x)=%1.30e n=%ld\n", mpfr_get_d1(x), n));
/* error bounds the cancelled bits in x - n*log(2) */