diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2003-10-06 14:44:18 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2003-10-06 14:44:18 +0000 |
commit | a927fbd495443d0d69179d79ef842f148dbf57b6 (patch) | |
tree | 829cfeaabf0d1e52e6fc7dd2d973f983f1aab987 | |
parent | cd9cf505966fd9e1c8f52ce2eec144e3d3822f6f (diff) | |
download | mpfr-a927fbd495443d0d69179d79ef842f148dbf57b6.tar.gz |
inexact flag should now be correct for directed rounding
fixed a bug for mpfr_atan(-Inf) [gave +Pi/2 instead of -Pi/2]
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2478 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | asin.c | 15 | ||||
-rw-r--r-- | atan.c | 46 |
2 files changed, 33 insertions, 28 deletions
@@ -40,7 +40,8 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) int good = 0; int realprec; int estimated_delta; - int compared; + int compared; + int inexact; /* Trivial cases */ if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) @@ -68,25 +69,25 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) if (compared == 0) /* x = 1 or x = -1 */ { if (signe > 0) /* asin(+1) = Pi/2 */ - mpfr_const_pi (asin, rnd_mode); + inexact = mpfr_const_pi (asin, rnd_mode); else /* asin(-1) = -Pi/2 */ { if (rnd_mode == GMP_RNDU) rnd_mode = GMP_RNDD; else if (rnd_mode == GMP_RNDD) rnd_mode = GMP_RNDU; - mpfr_const_pi (asin, rnd_mode); + inexact = -mpfr_const_pi (asin, rnd_mode); mpfr_neg (asin, asin, rnd_mode); } MPFR_SET_EXP (asin, MPFR_GET_EXP (asin) - 1); mpfr_clear (xp); - return 1; /* inexact */ + return inexact; } if (MPFR_IS_ZERO(x)) /* x = 0 */ { mpfr_set_ui (asin, 0, GMP_RNDN); - mpfr_clear(xp); + mpfr_clear (xp); return 0; /* exact result */ } @@ -152,7 +153,7 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) #endif if (mpfr_can_round (arcs, realprec, GMP_RNDN, rnd_mode, MPFR_PREC(asin))) { - mpfr_set (asin, arcs, rnd_mode); + inexact = mpfr_set (asin, arcs, rnd_mode); #ifdef DEBUG printf("asin ="); mpfr_out_str (stdout, 2, prec_asin, asin, GMP_RNDN); @@ -173,7 +174,7 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_clear (xp); - return 1; /* inexact result */ + return inexact; } @@ -57,7 +57,7 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_t xp; mpfr_t arctgt; - int comparaison, signe, supplement; + int comparaison, signe, supplement, inexact; mpfr_t t_arctan; int i; @@ -94,17 +94,18 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) { MPFR_CLEAR_FLAGS(arctangent); if (MPFR_SIGN(x) > 0) /* arctan(+inf) = Pi/2 */ - mpfr_const_pi (arctangent, rnd_mode); + inexact = mpfr_const_pi (arctangent, rnd_mode); else /* arctan(-inf) = -Pi/2 */ { if (rnd_mode == GMP_RNDU) rnd_mode = GMP_RNDD; else if (rnd_mode == GMP_RNDD) rnd_mode = GMP_RNDU; - mpfr_const_pi (arctangent, rnd_mode); + inexact = -mpfr_const_pi (arctangent, rnd_mode); + MPFR_CHANGE_SIGN (arctangent); } MPFR_SET_EXP (arctangent, MPFR_GET_EXP (arctangent) - 1); - return 1; /* inexact */ + return inexact; } MPFR_CLEAR_FLAGS(arctangent); @@ -118,23 +119,26 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) prec_arctan = MPFR_PREC(arctangent); /* Set x_p=|x| */ - mpfr_init2(xp, MPFR_PREC(x)); - mpfr_set(xp, x, rnd_mode); + mpfr_init2 (xp, MPFR_PREC(x)); + mpfr_set (xp, x, rnd_mode); if (signe == -1) MPFR_CHANGE_SIGN(xp); /* Other simple case arctang(-+1)=-+pi/4 */ - comparaison=mpfr_cmp_ui(xp, 1); - if (comparaison == 0) { - mpfr_init2(Pisur2, prec_arctan); - mpfr_const_pi(Pisur2, rnd_mode); - mpfr_div_2ui(arctangent, Pisur2, 2, rnd_mode); - if (signe == -1) - MPFR_CHANGE_SIGN(arctangent); - mpfr_clear(Pisur2); - mpfr_clear(xp); - return 1; /* inexact result */ - } + comparaison = mpfr_cmp_ui (xp, 1); + if (comparaison == 0) + { + inexact = mpfr_const_pi (arctangent, rnd_mode); + MPFR_SET_EXP (arctangent, MPFR_GET_EXP (arctangent) - 2); + if (signe == -1) + { + inexact = -inexact; + MPFR_CHANGE_SIGN(arctangent); + } + mpfr_clear (xp); + return inexact; + } + if (comparaison > 0) supplement = 2; else @@ -144,8 +148,8 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) logn = __gmpfr_ceil_log2 ((double) prec_x); if (logn < 2) logn = 2; realprec = prec_arctan + __gmpfr_ceil_log2((double) prec_arctan) + 4; - mpz_init(ukz); - mpz_init(square); + mpz_init (ukz); + mpz_init (square); while (!good){ @@ -230,7 +234,7 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) if (mpfr_can_round(arctgt, realprec, GMP_RNDN, rnd_mode, MPFR_PREC(arctangent))) { - mpfr_set(arctangent, arctgt, rnd_mode); + inexact = mpfr_set(arctangent, arctgt, rnd_mode); good = 1; realprec += 1; } @@ -259,5 +263,5 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) mpz_clear(ukz); mpz_clear(square); - return 1; /* inexact result */ + return inexact; } |