summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2015-06-12 13:27:00 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2015-06-12 13:27:00 +0000
commit6a2da610b91aa35bc66c8fc5f6206910c33bc02b (patch)
treee40675cc958fc19fea786a3a251b6039f00b9be8
parenta6e65f3d430315e6d40d82d7bd0f2e3a1224ef88 (diff)
downloadmpfr-6a2da610b91aa35bc66c8fc5f6206910c33bc02b.tar.gz
[src/fma.c] Completely fixed the scaling in case of underflow.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9569 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--src/fma.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/fma.c b/src/fma.c
index 297fe1355..33272125a 100644
--- a/src/fma.c
+++ b/src/fma.c
@@ -281,6 +281,7 @@ mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
MPFR_BLOCK_DECL (flags);
MPFR_BLOCK (flags, inexact = mpfr_add (s, u, new_z, rnd_mode));
+ MPFR_LOG_MSG (("inexact=%d\n", inexact));
MPFR_GROUP_CLEAR (group);
if (scale != 0)
{
@@ -292,9 +293,15 @@ mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
is not possible, but let's check that anyway. */
MPFR_ASSERTN (! MPFR_OVERFLOW (flags)); /* TODO... */
MPFR_ASSERTN (! MPFR_UNDERFLOW (flags)); /* not possible */
+ if (rnd_mode == MPFR_RNDN &&
+ MPFR_GET_EXP (s) == __gmpfr_emin - 1 + scale &&
+ mpfr_powerof2_raw (s))
+ {
+ MPFR_LOG_MSG (("Double rounding\n", 0));
+ rnd_mode = (MPFR_IS_NEG (s) ? inexact <= 0 : inexact >= 0)
+ ? MPFR_RNDZ : MPFR_RNDA;
+ }
inex2 = mpfr_div_2ui (s, s, scale, rnd_mode);
- /* FIXME: Handle the double rounding case:
- s / 2^scale = 2^(emin - 2) in MPFR_RNDN. */
MPFR_LOG_MSG (("inex2=%d\n", inex2));
if (inex2) /* underflow */
inexact = inex2;