summaryrefslogtreecommitdiff
path: root/sinh.c
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-05-17 15:17:32 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-05-17 15:17:32 +0000
commitc93e470c6407423e5179433f8da807d90a258511 (patch)
tree6668c00481fc0ce21c4050a7fc67d6da00f2ebac /sinh.c
parentab9a50230ebbe597c4fa3bf06d87fe9cdd6f13c7 (diff)
downloadmpfr-c93e470c6407423e5179433f8da807d90a258511.tar.gz
Improve way of handling overflow (still not perfect but far better).
Improve coverage test. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3578 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'sinh.c')
-rw-r--r--sinh.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/sinh.c b/sinh.c
index b871d049c..4ac3a1786 100644
--- a/sinh.c
+++ b/sinh.c
@@ -27,7 +27,7 @@ MA 02111-1307, USA. */
int
mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode)
-{
+{
mpfr_t x;
int inexact;
@@ -38,11 +38,11 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode)
{
if (MPFR_IS_NAN(xt))
{
- MPFR_SET_NAN(y);
+ MPFR_SET_NAN(y);
MPFR_RET_NAN;
}
else if (MPFR_IS_INF(xt))
- {
+ {
MPFR_SET_INF(y);
MPFR_SET_SAME_SIGN(y, xt);
MPFR_RET(0);
@@ -63,7 +63,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode)
{
mpfr_t t, ti;
- mp_exp_t d;
+ mp_exp_t d;
mp_prec_t Nt; /* Precision of the intermediary variable */
long int err; /* Precision of error */
MPFR_ZIV_DECL (loop);
@@ -86,28 +86,30 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode)
for (;;) {
/* compute sinh */
mpfr_clear_overflow ();
+ mpfr_clear_underflow ();
mpfr_exp (t, x, GMP_RNDD); /* exp(x) */
/* exp(x) can overflow or underflow or return ~1 ! */
- d = MPFR_GET_EXP (t);
- if (MPFR_UNLIKELY (mpfr_overflow_p ())) {
- MPFR_SET_INF (t);
+ if (MPFR_UNLIKELY (mpfr_overflow_p () || mpfr_underflow_p ())) {
+ mpfr_overflow (t, rnd_mode,
+ mpfr_overflow_p () ? MPFR_SIGN_POS : MPFR_SIGN_NEG);
break;
}
+ d = MPFR_GET_EXP (t);
mpfr_ui_div (ti, 1, t, GMP_RNDU); /* 1/exp(x) */
mpfr_sub (t, t, 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) */
err = 0;
if (!MPFR_IS_ZERO (t))
{
/* calculation of the error */
- d = d - MPFR_GET_EXP (t) + 2;
+ d = d - MPFR_GET_EXP (t) + 2;
/* error estimate */
/* err = Nt-(__gmpfr_ceil_log2(1+pow(2,d)));*/
err = Nt - (MAX (d, 0) + 1);
-
+
if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, MPFR_PREC (y), rnd_mode)))
break;
}