summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--src/exp.c16
-rw-r--r--tests/exp.dat3
3 files changed, 13 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 801d358..afaa3f5 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ Changes in version 0.8.3:
mpc_pow_z when the exponent fits in a long
- Bug fixes:
- trigonometric functions: infinite loop due to overflow for large arguments
+ - exp: close to infinite loop for argument close to 0
Changes in version 0.8.2:
- Speed-up of mpc_pow_ui through binary exponentiation
diff --git a/src/exp.c b/src/exp.c
index 21d4154..d304c62 100644
--- a/src/exp.c
+++ b/src/exp.c
@@ -148,8 +148,13 @@ mpc_exp (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
/* from now on, both parts of op are regular numbers */
- prec = MPC_MAX_PREC(rop);
-
+ prec = MPC_MAX_PREC(rop)
+ + MPC_MAX (MPC_MAX (-mpfr_get_exp (MPC_RE (op)), 0),
+ -mpfr_get_exp (MPC_IM (op)));
+ /* When op is close to 0, then exp is close to 1+Re(op), while
+ cos is close to 1-Im(op); to decide on the ternary value of exp*cos,
+ we need a high enough precision so that none of exp or cos is
+ computed as 1. */
mpfr_init2 (x, 2);
mpfr_init2 (y, 2);
mpfr_init2 (z, 2);
@@ -166,10 +171,9 @@ mpc_exp (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
could be represented in the precision of rop. */
mpfr_clear_overflow ();
mpfr_clear_underflow ();
- mpfr_exp (x, MPC_RE(op), GMP_RNDN);
- mpfr_sin_cos (z, y, MPC_IM(op), GMP_RNDN);
- mpfr_mul (y, y, x, GMP_RNDN);
-
+ mpfr_exp (x, MPC_RE(op), GMP_RNDN); /* error <= 0.5ulp */
+ mpfr_sin_cos (z, y, MPC_IM(op), GMP_RNDN); /* errors <= 0.5ulp */
+ mpfr_mul (y, y, x, GMP_RNDN); /* error <= 2ulp */
ok = mpfr_overflow_p () || mpfr_zero_p (x)
|| mpfr_can_round (y, prec - 2, GMP_RNDN, GMP_RNDZ,
MPFR_PREC(MPC_RE(rop)) + (MPC_RND_RE(rnd) == GMP_RNDN));
diff --git a/tests/exp.dat b/tests/exp.dat
index f9c5fa3..5c9c978 100644
--- a/tests/exp.dat
+++ b/tests/exp.dat
@@ -1,6 +1,6 @@
# Data file for mpc_exp.
#
-# Copyright (C) 2008, 2010 Philippe Th\'eveny, Andreas Enge
+# Copyright (C) 2008, 2010 Philippe Th\'eveny, Andreas Enge, Paul Zimmermann
#
# This file is part of the MPC Library.
#
@@ -116,4 +116,5 @@
# overflow
- - 2 -inf 2 -inf 53 0x3312ae437f94441ec@-9 53 0xe45f7bab0595dd700@-10 N N
+# input close to 0
? ? 53 1 53 0x5D7A2148071Fp-7213522 53 0x1E02AE0D0F6Fp-7213521 53 0x5D7A2148071Fp-7213522 N N