diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-11-10 01:45:36 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-11-10 01:45:36 +0000 |
commit | f1c41fb6bd97c0a5680aa4df1a00a01f4a4d0d60 (patch) | |
tree | 08e27e3c47d4584830acca621cbe6364d1386d37 /add.c | |
parent | 3bdb8b4f6f3ab6fc0c2aa5f71535a2c7133cc04c (diff) | |
download | mpfr-f1c41fb6bd97c0a5680aa4df1a00a01f4a4d0d60.tar.gz |
GNU coding style. K&R function headers removed.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@1488 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'add.c')
-rw-r--r-- | add.c | 906 |
1 files changed, 446 insertions, 460 deletions
@@ -25,24 +25,13 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" -#define ONE ((mp_limb_t) 1) - /* signs of b and c are supposed equal, diff_exp is the difference between the exponents of b and c, which is supposed >= 0 */ int -#if __STDC__ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode, mp_exp_unsigned_t diff_exp) -#else -mpfr_add1 (a, b, c, rnd_mode, diff_exp) - mpfr_ptr a; - mpfr_srcptr b; - mpfr_srcptr c; - mp_rnd_t rnd_mode; - mp_exp_unsigned_t diff_exp; -#endif { mp_limb_t *ap, *bp, *cp; mp_prec_t aq, bq, cq, aq2; @@ -60,16 +49,17 @@ mpfr_add1 (a, b, c, rnd_mode, diff_exp) cp = MPFR_MANT(c); if (ap == bp) - { - bp = (mp_ptr) TMP_ALLOC(MPFR_ABSSIZE(b) * BYTES_PER_MP_LIMB); - MPN_COPY (bp, ap, MPFR_ABSSIZE(b)); - if (ap == cp) { cp = bp; } - } + { + bp = (mp_ptr) TMP_ALLOC(MPFR_ABSSIZE(b) * BYTES_PER_MP_LIMB); + MPN_COPY (bp, ap, MPFR_ABSSIZE(b)); + if (ap == cp) + { cp = bp; } + } else if (ap == cp) - { - cp = (mp_ptr) TMP_ALLOC (MPFR_ABSSIZE(c) * BYTES_PER_MP_LIMB); - MPN_COPY(cp, ap, MPFR_ABSSIZE(c)); - } + { + cp = (mp_ptr) TMP_ALLOC (MPFR_ABSSIZE(c) * BYTES_PER_MP_LIMB); + MPN_COPY(cp, ap, MPFR_ABSSIZE(c)); + } aq = MPFR_PREC(a); bq = MPFR_PREC(b); @@ -105,118 +95,118 @@ mpfr_add1 (a, b, c, rnd_mode, diff_exp) rb = fb = -1; /* means: not initialized */ if (aq2 <= diff_exp) - { /* c does not overlap with a' */ - if (an > bn) - { /* a has more limbs than b */ - /* copy b to the most significant limbs of a */ - MPN_COPY(ap + (an - bn), bp, bn); - /* zero the least significant limbs of a */ - MPN_ZERO(ap, an - bn); - } - else /* an <= bn */ - { - /* copy the most significant limbs of b to a */ - MPN_COPY(ap, bp + (bn - an), an); + { /* c does not overlap with a' */ + if (an > bn) + { /* a has more limbs than b */ + /* copy b to the most significant limbs of a */ + MPN_COPY(ap + (an - bn), bp, bn); + /* zero the least significant limbs of a */ + MPN_ZERO(ap, an - bn); + } + else /* an <= bn */ + { + /* copy the most significant limbs of b to a */ + MPN_COPY(ap, bp + (bn - an), an); + } } - } else /* aq2 > diff_exp */ - { /* c overlaps with a' */ - mp_limb_t *a2p; - mp_limb_t cc; - mp_prec_t dif; - mp_size_t difn, k; - int shift; + { /* c overlaps with a' */ + mp_limb_t *a2p; + mp_limb_t cc; + mp_prec_t dif; + mp_size_t difn, k; + int shift; - /* copy c (shifted) into a */ + /* copy c (shifted) into a */ - dif = aq2 - diff_exp; - /* dif is the number of bits of c which overlap with a' */ + dif = aq2 - diff_exp; + /* dif is the number of bits of c which overlap with a' */ - difn = (dif-1)/BITS_PER_MP_LIMB + 1; - /* only the highest difn limbs from c have to be considered */ - if (difn > cn) - { - /* c doesn't have enough limbs; take into account the virtual - zero limbs now by zeroing the least significant limbs of a' */ - MPFR_ASSERTN(difn - cn <= an); - MPN_ZERO(ap, difn - cn); - difn = cn; - } - - k = diff_exp / BITS_PER_MP_LIMB; + difn = (dif-1)/BITS_PER_MP_LIMB + 1; + /* only the highest difn limbs from c have to be considered */ + if (difn > cn) + { + /* c doesn't have enough limbs; take into account the virtual + zero limbs now by zeroing the least significant limbs of a' */ + MPFR_ASSERTN(difn - cn <= an); + MPN_ZERO(ap, difn - cn); + difn = cn; + } - /* zero the most significant k limbs of a */ - a2p = ap + (an - k); - MPN_ZERO(a2p, k); + k = diff_exp / BITS_PER_MP_LIMB; - shift = diff_exp % BITS_PER_MP_LIMB; + /* zero the most significant k limbs of a */ + a2p = ap + (an - k); + MPN_ZERO(a2p, k); - if (shift) - { - MPFR_ASSERTN(a2p - difn >= ap); - cc = mpn_rshift(a2p - difn, cp + (cn - difn), difn, shift); - if (a2p - difn > ap) - *(a2p - difn - 1) = cc; - } - else - MPN_COPY(a2p - difn, cp + (cn - difn), difn); + shift = diff_exp % BITS_PER_MP_LIMB; - /* add b to a */ + if (shift) + { + MPFR_ASSERTN(a2p - difn >= ap); + cc = mpn_rshift(a2p - difn, cp + (cn - difn), difn, shift); + if (a2p - difn > ap) + *(a2p - difn - 1) = cc; + } + else + MPN_COPY(a2p - difn, cp + (cn - difn), difn); - cc = an > bn - ? mpn_add_n(ap + (an - bn), ap + (an - bn), bp, bn) - : mpn_add_n(ap, ap, bp + (bn - an), an); + /* add b to a */ - if (cc) /* carry */ - { - mp_exp_t exp = MPFR_EXP(a); - if (exp == __mpfr_emax) - { - inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a)); - goto end_of_add; - } - MPFR_EXP(a)++; - rb = (ap[0] >> sh) & 1; /* LSB(a) --> rounding bit after the shift */ - if (sh) - { - mp_limb_t mask, bb; + cc = an > bn + ? mpn_add_n(ap + (an - bn), ap + (an - bn), bp, bn) + : mpn_add_n(ap, ap, bp + (bn - an), an); - mask = (ONE << sh) - 1; - bb = ap[0] & mask; - ap[0] &= (~mask) << 1; - if (bb == 0) - fb = 0; - else if (bb == mask) - fb = 1; - } - mpn_rshift(ap, ap, an, 1); - ap[an-1] += MP_LIMB_T_HIGHBIT; - if (sh && fb < 0) - goto rounding; - } /* cc */ - } /* aq2 > diff_exp */ + if (cc) /* carry */ + { + mp_exp_t exp = MPFR_EXP(a); + if (exp == __mpfr_emax) + { + inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a)); + goto end_of_add; + } + MPFR_EXP(a)++; + rb = (ap[0] >> sh) & 1; /* LSB(a) --> rounding bit after the shift */ + if (sh) + { + mp_limb_t mask, bb; + + mask = (MP_LIMB_T_ONE << sh) - 1; + bb = ap[0] & mask; + ap[0] &= (~mask) << 1; + if (bb == 0) + fb = 0; + else if (bb == mask) + fb = 1; + } + mpn_rshift(ap, ap, an, 1); + ap[an-1] += MP_LIMB_T_HIGHBIT; + if (sh && fb < 0) + goto rounding; + } /* cc */ + } /* aq2 > diff_exp */ /* non-significant bits of a */ if (rb < 0 && sh) - { - mp_limb_t mask, bb; - - mask = (ONE << sh) - 1; - bb = ap[0] & mask; - ap[0] &= ~mask; - rb = bb >> (sh - 1); - if (sh > 1) { - mask >>= 1; - bb &= mask; - if (bb == 0) - fb = 0; - else if (bb == mask) - fb = 1; - else - goto rounding; + mp_limb_t mask, bb; + + mask = (MP_LIMB_T_ONE << sh) - 1; + bb = ap[0] & mask; + ap[0] &= ~mask; + rb = bb >> (sh - 1); + if (sh > 1) + { + mask >>= 1; + bb &= mask; + if (bb == 0) + fb = 0; + else if (bb == mask) + fb = 1; + else + goto rounding; + } } - } /* determine rounding and sticky bits (and possible carry) */ @@ -226,292 +216,294 @@ mpfr_add1 (a, b, c, rnd_mode, diff_exp) n limbs from b won't be combined with c. */ if (bn > an) - { /* there are still limbs from b that haven't been taken into account */ - mp_size_t bk; + { /* there are still limbs from b that haven't been taken into account */ + mp_size_t bk; - if (fb == 0 && difw <= 0) - { - fb = 1; /* c hasn't been taken into account ==> sticky bit != 0 */ - goto rounding; - } - - bk = bn - an; /* index of lowest considered limb from b, > 0 */ - while (difw < 0) - { /* ulp(next limb from b) > msb(c) */ - mp_limb_t bb; - - bb = bp[--bk]; - - MPFR_ASSERTD(fb != 0); - if (fb > 0) - { - if (bb != MP_LIMB_T_MAX) + if (fb == 0 && difw <= 0) { fb = 1; /* c hasn't been taken into account ==> sticky bit != 0 */ goto rounding; } - } - else /* fb not initialized yet */ - { - if (rb < 0) /* rb not initialized yet */ - { - rb = bb >> (BITS_PER_MP_LIMB - 1); - bb |= MP_LIMB_T_HIGHBIT; - } - fb = 1; - if (bb != MP_LIMB_T_MAX) - goto rounding; - } - - if (bk == 0) - { /* b has entirely been read */ - fb = 1; /* c hasn't been taken into account ==> sticky bit != 0 */ - goto rounding; - } - - difw++; - } /* while */ - MPFR_ASSERTN(bk > 0 && difw >= 0); - - if (difw <= cn) - { - mp_size_t ck; - mp_limb_t cprev; - int difs; - ck = cn - difw; - difs = diff_exp % BITS_PER_MP_LIMB; + bk = bn - an; /* index of lowest considered limb from b, > 0 */ + while (difw < 0) + { /* ulp(next limb from b) > msb(c) */ + mp_limb_t bb; - if (difs == 0 && ck == 0) - goto c_read; - - cprev = ck == cn ? 0 : cp[ck]; - - if (fb < 0) - { - mp_limb_t bb, cc; + bb = bp[--bk]; - if (difs) - { - cc = cprev << (BITS_PER_MP_LIMB - difs); - if (--ck >= 0) - { - cprev = cp[ck]; - cc += cprev >> difs; - } - } - else - cc = cp[--ck]; + MPFR_ASSERTD(fb != 0); + if (fb > 0) + { + if (bb != MP_LIMB_T_MAX) + { + fb = 1; /* c hasn't been taken into account + ==> sticky bit != 0 */ + goto rounding; + } + } + else /* fb not initialized yet */ + { + if (rb < 0) /* rb not initialized yet */ + { + rb = bb >> (BITS_PER_MP_LIMB - 1); + bb |= MP_LIMB_T_HIGHBIT; + } + fb = 1; + if (bb != MP_LIMB_T_MAX) + goto rounding; + } - bb = bp[--bk] + cc; + if (bk == 0) + { /* b has entirely been read */ + fb = 1; /* c hasn't been taken into account + ==> sticky bit != 0 */ + goto rounding; + } - if (bb < cc /* carry */ - && (rb < 0 || (rb ^= 1) == 0) - && mpn_add_1(ap, ap, an, ONE<<sh)) - { - mp_exp_t exp = MPFR_EXP(a); - if (exp == __mpfr_emax) - { - inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a)); - goto end_of_add; - } - MPFR_EXP(a)++; - ap[an-1] = MP_LIMB_T_HIGHBIT; - rb = 0; - } + difw++; + } /* while */ + MPFR_ASSERTN(bk > 0 && difw >= 0); - if (rb < 0) /* rb not initialized yet */ + if (difw <= cn) { - rb = bb >> (BITS_PER_MP_LIMB - 1); - bb <<= 1; - bb |= bb >> (BITS_PER_MP_LIMB - 1); - } + mp_size_t ck; + mp_limb_t cprev; + int difs; - fb = bb != 0; - if (fb && bb != MP_LIMB_T_MAX) - goto rounding; - } /* fb < 0 */ + ck = cn - difw; + difs = diff_exp % BITS_PER_MP_LIMB; - while (bk > 0) - { - mp_limb_t bb, cc; - - if (difs) - { - if (ck < 0) - goto c_read; - cc = cprev << (BITS_PER_MP_LIMB - difs); - if (--ck >= 0) - { - cprev = cp[ck]; - cc += cprev >> difs; - } - } - else - { - if (ck == 0) + if (difs == 0 && ck == 0) goto c_read; - cc = cp[--ck]; - } - bb = bp[--bk] + cc; - if (bb < cc) /* carry */ - { - fb ^= 1; - if (fb) + cprev = ck == cn ? 0 : cp[ck]; + + if (fb < 0) + { + mp_limb_t bb, cc; + + if (difs) + { + cc = cprev << (BITS_PER_MP_LIMB - difs); + if (--ck >= 0) + { + cprev = cp[ck]; + cc += cprev >> difs; + } + } + else + cc = cp[--ck]; + + bb = bp[--bk] + cc; + + if (bb < cc /* carry */ + && (rb < 0 || (rb ^= 1) == 0) + && mpn_add_1(ap, ap, an, MP_LIMB_T_ONE << sh)) + { + mp_exp_t exp = MPFR_EXP(a); + if (exp == __mpfr_emax) + { + inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a)); + goto end_of_add; + } + MPFR_EXP(a)++; + ap[an-1] = MP_LIMB_T_HIGHBIT; + rb = 0; + } + + if (rb < 0) /* rb not initialized yet */ + { + rb = bb >> (BITS_PER_MP_LIMB - 1); + bb <<= 1; + bb |= bb >> (BITS_PER_MP_LIMB - 1); + } + + fb = bb != 0; + if (fb && bb != MP_LIMB_T_MAX) + goto rounding; + } /* fb < 0 */ + + while (bk > 0) + { + mp_limb_t bb, cc; + + if (difs) + { + if (ck < 0) + goto c_read; + cc = cprev << (BITS_PER_MP_LIMB - difs); + if (--ck >= 0) + { + cprev = cp[ck]; + cc += cprev >> difs; + } + } + else + { + if (ck == 0) + goto c_read; + cc = cp[--ck]; + } + + bb = bp[--bk] + cc; + if (bb < cc) /* carry */ + { + fb ^= 1; + if (fb) + goto rounding; + rb ^= 1; + if (rb == 0 && mpn_add_1(ap, ap, an, MP_LIMB_T_ONE << sh)) + { + mp_exp_t exp = MPFR_EXP(a); + if (exp == __mpfr_emax) + { + inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a)); + goto end_of_add; + } + MPFR_EXP(a)++; + ap[an-1] = MP_LIMB_T_HIGHBIT; + } + } /* bb < cc */ + + if (!fb && bb != 0) + { + fb = 1; + goto rounding; + } + if (fb && bb != MP_LIMB_T_MAX) + goto rounding; + } /* while */ + + /* b has entirely been read */ + + if (fb || ck < 0) goto rounding; - rb ^= 1; - if (rb == 0 && mpn_add_1(ap, ap, an, ONE<<sh)) - { - mp_exp_t exp = MPFR_EXP(a); - if (exp == __mpfr_emax) + if (difs && cprev << (BITS_PER_MP_LIMB - difs)) { - inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a)); - goto end_of_add; + fb = 1; + goto rounding; } - MPFR_EXP(a)++; - ap[an-1] = MP_LIMB_T_HIGHBIT; - } - } /* bb < cc */ - - if (!fb && bb != 0) - { - fb = 1; - goto rounding; - } - if (fb && bb != MP_LIMB_T_MAX) - goto rounding; - } /* while */ - - /* b has entirely been read */ - - if (fb || ck < 0) - goto rounding; - if (difs && cprev << (BITS_PER_MP_LIMB - difs)) - { - fb = 1; - goto rounding; - } - while (ck) - { - if (cp[--ck]) - { - fb = 1; - goto rounding; - } - } /* while */ - } /* difw <= cn */ - else - { /* c has entirely been read */ - c_read: - if (fb < 0) /* fb not initialized yet */ - { - mp_limb_t bb; - - MPFR_ASSERTN(bk > 0); - bb = bp[--bk]; - if (rb < 0) /* rb not initialized yet */ - { - rb = bb >> (BITS_PER_MP_LIMB - 1); - bb &= ~MP_LIMB_T_HIGHBIT; + while (ck) + { + if (cp[--ck]) + { + fb = 1; + goto rounding; + } + } /* while */ + } /* difw <= cn */ + else + { /* c has entirely been read */ + c_read: + if (fb < 0) /* fb not initialized yet */ + { + mp_limb_t bb; + + MPFR_ASSERTN(bk > 0); + bb = bp[--bk]; + if (rb < 0) /* rb not initialized yet */ + { + rb = bb >> (BITS_PER_MP_LIMB - 1); + bb &= ~MP_LIMB_T_HIGHBIT; + } + fb = bb != 0; + } /* fb < 0 */ + if (fb) + goto rounding; + while (bk) + { + if (bp[--bk]) + { + fb = 1; + goto rounding; + } + } /* while */ + } /* difw > cn */ + } /* bn > an */ + else if (fb != 1) /* if fb == 1, the sticky bit is 1 (no possible carry) */ + { /* b has entirely been read */ + if (difw > cn) + { /* c has entirely been read */ + if (rb < 0) + rb = 0; + fb = 0; } - fb = bb != 0; - } /* fb < 0 */ - if (fb) - goto rounding; - while (bk) - { - if (bp[--bk]) - { + else if (diff_exp > aq2) + { /* b is followed by at least a zero bit, then by c */ + if (rb < 0) + rb = 0; fb = 1; - goto rounding; } - } /* while */ - } /* difw > cn */ - } /* bn > an */ - else if (fb != 1) /* if fb == 1, the sticky bit is 1 (no possible carry) */ - { /* b has entirely been read */ - if (difw > cn) - { /* c has entirely been read */ - if (rb < 0) - rb = 0; - fb = 0; - } - else if (diff_exp > aq2) - { /* b is followed by at least a zero bit, then by c */ - if (rb < 0) - rb = 0; - fb = 1; - } - else - { - mp_size_t ck; - int difs; - - MPFR_ASSERTN(difw >= 0 && cn >= difw); - ck = cn - difw; - difs = diff_exp % BITS_PER_MP_LIMB; - - if (difs == 0 && ck == 0) - { /* c has entirely been read */ - if (rb < 0) - rb = 0; - fb = 0; - } else - { - mp_limb_t cc; - - cc = difs ? (MPFR_ASSERTN(ck < cn), - cp[ck] << (BITS_PER_MP_LIMB - difs)) : cp[--ck]; - if (rb < 0) { - rb = cc >> (BITS_PER_MP_LIMB - 1); - cc &= ~MP_LIMB_T_HIGHBIT; + mp_size_t ck; + int difs; + + MPFR_ASSERTN(difw >= 0 && cn >= difw); + ck = cn - difw; + difs = diff_exp % BITS_PER_MP_LIMB; + + if (difs == 0 && ck == 0) + { /* c has entirely been read */ + if (rb < 0) + rb = 0; + fb = 0; + } + else + { + mp_limb_t cc; + + cc = difs ? (MPFR_ASSERTN(ck < cn), + cp[ck] << (BITS_PER_MP_LIMB - difs)) : cp[--ck]; + if (rb < 0) + { + rb = cc >> (BITS_PER_MP_LIMB - 1); + cc &= ~MP_LIMB_T_HIGHBIT; + } + while (cc == 0) + { + if (ck == 0) + { + fb = 0; + goto rounding; + } + cc = cp[--ck]; + } /* while */ + fb = 1; + } } - while (cc == 0) - { - if (ck == 0) - { - fb = 0; - goto rounding; - } - cc = cp[--ck]; - } /* while */ - fb = 1; - } - } - } /* fb != 1 */ + } /* fb != 1 */ - rounding: + rounding: switch (rnd_mode) - { + { case GMP_RNDN: if (fb == 0) - { - if (rb == 0) { - inex = 0; - goto end_of_add; + if (rb == 0) + { + inex = 0; + goto end_of_add; + } + /* round to even */ + if (ap[0] & (MP_LIMB_T_ONE << sh)) + goto rndn_away; + else + goto rndn_zero; } - /* round to even */ - if (ap[0] & (ONE << sh)) - goto rndn_away; - else - goto rndn_zero; - } if (rb == 0) - { + { rndn_zero: - inex = MPFR_ISNEG(a) ? 1 : -1; - goto end_of_add; - } + inex = MPFR_ISNEG(a) ? 1 : -1; + goto end_of_add; + } else - { + { rndn_away: - inex = MPFR_ISNONNEG(a) ? 1 : -1; - goto add_one_ulp; - } + inex = MPFR_ISNONNEG(a) ? 1 : -1; + goto add_one_ulp; + } case GMP_RNDZ: inex = rb || fb ? (MPFR_ISNEG(a) ? 1 : -1) : 0; @@ -535,133 +527,127 @@ mpfr_add1 (a, b, c, rnd_mode, diff_exp) MPFR_ASSERTN(0); inex = 0; goto end_of_add; - } - - add_one_ulp: /* add one unit in last place to a */ - if (mpn_add_1(ap, ap, an, ONE<<sh)) - { - mp_exp_t exp = MPFR_EXP(a); - if (exp == __mpfr_emax) - inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a)); - else + } + + add_one_ulp: /* add one unit in last place to a */ + if (mpn_add_1(ap, ap, an, MP_LIMB_T_ONE << sh)) { - MPFR_EXP(a)++; - ap[an-1] = MP_LIMB_T_HIGHBIT; + mp_exp_t exp = MPFR_EXP(a); + if (exp == __mpfr_emax) + inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a)); + else + { + MPFR_EXP(a)++; + ap[an-1] = MP_LIMB_T_HIGHBIT; + } } - } - end_of_add: + end_of_add: TMP_FREE(marker); return inex; } int -#if __STDC__ mpfr_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode) -#else -mpfr_add (a, b, c, rnd_mode) - mpfr_ptr a; - mpfr_srcptr b; - mpfr_srcptr c; - mp_rnd_t rnd_mode; -#endif { if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c)) - { - MPFR_SET_NAN(a); - MPFR_RET_NAN; - } + { + MPFR_SET_NAN(a); + MPFR_RET_NAN; + } MPFR_CLEAR_NAN(a); if (MPFR_IS_INF(b)) - { - if (!MPFR_IS_INF(c) || MPFR_SIGN(b) == MPFR_SIGN(c)) { - MPFR_SET_INF(a); - MPFR_SET_SAME_SIGN(a, b); - MPFR_RET(0); /* exact */ - } - else - { - MPFR_SET_NAN(a); - MPFR_RET_NAN; + if (!MPFR_IS_INF(c) || MPFR_SIGN(b) == MPFR_SIGN(c)) + { + MPFR_SET_INF(a); + MPFR_SET_SAME_SIGN(a, b); + MPFR_RET(0); /* exact */ + } + else + { + MPFR_SET_NAN(a); + MPFR_RET_NAN; + } } - } else if (MPFR_IS_INF(c)) - { - MPFR_SET_INF(a); - MPFR_SET_SAME_SIGN(a, c); - MPFR_RET(0); /* exact */ - } + { + MPFR_SET_INF(a); + MPFR_SET_SAME_SIGN(a, c); + MPFR_RET(0); /* exact */ + } MPFR_ASSERTN(MPFR_IS_FP(b) && MPFR_IS_FP(c)); if (MPFR_IS_ZERO(b)) - { - if (MPFR_IS_ZERO(c)) { - if (MPFR_SIGN(a) != - (rnd_mode != GMP_RNDD ? - ((MPFR_SIGN(b) < 0 && MPFR_SIGN(c) < 0) ? -1 : 1) : - ((MPFR_SIGN(b) > 0 && MPFR_SIGN(c) > 0) ? 1 : -1))) - MPFR_CHANGE_SIGN(a); - MPFR_CLEAR_INF(a); - MPFR_SET_ZERO(a); - MPFR_RET(0); /* 0 + 0 is exact */ + if (MPFR_IS_ZERO(c)) + { + if (MPFR_SIGN(a) != + (rnd_mode != GMP_RNDD ? + ((MPFR_SIGN(b) < 0 && MPFR_SIGN(c) < 0) ? -1 : 1) : + ((MPFR_SIGN(b) > 0 && MPFR_SIGN(c) > 0) ? 1 : -1))) + { + MPFR_CHANGE_SIGN(a); + } + MPFR_CLEAR_INF(a); + MPFR_SET_ZERO(a); + MPFR_RET(0); /* 0 + 0 is exact */ + } + return mpfr_set(a, c, rnd_mode); } - return mpfr_set(a, c, rnd_mode); - } if (MPFR_IS_ZERO(c)) - { - return mpfr_set(a, b, rnd_mode); - } + { + return mpfr_set(a, b, rnd_mode); + } MPFR_CLEAR_INF(a); /* clear Inf flag */ if (MPFR_SIGN(b) != MPFR_SIGN(c)) - { /* signs differ, it's a subtraction */ - if (MPFR_EXP(b) < MPFR_EXP(c)) - { - return mpfr_sub1(a, c, b, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); - } - else if (MPFR_EXP(b) > MPFR_EXP(c)) - { - return mpfr_sub1(a, b, c, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c)); - } - else - { /* MPFR_EXP(b) == MPFR_EXP(c) */ - int d = mpfr_cmp_abs(b,c); - if (d == 0) - { - if (rnd_mode == GMP_RNDD) - MPFR_SET_NEG(a); - else - MPFR_SET_POS(a); - MPFR_SET_ZERO(a); - MPFR_RET(0); - } - else if (d > 0) - return mpfr_sub1(a, b, c, rnd_mode, 0); + { /* signs differ, it's a subtraction */ + if (MPFR_EXP(b) < MPFR_EXP(c)) + { + return mpfr_sub1(a, c, b, rnd_mode, + (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); + } + else if (MPFR_EXP(b) > MPFR_EXP(c)) + { + return mpfr_sub1(a, b, c, rnd_mode, + (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c)); + } else - return mpfr_sub1(a, c, b, rnd_mode, 0); + { /* MPFR_EXP(b) == MPFR_EXP(c) */ + int d = mpfr_cmp_abs(b,c); + if (d == 0) + { + if (rnd_mode == GMP_RNDD) + MPFR_SET_NEG(a); + else + MPFR_SET_POS(a); + MPFR_SET_ZERO(a); + MPFR_RET(0); + } + else if (d > 0) + return mpfr_sub1(a, b, c, rnd_mode, 0); + else + return mpfr_sub1(a, c, b, rnd_mode, 0); + } } - } else - { /* signs are equal, it's an addition */ - if (MPFR_EXP(b) < MPFR_EXP(c)) - { - return mpfr_add1(a, c, b, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); - } - else - { - return mpfr_add1(a, b, c, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c)); + { /* signs are equal, it's an addition */ + if (MPFR_EXP(b) < MPFR_EXP(c)) + { + return mpfr_add1(a, c, b, rnd_mode, + (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); + } + else + { + return mpfr_add1(a, b, c, rnd_mode, + (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c)); + } } - } } |