diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2007-06-22 12:15:03 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2007-06-22 12:15:03 +0000 |
commit | cbe4b4045108db2a9eeaa996ff1d86d374065919 (patch) | |
tree | 518edaac64ce8fbdec78c4519a76874dc6545ead | |
parent | 35e47491aae2d203e35253de6315cc3ab11d50bc (diff) | |
download | mpfr-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.c | 2 | ||||
-rw-r--r-- | sech.c | 2 | ||||
-rw-r--r-- | tests/tcoth.c | 67 | ||||
-rw-r--r-- | tests/tsech.c | 79 |
4 files changed, 148 insertions, 2 deletions
@@ -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) @@ -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; |