diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-01-16 08:29:34 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-01-16 08:29:34 +0000 |
commit | a672495b2d38557c2ea044f3ae48d619d1dcdc6d (patch) | |
tree | 8f6f274fd8bdd1403f2042c77c0f6a8da98cc66a /src/fmma.c | |
parent | b12a5184c074f0756527379522df35e5357ae68c (diff) | |
download | mpfr-a672495b2d38557c2ea044f3ae48d619d1dcdc6d.tar.gz |
try to fix bugs in fmma (work in progress)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9820 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src/fmma.c')
-rw-r--r-- | src/fmma.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/fmma.c b/src/fmma.c index 8692061ab..80b1f9edc 100644 --- a/src/fmma.c +++ b/src/fmma.c @@ -53,6 +53,7 @@ mpfr_fmma_fast (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_t u, v; mp_size_t an, bn, cn, dn; mpfr_limb_ptr up, vp; + unsigned int saved_flags = __gmpfr_flags; MPFR_TMP_DECL(marker); MPFR_SAVE_EXPO_DECL (expo); @@ -76,6 +77,8 @@ mpfr_fmma_fast (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c, { mpn_lshift (up, up, an + bn, 1); MPFR_SET_EXP (u, MPFR_EXP(a) + MPFR_EXP(b) - 1); + if (MPFR_UNLIKELY(MPFR_EXP(u) == __MPFR_EXP_INF)) + goto failure; } else MPFR_SET_EXP (u, MPFR_EXP(a) + MPFR_EXP(b)); @@ -89,6 +92,8 @@ mpfr_fmma_fast (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c, { mpn_lshift (vp, vp, cn + dn, 1); MPFR_SET_EXP (v, MPFR_EXP(c) + MPFR_EXP(d) - 1); + if (MPFR_UNLIKELY(MPFR_EXP(v) == __MPFR_EXP_INF)) + goto failure; } else MPFR_SET_EXP (v, MPFR_EXP(c) + MPFR_EXP(d)); @@ -107,6 +112,12 @@ mpfr_fmma_fast (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c, MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (z, inex, rnd); + + failure: + __gmpfr_flags = saved_flags; + MPFR_TMP_FREE(marker); + MPFR_SAVE_EXPO_FREE (expo); + return mpfr_fmma_slow (z, a, b, c, d, rnd); } /* z <- a*b + c*d */ |