diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-08-23 14:25:50 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-08-23 14:25:50 +0000 |
commit | be52e961cc205f2df4c0b9eb194ebfaa6f9dabbc (patch) | |
tree | 7a580c8b05c309c498dbf9fbfbc4cd0b4a320dbb /sub.c | |
parent | eb7aca4237f84704bfc5fb631e5d80fcead83424 (diff) | |
download | mpfr-be52e961cc205f2df4c0b9eb194ebfaa6f9dabbc.tar.gz |
fixed bug for (2^53+4) - 1
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@1139 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'sub.c')
-rw-r--r-- | sub.c | 8 |
1 files changed, 5 insertions, 3 deletions
@@ -120,7 +120,7 @@ mpfr_sub1 (a, b, c, rnd_mode, diff_exp) /* case 1: diff_exp>=prec(a), i.e. c only affects the last bit through rounding */ - dif = MPFR_PREC(a) - diff_exp; + dif = MPFR_PREC(a) + cancel - diff_exp; #ifdef DEBUG printf("MPFR_PREC(a)=%d an=%u MPFR_PREC(b)=%d bn=%u MPFR_PREC(c)=%d diff_exp=%u dif=%d cancel=%d\n", @@ -153,9 +153,12 @@ mpfr_sub1 (a, b, c, rnd_mode, diff_exp) mp_limb_t *cp2 = cp + (cn-1); /* highest limb */ + /* first check if highest limb is 2^(BITS_PER_MP_LIMB-1) */ cc = *cp2 - MP_LIMB_T_HIGHBIT; + /* then check if low significant limbs are zero */ while (cc == 0 && cp2 > cp) cc = *--cp2; + /* now c is an exact power of two iff cc = 0 */ if (cc || ((ap[0] >> sh) & ONE)) goto sub_one_ulp; /* mant(c)>1/2 or mant(c) = 1/2: subtract 1 iff lsb(a)=1 */ @@ -302,8 +305,7 @@ mpfr_sub1 (a, b, c, rnd_mode, diff_exp) /* first copy upper part of c into a (after shift) */ int overlap; - dif += cancel; - k = (dif-1)/BITS_PER_MP_LIMB + 1; /* only the highest k limbs from c + k = (dif - 1) / BITS_PER_MP_LIMB + 1; /* only the highest k limbs from c have to be considered */ if (k<an) { MPN_ZERO(ap+k, an-k); /* do it now otherwise ap[k] may be |