summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-07-26 15:52:58 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-07-26 15:52:58 +0000
commit49c11f49544fd4ee9b0f88f4bdc742a86583852e (patch)
tree1bfda22c1dad2721f7a684c26d9bbfe33ebc9cbd
parent705a965275388c9cbd0491867e3c1138325c3af0 (diff)
downloadmpfr-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--TODO2
-rw-r--r--exceptions.c4
-rw-r--r--exp.c27
-rw-r--r--mpfr-impl.h4
-rw-r--r--next.c21
-rw-r--r--setmax.c4
-rw-r--r--setmin.c4
7 files changed, 40 insertions, 26 deletions
diff --git a/TODO b/TODO
index 341f32edc..ef941b31b 100644
--- a/TODO
+++ b/TODO
@@ -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
diff --git a/exp.c b/exp.c
index 32d35ec8c..4aa50f612 100644
--- a/exp.c
+++ b/exp.c
@@ -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)
diff --git a/next.c b/next.c
index f545ee964..2f612d3df 100644
--- a/next.c
+++ b/next.c
@@ -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)
diff --git a/setmax.c b/setmax.c
index 4e9bf8d8e..141036908 100644
--- a/setmax.c
+++ b/setmax.c
@@ -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);
diff --git a/setmin.c b/setmin.c
index 42eb30693..f4b0ca2b6 100644
--- a/setmin.c
+++ b/setmin.c
@@ -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;