summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2015-02-24 10:22:17 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2015-02-24 10:22:17 +0000
commitd262be1ddeef4cb6ace2a17c054d469028400b1f (patch)
tree2837af3a0fbc16d8cf685965d5efa0e589194216
parent18b6f246cb44743e1de764ed715fd24255a0b9ea (diff)
downloadmpfr-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.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/sum.c b/src/sum.c
index 7f1319063..3d58d3189 100644
--- a/src/sum.c
+++ b/src/sum.c
@@ -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)... */