summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2007-06-22 00:12:18 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2007-06-22 00:12:18 +0000
commit35e47491aae2d203e35253de6315cc3ab11d50bc (patch)
tree0693e7f1066a5e8387015e06405c9ebd8e96d0b2
parentdecb100a8d962ee0a7bbf9974815361e596c4440 (diff)
downloadmpfr-35e47491aae2d203e35253de6315cc3ab11d50bc.tar.gz
* gen_inverse.h: ACTION_TINY must be called after MPFR_SAVE_EXPO_MARK
(this is necessary for some functions). Moved MPFR_SAVE_EXPO_FREE after the "end:" label. * coth.c, csc.c, csch.c: as a consequence, MPFR_SAVE_EXPO_UPDATE_FLAGS had to be added before "goto end;". * sec.c: a rounding mode was incorrect. * tests/tsec.c: added overflowed_sec0 test. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@4569 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--coth.c1
-rw-r--r--csc.c1
-rw-r--r--csch.c1
-rw-r--r--gen_inverse.h6
-rw-r--r--sec.c2
-rw-r--r--tests/tsec.c77
6 files changed, 83 insertions, 5 deletions
diff --git a/coth.c b/coth.c
index 2e9d1274b..c54ef82eb 100644
--- a/coth.c
+++ b/coth.c
@@ -84,6 +84,7 @@ MA 02110-1301, USA. */
else /* round to zero, or nearest */ \
inexact = -signx; \
} \
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); \
goto end; \
}
diff --git a/csc.c b/csc.c
index d0f438e19..c53441626 100644
--- a/csc.c
+++ b/csc.c
@@ -67,6 +67,7 @@ MA 02110-1301, USA. */
else /* round to zero, or nearest */ \
inexact = -signx; \
} \
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); \
goto end; \
}
diff --git a/csch.c b/csch.c
index 83e438ae9..7ed0de374 100644
--- a/csch.c
+++ b/csch.c
@@ -70,6 +70,7 @@ MA 02110-1301, USA. */
else /* round to nearest */ \
inexact = signx; \
} \
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); \
goto end; \
}
diff --git a/gen_inverse.h b/gen_inverse.h
index e50a531c1..6efb9d825 100644
--- a/gen_inverse.h
+++ b/gen_inverse.h
@@ -60,10 +60,9 @@ FUNCTION (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
ACTION_ZERO(y,x);
}
- ACTION_TINY(y,x,rnd_mode); /* special case for very small input x */
-
/* x is neither NaN, Inf nor zero */
MPFR_SAVE_EXPO_MARK (expo);
+ ACTION_TINY (y, x, rnd_mode); /* special case for very small input x */
precy = MPFR_PREC(y);
m = precy + MPFR_INT_CEIL_LOG2 (precy) + 3;
mpfr_init2 (z, m);
@@ -99,8 +98,7 @@ FUNCTION (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
inexact = mpfr_set (y, z, rnd_mode);
mpfr_clear (z);
- MPFR_SAVE_EXPO_FREE (expo);
-
end:
+ MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (y, inexact, rnd_mode);
}
diff --git a/sec.c b/sec.c
index 2a1ea14f8..eb3718623 100644
--- a/sec.c
+++ b/sec.c
@@ -24,7 +24,7 @@ MA 02110-1301, USA. */
#define INVERSE mpfr_cos
#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
#define ACTION_INF(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
-#define ACTION_ZERO(y,x) return mpfr_set_ui (y, 1, GMP_RNDN)
+#define ACTION_ZERO(y,x) return mpfr_set_ui (y, 1, rnd_mode)
/* for x near 0, sec(x) = 1 + x^2/2 + ..., more precisely |sec(x)-1| < x^2
for |x| <= 1. */
#define ACTION_TINY(y,x,r) \
diff --git a/tests/tsec.c b/tests/tsec.c
index 0699b61ac..58dea4cfe 100644
--- a/tests/tsec.c
+++ b/tests/tsec.c
@@ -80,6 +80,82 @@ check_specials (void)
mpfr_clear (y);
}
+static void
+overflowed_sec0 (void)
+{
+ mpfr_t x, y;
+ int emax, i, inex, rnd, err = 0;
+ mp_exp_t old_emax;
+
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ for (emax = -1; emax <= 0; emax++)
+ {
+ mpfr_set_ui_2exp (y, 1, emax, GMP_RNDN);
+ mpfr_nextbelow (y);
+ set_emax (emax); /* 1 is not representable. */
+ for (i = -1; i <= 1; i++)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si_2exp (x, i, -512 * ABS (i), GMP_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_sec (x, x, rnd);
+ if (! mpfr_overflow_p ())
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " The overflow flag is not set.\n",
+ i, mpfr_print_rnd_mode (rnd));
+ err = 1;
+ }
+ if (rnd == GMP_RNDZ || rnd == GMP_RNDD)
+ {
+ if (inex >= 0)
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ i, mpfr_print_rnd_mode (rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (x, y))
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode (rnd));
+ mpfr_print_binary (x);
+ printf (" instead of 0.11111111E%d.\n", emax);
+ err = 1;
+ }
+ }
+ else
+ {
+ if (inex <= 0)
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ i, mpfr_print_rnd_mode (rnd));
+ err = 1;
+ }
+ if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode (rnd));
+ mpfr_print_binary (x);
+ printf (" instead of +Inf.\n");
+ err = 1;
+ }
+ }
+ }
+ set_emax (old_emax);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
int
main (int argc, char *argv[])
{
@@ -88,6 +164,7 @@ main (int argc, char *argv[])
check_specials ();
test_generic (2, 200, 10);
+ overflowed_sec0 ();
tests_end_mpfr ();
return 0;