summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2007-06-22 12:15:03 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2007-06-22 12:15:03 +0000
commitcbe4b4045108db2a9eeaa996ff1d86d374065919 (patch)
tree518edaac64ce8fbdec78c4519a76874dc6545ead
parent35e47491aae2d203e35253de6315cc3ab11d50bc (diff)
downloadmpfr-cbe4b4045108db2a9eeaa996ff1d86d374065919.tar.gz
coth.c, sech.c: a rounding mode was incorrect.
tests/tcoth.c: added underflowed_cothinf test. tests/tsech.c: added overflowed_sech0 test. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@4570 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--coth.c2
-rw-r--r--sech.c2
-rw-r--r--tests/tcoth.c67
-rw-r--r--tests/tsech.c79
4 files changed, 148 insertions, 2 deletions
diff --git a/coth.c b/coth.c
index c54ef82eb..bbbcdd63b 100644
--- a/coth.c
+++ b/coth.c
@@ -31,7 +31,7 @@ MA 02110-1301, USA. */
#define FUNCTION mpfr_coth
#define INVERSE mpfr_tanh
#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
-#define ACTION_INF(y) return mpfr_set_si (y, MPFR_IS_POS(x) ? 1 : -1, GMP_RNDN)
+#define ACTION_INF(y) return mpfr_set_si (y, MPFR_IS_POS(x) ? 1 : -1, rnd_mode)
#define ACTION_ZERO(y,x) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_ZERO(y); \
MPFR_RET(0); } while (1)
diff --git a/sech.c b/sech.c
index 7e3ff4939..cdfa5fb82 100644
--- a/sech.c
+++ b/sech.c
@@ -30,7 +30,7 @@ MA 02110-1301, USA. */
#define INVERSE mpfr_cosh
#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
#define ACTION_INF(y) return mpfr_set_ui (y, 0, GMP_RNDN)
-#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, sech(x) = 1 - x^2/2 + ..., more precisely |sech(x)-1| <= x^2/2
for |x| <= 1. The tiny action is the same as for cos(x). */
#define ACTION_TINY(y,x,r) \
diff --git a/tests/tcoth.c b/tests/tcoth.c
index 60d30cde0..064771eb6 100644
--- a/tests/tcoth.c
+++ b/tests/tcoth.c
@@ -131,6 +131,72 @@ check_bugs (void)
mpfr_clear (y);
}
+static void
+underflowed_cothinf (void)
+{
+ mpfr_t x, y;
+ int i, inex, rnd, err = 0;
+ mp_exp_t old_emin;
+
+ old_emin = mpfr_get_emin ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ for (i = -1; i <= 1; i += 2)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_inf (x, i);
+ mpfr_clear_flags ();
+ set_emin (2); /* 1 is not representable. */
+ inex = mpfr_coth (x, x, rnd);
+ set_emin (old_emin);
+ if (! mpfr_underflow_p ())
+ {
+ printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
+ " The underflow flag is not set.\n",
+ i, mpfr_print_rnd_mode (rnd));
+ err = 1;
+ }
+ mpfr_set_si (y, (i < 0 && rnd == GMP_RNDD) ||
+ (i > 0 && rnd == GMP_RNDU) ? 2 : 0, GMP_RNDN);
+ if (i < 0)
+ mpfr_neg (y, y, GMP_RNDN);
+ if (! (mpfr_equal_p (x, y) &&
+ MPFR_MULT_SIGN (MPFR_SIGN (x), MPFR_SIGN (y)) > 0))
+ {
+ printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode (rnd));
+ mpfr_print_binary (x);
+ printf (" instead of ");
+ mpfr_print_binary (y);
+ printf (".\n");
+ err = 1;
+ }
+ if ((rnd == GMP_RNDD ||
+ (i > 0 && (rnd == GMP_RNDN || rnd == GMP_RNDZ))) && inex >= 0)
+ {
+ printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ i, mpfr_print_rnd_mode (rnd));
+ err = 1;
+ }
+ if ((rnd == GMP_RNDU ||
+ (i < 0 && (rnd == GMP_RNDN || rnd == GMP_RNDZ))) && inex <= 0)
+ {
+ printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ i, mpfr_print_rnd_mode (rnd));
+ err = 1;
+ }
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
int
main (int argc, char *argv[])
{
@@ -139,6 +205,7 @@ main (int argc, char *argv[])
check_specials ();
check_bugs ();
test_generic (2, 200, 10);
+ underflowed_cothinf ();
tests_end_mpfr ();
return 0;
diff --git a/tests/tsech.c b/tests/tsech.c
index 40b113698..e35a114b9 100644
--- a/tests/tsech.c
+++ b/tests/tsech.c
@@ -96,6 +96,84 @@ check_specials (void)
mpfr_clear (y);
}
+static void
+overflowed_sech0 (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. */
+ /* and if emax < 0, 1 - eps is not representable either. */
+ 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_sech (x, x, rnd);
+ if ((i == 0 || emax < 0 || rnd == GMP_RNDN || rnd == GMP_RNDU) &&
+ ! mpfr_overflow_p ())
+ {
+ printf ("Error in overflowed_sech0 (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_sech0 (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_sech0 (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_sech0 (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_sech0 (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[])
{
@@ -103,6 +181,7 @@ main (int argc, char *argv[])
check_specials ();
test_generic (2, 200, 10);
+ overflowed_sech0 ();
tests_end_mpfr ();
return 0;