diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-02-24 10:22:17 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-02-24 10:22:17 +0000 |
commit | d262be1ddeef4cb6ace2a17c054d469028400b1f (patch) | |
tree | 2837af3a0fbc16d8cf685965d5efa0e589194216 | |
parent | 18b6f246cb44743e1de764ed715fd24255a0b9ea (diff) | |
download | mpfr-d262be1ddeef4cb6ace2a17c054d469028400b1f.tar.gz |
[src/sum.c] Virtually eliminate halfway cases by making them equivalent
to a non-halfway case.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/new-sum@9298 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | src/sum.c | 19 |
1 files changed, 15 insertions, 4 deletions
@@ -843,9 +843,21 @@ sum_aux (mpfr_ptr sum, mpfr_ptr *const x, unsigned long n, mpfr_rnd_t rnd, else if (maxexp != MPFR_EXP_MIN) sst = 1; else - do - sst = wp[ws] != 0; - while (sst == 0 && ws-- > 0); + { + do + sst = wp[ws] != 0; + while (sst == 0 && ws-- > 0); + if (sst == 0 && tmd == 2) + { + /* For halfway cases, let's virtually eliminate them + by setting a sst equivalent to a non-halfway case, + which depends on the last bit of the pre-rounded + result and the sign. */ + MPFR_ASSERTD (rnd == MPFR_RNDN); + sst = (sump[0] & MPFR_LIMB_ONE) ? + (pos ? 1 : -1) : (pos ? -1 : 1); + } + } MPFR_LOG_MSG (("[Step 8] tmd=%d rbit=%d sst=%d\n", tmd, rbit != 0, sst)); @@ -855,7 +867,6 @@ sum_aux (mpfr_ptr sum, mpfr_ptr *const x, unsigned long n, mpfr_rnd_t rnd, MPFR_IS_LIKE_RNDU (rnd, pos ? 1 : -1) ? (sst ? 1 : 0) : (MPFR_ASSERTD (rnd == MPFR_RNDN), tmd == 1 ? - sst : sst); - /* Note: halfway cases may have to be corrected. */ /* TODO: possible correction of the value (+/- 1 ulp)... */ |