diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-10-19 15:45:18 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-10-19 15:45:18 +0000 |
commit | 606a422f38793b9b78996f9054b20576a1ca8b0e (patch) | |
tree | c1b519fd4fafc628fb394f340d6d72ff12e3e553 | |
parent | ade345c5ded27462715c948ef33ac40a1b07235c (diff) | |
download | mpfr-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
-rw-r--r-- | add.c | 57 | ||||
-rw-r--r-- | mpfr-impl.h | 4 | ||||
-rw-r--r-- | mpfr.h | 2 | ||||
-rw-r--r-- | sub.c | 74 |
4 files changed, 68 insertions, 69 deletions
@@ -27,16 +27,13 @@ MA 02111-1307, USA. */ #define ONE ((mp_limb_t) 1) -extern void mpfr_sub1 _PROTO((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, - mp_rnd_t, mp_exp_unsigned_t)); -void mpfr_add1 _PROTO((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, - mp_rnd_t, mp_exp_unsigned_t)); - /* signs of b and c are supposed equal, diff_exp is the difference between the exponents of b and c, which is supposed >= 0 */ -void +/* returns an int, but ternary inexact value currently unsupported */ + +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) @@ -132,8 +129,8 @@ mpfr_add1 (a, b, c, rnd_mode, diff_exp) } /* bq <= aq */ else /* bq > aq */ { - mp_limb_t inv, bb = 0, cc = 0; - int difs, r = 0; + mp_limb_t inv, bb, cc = 0; + int difs, r; mp_exp_t difw; /* mp_exp_t may be larger than mp_size_t */ /* MPFR_PREC(b)>MPFR_PREC(a) : we have to round b+c */ @@ -403,7 +400,7 @@ mpfr_add1 (a, b, c, rnd_mode, diff_exp) } if ((long)cout>0 || (cout==0 && cc)) goto add_one_ulp; else if ((long)cout<0) - { TMP_FREE(marker); return; /* no carry possible any more */ } + { TMP_FREE(marker); return 2; /* no carry possible any more */ } else if (kc==0) { while (k && cout==0) cout=bp[--k]; if ((~cout) && (cout || (rnd_mode==GMP_RNDN && (*ap & (ONE<<sh))))) @@ -516,10 +513,10 @@ mpfr_add1 (a, b, c, rnd_mode, diff_exp) end_of_add: TMP_FREE(marker); - return; + return 2; } -void +int #if __STDC__ mpfr_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode) #else @@ -533,7 +530,7 @@ mpfr_add (a, b, c, rnd_mode) if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c)) { MPFR_SET_NAN(a); - return; + MPFR_RET_NAN; } MPFR_CLEAR_NAN(a); @@ -544,17 +541,20 @@ mpfr_add (a, b, c, rnd_mode) { MPFR_SET_INF(a); MPFR_SET_SAME_SIGN(a, b); + MPFR_RET(0); /* exact */ } else + { MPFR_SET_NAN(a); - return; + MPFR_RET_NAN; + } } else if (MPFR_IS_INF(c)) { MPFR_SET_INF(a); MPFR_SET_SAME_SIGN(a, c); - return; + MPFR_RET(0); /* exact */ } MPFR_ASSERTN(MPFR_IS_FP(b) && MPFR_IS_FP(c)); @@ -570,16 +570,14 @@ mpfr_add (a, b, c, rnd_mode) MPFR_CHANGE_SIGN(a); MPFR_CLEAR_INF(a); MPFR_SET_ZERO(a); - return; + MPFR_RET(0); /* 0 + 0 is exact */ } - mpfr_set(a, c, rnd_mode); - return; + return mpfr_set(a, c, rnd_mode); } if (MPFR_IS_ZERO(c)) { - mpfr_set(a, b, rnd_mode); - return; + return mpfr_set(a, b, rnd_mode); } MPFR_CLEAR_INF(a); /* clear Inf flag */ @@ -588,13 +586,13 @@ mpfr_add (a, b, c, rnd_mode) { /* signs differ, it's a subtraction */ if (MPFR_EXP(b) < MPFR_EXP(c)) { - mpfr_sub1(a, c, b, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); + 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)) { - 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) */ @@ -606,24 +604,25 @@ mpfr_add (a, b, c, rnd_mode) else MPFR_SET_POS(a); MPFR_SET_ZERO(a); + MPFR_RET(0); } else if (d > 0) - mpfr_sub1(a, b, c, rnd_mode, 0); + return mpfr_sub1(a, b, c, rnd_mode, 0); else - mpfr_sub1(a, c, b, rnd_mode, 0); + return mpfr_sub1(a, c, b, rnd_mode, 0); } } else { /* signs are equal, it's an addition */ if (MPFR_EXP(b) < MPFR_EXP(c)) { - mpfr_add1(a, c, b, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); + return mpfr_add1(a, c, b, rnd_mode, + (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); } 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)); } } } diff --git a/mpfr-impl.h b/mpfr-impl.h index 54a8e59d4..7bba17c0a 100644 --- a/mpfr-impl.h +++ b/mpfr-impl.h @@ -129,6 +129,10 @@ int mpfr_set_overflow _PROTO ((mpfr_ptr, mp_rnd_t, int)); void mpfr_save_emin_emax _PROTO ((void)); void mpfr_restore_emin_emax _PROTO ((void)); +int 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)); int mpfr_round_raw _PROTO ((mp_limb_t *, mp_limb_t *, mp_prec_t, int, mp_prec_t, mp_rnd_t, int *)); int mpfr_round_raw2 _PROTO((mp_limb_t *, mp_prec_t, int, mp_rnd_t, mp_prec_t)); @@ -153,7 +153,7 @@ void mpfr_div _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); void mpfr_agm _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); int mpfr_sqrt _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); int mpfr_sqrt_ui _PROTO ((mpfr_ptr, unsigned long, mp_rnd_t)); -void mpfr_add _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_add _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); void mpfr_add_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long, mp_rnd_t)); int mpfr_sub_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long, mp_rnd_t)); void mpfr_add_one_ulp _PROTO ((mpfr_ptr)); @@ -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; } |