From 27e857dc9e371f5dbd0656c254e4d3592adf6684 Mon Sep 17 00:00:00 2001 From: bdadoun Date: Wed, 27 Jun 2012 09:10:26 +0000 Subject: [src/div.c] correct handling of negative overflows [tests/div.dat] examples to exercise negative overflows git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@1182 211d60ee-9f03-0410-a15a-8952a2c7a4e4 --- src/div.c | 35 +++++++++++++++++++++++++++-------- tests/div.dat | 10 ++++++++-- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/div.c b/src/div.c index 45bc820..252a61f 100644 --- a/src/div.c +++ b/src/div.c @@ -18,6 +18,8 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/ . */ +#include + #include "mpc-impl.h" /* this routine deals with the case where w is zero */ @@ -242,6 +244,7 @@ mpc_div (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd) int underflow_re = 0, overflow_re = 0, underflow_im = 0, overflow_im = 0; mpfr_rnd_t rnd_re = MPC_RND_RE (rnd), rnd_im = MPC_RND_IM (rnd); int saved_underflow, saved_overflow; + int tmpsgn; /* According to the C standard G.3, there are three types of numbers: */ /* finite (both parts are usual real numbers; contains 0), infinite */ @@ -311,20 +314,36 @@ mpc_div (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd) hopefully, the side-effects of mpc_mul do indeed raise the mpfr exceptions */ if (overflow_prod) { - mpfr_nextabove (mpc_realref (res)); - if (mpfr_inf_p (mpc_realref (res))) + tmpsgn = mpfr_sgn (mpc_realref(res)); + if (tmpsgn > 0) + mpfr_nextabove (mpc_realref(res)); + else if (tmpsgn < 0) + mpfr_nextbelow (mpc_realref(res)); + if (mpfr_inf_p (mpc_realref(res))) { - mpfr_set_inf (mpc_realref (res), mpfr_sgn (mpc_realref (res))); + mpfr_set_inf (mpc_realref(res), tmpsgn); overflow_re = 1; } - else mpfr_nextbelow (mpc_realref (res)); - mpfr_nextabove (mpc_imagref (res)); - if (mpfr_inf_p (mpc_imagref (res))) + else + if (tmpsgn > 0) + mpfr_nextbelow (mpc_realref(res)); + else if (tmpsgn < 0) + mpfr_nextabove (mpc_realref(res)); + tmpsgn = mpfr_sgn (mpc_imagref(res)); + if (tmpsgn > 0) + mpfr_nextabove (mpc_imagref(res)); + else if (tmpsgn < 0) + mpfr_nextbelow (mpc_imagref(res)); + if (mpfr_inf_p (mpc_imagref(res))) { - mpfr_set_inf (mpc_imagref (res), mpfr_sgn (mpc_imagref (res))); + mpfr_set_inf (mpc_imagref(res), tmpsgn); overflow_im = 1; } - else mpfr_nextbelow (mpc_imagref (res)); + else + if (tmpsgn > 0) + mpfr_nextbelow (mpc_imagref(res)); + else if (tmpsgn < 0) + mpfr_nextabove (mpc_imagref(res)); mpc_set (a, res, rnd); goto end; } diff --git a/tests/div.dat b/tests/div.dat index a7383aa..2cffc7e 100644 --- a/tests/div.dat +++ b/tests/div.dat @@ -2468,7 +2468,13 @@ # current result: (@NaN@ @Inf@) #0 0 10 0 10 1 10 -0b1@-536870913 10 0b1@536870912 10 0b1@536870912 10 0b1@-536870913 N N -# example to exercise overflow (re) +# examples to exercise overflow (re) +# positive overflow + 0 2 inf 2 0 10 0x3ffp1073741813 10 0x3ffp1073741813 10 0x2abp-10 10 0x2abp-10 N N -# example to exercise overflow (im) +# negative overflow +- 0 2 -inf 2 0 10 -0x3ffp1073741813 10 -0x3ffp1073741813 10 0x2abp-10 10 0x2abp-10 N N +# examples to exercise overflow (im) +# positive overflow 0 + 2 0 2 inf 10 0x3ffp1073741813 10 0x3ffp1073741813 10 0x2abp-10 10 -0x2abp-10 N N +# negative overflow +0 - 2 0 2 -inf 10 -0x3ffp1073741813 10 -0x3ffp1073741813 10 0x2abp-10 10 -0x2abp-10 N N -- cgit v1.2.1