summaryrefslogtreecommitdiff
path: root/sub.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2001-10-19 15:45:18 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2001-10-19 15:45:18 +0000
commit606a422f38793b9b78996f9054b20576a1ca8b0e (patch)
treec1b519fd4fafc628fb394f340d6d72ff12e3e553 /sub.c
parentade345c5ded27462715c948ef33ac40a1b07235c (diff)
downloadmpfr-606a422f38793b9b78996f9054b20576a1ca8b0e.tar.gz
mpfr_add1 and mpfr_sub1 prototypes moved to mpfr-impl.h (to detect clashes).
Bug fix concerning the inexact ternary value in mpfr_sub. mpfr_add now returns an int (inexact ternary value unsupported if true add). git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@1309 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'sub.c')
-rw-r--r--sub.c74
1 files changed, 35 insertions, 39 deletions
diff --git a/sub.c b/sub.c
index c98f2035a..07605bf79 100644
--- a/sub.c
+++ b/sub.c
@@ -30,11 +30,6 @@ MA 02111-1307, USA. */
#define ONE ((mp_limb_t) 1)
-extern void mpfr_add1 _PROTO((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
- mp_rnd_t, mp_exp_unsigned_t));
-int mpfr_sub1 _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
- mp_rnd_t, mp_exp_unsigned_t));
-
/* signs of b and c differ, abs(b) > abs(c),
diff_exp = EXP(b) - EXP(c).
Returns 0 iff result is exact,
@@ -396,12 +391,10 @@ mpfr_sub (a, b, c, rnd_mode)
mp_rnd_t rnd_mode;
#endif
{
- int inexact;
-
if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c))
{
MPFR_SET_NAN(a);
- return 1; /* a NaN result is inexact */
+ MPFR_RET_NAN;
}
MPFR_CLEAR_NAN(a);
@@ -412,21 +405,21 @@ mpfr_sub (a, b, c, rnd_mode)
{
MPFR_SET_INF(a);
MPFR_SET_SAME_SIGN(a, b);
- return 0; /* +/-infinity is exact */
+ MPFR_RET(0); /* exact */
}
else
- {
- MPFR_SET_NAN(a);
- return 1; /* a NaN result is inexact */
- }
+ {
+ MPFR_SET_NAN(a);
+ MPFR_RET_NAN;
+ }
}
else
if (MPFR_IS_INF(c))
{
MPFR_SET_INF(a);
- if (MPFR_SIGN(c) == MPFR_SIGN(a))
- MPFR_CHANGE_SIGN(a);
- return 0; /* +/-infinity is exact */
+ if (MPFR_SIGN(c) == MPFR_SIGN(a))
+ MPFR_CHANGE_SIGN(a);
+ MPFR_RET(0); /* exact */
}
MPFR_ASSERTN(MPFR_IS_FP(b) && MPFR_IS_FP(c));
@@ -442,16 +435,14 @@ mpfr_sub (a, b, c, rnd_mode)
MPFR_CHANGE_SIGN(a);
MPFR_CLEAR_INF(a);
MPFR_SET_ZERO(a);
- return 0; /* 0 - 0 is exact */
+ MPFR_RET(0); /* 0 - 0 is exact */
}
- mpfr_neg (a, c, rnd_mode);
- return 0; /* 0 - c is exact */
+ return mpfr_neg (a, c, rnd_mode);
}
if (MPFR_IS_ZERO(c))
{
- mpfr_set (a, b, rnd_mode);
- return 0; /* b - 0 is exact */
+ return mpfr_set (a, b, rnd_mode);
}
MPFR_CLEAR_INF(a);
@@ -460,40 +451,44 @@ mpfr_sub (a, b, c, rnd_mode)
{ /* signs are equal, it's a real subtraction */
if (MPFR_EXP(b) < MPFR_EXP(c))
{ /* exchange rounding modes towards +/- infinity */
+ int inexact;
if (rnd_mode == GMP_RNDU)
rnd_mode = GMP_RNDD;
else if (rnd_mode == GMP_RNDD)
rnd_mode = GMP_RNDU;
- inexact = -mpfr_sub1(a, c, b, rnd_mode,
- (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b));
+ inexact = - mpfr_sub1(a, c, b, rnd_mode,
+ (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b));
MPFR_CHANGE_SIGN(a);
+ return inexact;
}
else if (MPFR_EXP(b) > MPFR_EXP(c))
- inexact = mpfr_sub1(a, b, c, rnd_mode,
- (mp_exp_unsigned_t) 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);
- inexact = 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)
- inexact = mpfr_sub1 (a, b, c, rnd_mode, 0);
+ return mpfr_sub1 (a, b, c, rnd_mode, 0);
else
{ /* exchange rounding modes towards +/- infinity */
+ int inexact;
if (rnd_mode == GMP_RNDU)
rnd_mode = GMP_RNDD;
else if (rnd_mode == GMP_RNDD)
rnd_mode = GMP_RNDU;
- inexact = -mpfr_sub1 (a, c, b, rnd_mode, 0);
+ inexact = - mpfr_sub1 (a, c, b, rnd_mode, 0);
MPFR_CHANGE_SIGN(a);
+ return inexact;
}
}
}
@@ -501,19 +496,20 @@ mpfr_sub (a, b, c, rnd_mode)
{ /* signs differ, it's an addition */
if (MPFR_EXP(b) < MPFR_EXP(c))
{ /* exchange rounding modes towards +/- infinity */
+ int inexact;
if (rnd_mode == GMP_RNDU)
rnd_mode = GMP_RNDD;
else if (rnd_mode == GMP_RNDD)
rnd_mode = GMP_RNDU;
- mpfr_add1(a, c, b, rnd_mode,
- (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b));
+ inexact = mpfr_add1(a, c, b, rnd_mode,
+ (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b));
MPFR_CHANGE_SIGN(a);
+ return inexact;
}
else
{
- mpfr_add1(a, b, c, rnd_mode,
- (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c));
+ return mpfr_add1(a, b, c, rnd_mode,
+ (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c));
}
}
- return inexact;
}