diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2002-07-26 15:52:58 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2002-07-26 15:52:58 +0000 |
commit | 49c11f49544fd4ee9b0f88f4bdc742a86583852e (patch) | |
tree | 1bfda22c1dad2721f7a684c26d9bbfe33ebc9cbd | |
parent | 705a965275388c9cbd0491867e3c1138325c3af0 (diff) | |
download | mpfr-49c11f49544fd4ee9b0f88f4bdc742a86583852e.tar.gz |
Prototype of mpfr_setmax and mpfr_setmin changed (exponent given).
In mpfr_exp for x ~= 0, add_one_ulp and sub_one_ulp are no longer
used (sub_one_ulp was incorrect). These cases should now be faster.
Small fix in mpfr_nextabove, mpfr_nextbelow and mpfr_nexttoward.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2002 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | exceptions.c | 4 | ||||
-rw-r--r-- | exp.c | 27 | ||||
-rw-r--r-- | mpfr-impl.h | 4 | ||||
-rw-r--r-- | next.c | 21 | ||||
-rw-r--r-- | setmax.c | 4 | ||||
-rw-r--r-- | setmin.c | 4 |
7 files changed, 40 insertions, 26 deletions
@@ -25,8 +25,6 @@ Changes in existing functions: Possibly accept other strings, like those accepted by strtod. - implement ternary flag for mpfr_agm: result is exact when u=v, or u=0, or v=0. -- use nextafter/nexttoward instead of add_one_ulp/sub_one_ulp in mpfr_exp - (they differ for a power of 2) New functions to implement: diff --git a/exceptions.c b/exceptions.c index be922a08c..ec7887308 100644 --- a/exceptions.c +++ b/exceptions.c @@ -196,7 +196,7 @@ mpfr_set_underflow (mpfr_ptr x, mp_rnd_t rnd_mode, int sign) || (rnd_mode == GMP_RNDU && sign > 0) || (rnd_mode == GMP_RNDD && sign < 0)) { - mpfr_setmin (x); + mpfr_setmin (x, __mpfr_emin); inex = 1; } else @@ -221,7 +221,7 @@ mpfr_set_overflow (mpfr_ptr x, mp_rnd_t rnd_mode, int sign) if ((rnd_mode == GMP_RNDU && sign < 0) || (rnd_mode == GMP_RNDD && sign > 0)) { - mpfr_setmax (x); + mpfr_setmax (x, __mpfr_emax); inex = -1; } else @@ -85,17 +85,24 @@ mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) { int signx = MPFR_SIGN(x); - mpfr_set_ui (y, 1, rnd_mode); + if (signx < 0 && (rnd_mode == GMP_RNDD || rnd_mode == GMP_RNDZ)) + { + MPFR_CLEAR_FLAGS(y); + MPFR_SET_POS(y); + mpfr_setmax (y, 0); /* y = 1 - epsilon */ + return -1; + } + mpfr_setmin (y, 1); /* y = 1 */ if (signx > 0 && rnd_mode == GMP_RNDU) - { - mpfr_add_one_ulp (y, rnd_mode); - return 1; - } - else if (signx < 0 && (rnd_mode == GMP_RNDD || rnd_mode == GMP_RNDZ)) - { - mpfr_sub_one_ulp (y, rnd_mode); - return -1; - } + { + mp_size_t yn; + int sh; + + yn = 1 + (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB; + sh = (mp_prec_t) yn * BITS_PER_MP_LIMB - MPFR_PREC(y); + MPFR_MANT(y)[0] += MP_LIMB_T_ONE << sh; + return 1; + } return -signx; } diff --git a/mpfr-impl.h b/mpfr-impl.h index d0b2fad1d..eb1ac8a26 100644 --- a/mpfr-impl.h +++ b/mpfr-impl.h @@ -198,8 +198,8 @@ unsigned long _mpfr_cuberoot _PROTO ((unsigned long)); int mpfr_exp_2 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); int mpfr_exp3 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); int mpfr_powerof2_raw _PROTO ((mpfr_srcptr)); -void mpfr_setmax _PROTO ((mpfr_ptr)); -void mpfr_setmin _PROTO ((mpfr_ptr)); +void mpfr_setmax _PROTO ((mpfr_ptr, mp_exp_t)); +void mpfr_setmin _PROTO ((mpfr_ptr, mp_exp_t)); #define mpfr_round_raw(yp, xp, xprec, neg, yprec, r, inexp) \ mpfr_round_raw_generic((yp), (xp), (xprec), (neg), (yprec), (r), (inexp), 0) @@ -32,14 +32,14 @@ mpfr_nexttozero (mpfr_ptr x) if (MPFR_IS_INF(x)) { MPFR_CLEAR_FLAGS(x); - mpfr_setmax (x); + mpfr_setmax (x, __mpfr_emax); return; } if (MPFR_IS_ZERO(x)) { MPFR_CHANGE_SIGN(x); - mpfr_setmin (x); + mpfr_setmin (x, __mpfr_emin); } else { @@ -75,7 +75,7 @@ mpfr_nexttoinf (mpfr_ptr x) return; if (MPFR_IS_ZERO(x)) - mpfr_setmin (x); + mpfr_setmin (x, __mpfr_emin); else { mp_size_t xn; @@ -103,7 +103,10 @@ void mpfr_nextabove (mpfr_ptr x) { if (MPFR_IS_NAN(x)) - MPFR_RET_NAN; + { + __mpfr_flags |= MPFR_FLAGS_NAN; + return; + } if (MPFR_SIGN(x) < 0) mpfr_nexttozero (x); @@ -115,7 +118,10 @@ void mpfr_nextbelow (mpfr_ptr x) { if (MPFR_IS_NAN(x)) - MPFR_RET_NAN; + { + __mpfr_flags |= MPFR_FLAGS_NAN; + return; + } if (MPFR_SIGN(x) < 0) mpfr_nexttoinf (x); @@ -129,7 +135,10 @@ mpfr_nexttoward (mpfr_ptr x, mpfr_srcptr y) int s; if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y)) - MPFR_RET_NAN; + { + __mpfr_flags |= MPFR_FLAGS_NAN; + return; + } s = mpfr_cmp (x, y); if (s == 0) @@ -27,13 +27,13 @@ MA 02111-1307, USA. */ /* Note: the flags are not cleared and the current sign is kept. */ -void mpfr_setmax (mpfr_ptr x) +void mpfr_setmax (mpfr_ptr x, mp_exp_t e) { mp_size_t xn, i; int sh; mp_limb_t *xp; - MPFR_EXP(x) = __mpfr_emax; + MPFR_EXP(x) = e; xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB; sh = (mp_prec_t) xn * BITS_PER_MP_LIMB - MPFR_PREC(x); xp = MPFR_MANT(x); @@ -27,12 +27,12 @@ MA 02111-1307, USA. */ /* Note: the flags are not cleared and the current sign is kept. */ -void mpfr_setmin (mpfr_ptr x) +void mpfr_setmin (mpfr_ptr x, mp_exp_t e) { mp_size_t xn; mp_limb_t *xp; - MPFR_EXP(x) = __mpfr_emin; + MPFR_EXP(x) = e; xn = (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB; xp = MPFR_MANT(x); xp[xn] = MPFR_LIMB_HIGHBIT; |