summaryrefslogtreecommitdiff
path: root/src/sub1sp.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2018-02-15 18:42:18 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2018-02-15 18:42:18 +0000
commit2d620bac6f1ac70d854da8d5c91c0e8c05e24a62 (patch)
treec7be672e886e4f7f315bf9a837ee186c2595ac51 /src/sub1sp.c
parentc52d8468fcdfb68470eb191e2bdbcfdead5d5a62 (diff)
downloadmpfr-2d620bac6f1ac70d854da8d5c91c0e8c05e24a62.tar.gz
[src/sub1sp.c] fixed bug20180215()
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@12251 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src/sub1sp.c')
-rw-r--r--src/sub1sp.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/sub1sp.c b/src/sub1sp.c
index de22c5284..4f2360fe4 100644
--- a/src/sub1sp.c
+++ b/src/sub1sp.c
@@ -1620,8 +1620,8 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mpn_sub_n (ap, MPFR_MANT(b), cp, n);
/* mpfr_print_mant_binary("Sub= ", ap, p); */
- /* Normalize: we lose at most one bit */
- if (MPFR_UNLIKELY(MPFR_LIMB_MSB(ap[n-1]) == 0))
+ /* Normalize: we lose at most one bit */
+ if (MPFR_LIMB_MSB(ap[n-1]) == 0)
{
/* High bit is not set and we have to fix it! */
/* We can assume B >= 2^(p+1) up to scaling by 2^e,
@@ -1645,16 +1645,27 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
MPFR_ASSERTD( !(ap[0] & ~mask) );
+ /* if {ap, n} is a power of 2 and rb <> 0, we subtract 1 */
+ if (MPFR_UNLIKELY(MPFR_LIMB_MSB(ap[n-1]) == MPFR_LIMB_HIGHBIT &&
+ mpfr_powerof2_raw (a)))
+ {
+ mpn_sub_1 (ap, ap, n, MPFR_LIMB_ONE << sh);
+ ap[n-1] |= MPFR_LIMB_HIGHBIT;
+ bx--;
+ rb = rbb;
+ sb = sbb;
+ }
+
/* Rounding */
if (MPFR_LIKELY(rnd_mode == MPFR_RNDF))
goto truncate;
else if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
{
- if (MPFR_LIKELY(rb == 0))
+ if (rb == 0)
goto truncate;
else if (sb != 0 || (ap[0] & (MPFR_LIMB_ONE << sh)) != 0)
goto next_below;
- else
+ else /* rb = 1, sb = 0, even rule */
goto truncate;
}
else