diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2007-06-22 00:12:18 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2007-06-22 00:12:18 +0000 |
commit | 35e47491aae2d203e35253de6315cc3ab11d50bc (patch) | |
tree | 0693e7f1066a5e8387015e06405c9ebd8e96d0b2 | |
parent | decb100a8d962ee0a7bbf9974815361e596c4440 (diff) | |
download | mpfr-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.c | 1 | ||||
-rw-r--r-- | csc.c | 1 | ||||
-rw-r--r-- | csch.c | 1 | ||||
-rw-r--r-- | gen_inverse.h | 6 | ||||
-rw-r--r-- | sec.c | 2 | ||||
-rw-r--r-- | tests/tsec.c | 77 |
6 files changed, 83 insertions, 5 deletions
@@ -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; \ } @@ -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; \ } @@ -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); } @@ -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; |