diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-08-18 16:35:19 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-08-18 16:35:19 +0000 |
commit | bab5aab404897a12fe1c87734ebf2aa270b9b73b (patch) | |
tree | 73ab96f558e7e0b4ef371902ead983189184a0f7 /atan2.c | |
parent | 8328a51518450ad8ddb86e38e7952e28065ff22a (diff) | |
download | mpfr-bab5aab404897a12fe1c87734ebf2aa270b9b73b.tar.gz |
Converted tabs to spaces with expand.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3725 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'atan2.c')
-rw-r--r-- | atan2.c | 240 |
1 files changed, 120 insertions, 120 deletions
@@ -33,7 +33,7 @@ mpfr_atan2 (mpfr_ptr dest, mpfr_srcptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) MPFR_ZIV_DECL (loop); MPFR_LOG_FUNC (("y[%#R]=%R x[%#R]=%R rnd=%d", y, y, x, x, rnd_mode), - ("atan[%#R]=%R inexact=%d", dest, dest, inexact)); + ("atan[%#R]=%R inexact=%d", dest, dest, inexact)); /* Special cases */ if (MPFR_ARE_SINGULAR (x, y)) @@ -54,103 +54,103 @@ mpfr_atan2 (mpfr_ptr dest, mpfr_srcptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) -- atan2(±y, +oo) returns ±0, for finite y > 0. */ if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y)) - { - MPFR_SET_NAN (dest); - MPFR_RET_NAN; - } + { + MPFR_SET_NAN (dest); + MPFR_RET_NAN; + } if (MPFR_IS_ZERO (y)) - { - if (MPFR_IS_NEG (x)) /* +/- PI */ - { - set_pi: - if (MPFR_IS_NEG (y)) - { - inexact = mpfr_const_pi (dest, MPFR_INVERT_RND (rnd_mode)); - MPFR_CHANGE_SIGN (dest); - return -inexact; - } - else - return mpfr_const_pi (dest, rnd_mode); - } - else /* +/- 0 */ - { - set_zero: - MPFR_SET_ZERO (dest); - MPFR_SET_SAME_SIGN (dest, y); - return 0; - } - } + { + if (MPFR_IS_NEG (x)) /* +/- PI */ + { + set_pi: + if (MPFR_IS_NEG (y)) + { + inexact = mpfr_const_pi (dest, MPFR_INVERT_RND (rnd_mode)); + MPFR_CHANGE_SIGN (dest); + return -inexact; + } + else + return mpfr_const_pi (dest, rnd_mode); + } + else /* +/- 0 */ + { + set_zero: + MPFR_SET_ZERO (dest); + MPFR_SET_SAME_SIGN (dest, y); + return 0; + } + } if (MPFR_IS_ZERO (x)) - { - set_pi_2: - if (MPFR_IS_NEG (y)) /* -PI/2 */ - { - inexact = mpfr_const_pi (dest, MPFR_INVERT_RND(rnd_mode)); - MPFR_CHANGE_SIGN (dest); - mpfr_div_2ui (dest, dest, 1, rnd_mode); - return -inexact; - } - else /* PI/2 */ - { - inexact = mpfr_const_pi (dest, rnd_mode); + { + set_pi_2: + if (MPFR_IS_NEG (y)) /* -PI/2 */ + { + inexact = mpfr_const_pi (dest, MPFR_INVERT_RND(rnd_mode)); + MPFR_CHANGE_SIGN (dest); + mpfr_div_2ui (dest, dest, 1, rnd_mode); + return -inexact; + } + else /* PI/2 */ + { + inexact = mpfr_const_pi (dest, rnd_mode); mpfr_div_2ui (dest, dest, 1, rnd_mode); return inexact; - } - } + } + } if (MPFR_IS_INF (y)) - { - if (!MPFR_IS_INF (x)) /* +/- PI/2 */ - goto set_pi_2; - else if (MPFR_IS_POS (x)) /* +/- PI/4 */ - { - if (MPFR_IS_NEG (y)) - { - rnd_mode = MPFR_INVERT_RND (rnd_mode); - inexact = mpfr_const_pi (dest, rnd_mode); - MPFR_CHANGE_SIGN (dest); - mpfr_div_2ui (dest, dest, 2, rnd_mode); - return -inexact; - } - else - { - inexact = mpfr_const_pi (dest, rnd_mode); - mpfr_div_2ui (dest, dest, 2, rnd_mode); - return inexact; - } - } - else /* +/- 3*PI/4: Ugly since we have to round properly */ - { - mpfr_t tmp; - MPFR_ZIV_DECL (loop); - mp_prec_t prec = MPFR_PREC (dest) + BITS_PER_MP_LIMB; + { + if (!MPFR_IS_INF (x)) /* +/- PI/2 */ + goto set_pi_2; + else if (MPFR_IS_POS (x)) /* +/- PI/4 */ + { + if (MPFR_IS_NEG (y)) + { + rnd_mode = MPFR_INVERT_RND (rnd_mode); + inexact = mpfr_const_pi (dest, rnd_mode); + MPFR_CHANGE_SIGN (dest); + mpfr_div_2ui (dest, dest, 2, rnd_mode); + return -inexact; + } + else + { + inexact = mpfr_const_pi (dest, rnd_mode); + mpfr_div_2ui (dest, dest, 2, rnd_mode); + return inexact; + } + } + else /* +/- 3*PI/4: Ugly since we have to round properly */ + { + mpfr_t tmp; + MPFR_ZIV_DECL (loop); + mp_prec_t prec = MPFR_PREC (dest) + BITS_PER_MP_LIMB; - mpfr_init2 (tmp, prec); - MPFR_ZIV_INIT (loop, prec); - for (;;) - { - mpfr_const_pi (tmp, GMP_RNDN); - mpfr_mul_ui (tmp, tmp, 3, GMP_RNDN); /* Error <= 2 */ - mpfr_div_2ui (tmp, tmp, 2, GMP_RNDN); - if (mpfr_round_p (MPFR_MANT (tmp), MPFR_LIMB_SIZE (tmp), - MPFR_PREC (tmp)-2, - MPFR_PREC (dest) + (rnd_mode == GMP_RNDN))) - break; - MPFR_ZIV_NEXT (loop, prec); - mpfr_set_prec (tmp, prec); - } - MPFR_ZIV_FREE (loop); - if (MPFR_IS_NEG (y)) - MPFR_CHANGE_SIGN (tmp); - inexact = mpfr_set (dest, tmp, rnd_mode); - mpfr_clear (tmp); - return inexact; - } - } + mpfr_init2 (tmp, prec); + MPFR_ZIV_INIT (loop, prec); + for (;;) + { + mpfr_const_pi (tmp, GMP_RNDN); + mpfr_mul_ui (tmp, tmp, 3, GMP_RNDN); /* Error <= 2 */ + mpfr_div_2ui (tmp, tmp, 2, GMP_RNDN); + if (mpfr_round_p (MPFR_MANT (tmp), MPFR_LIMB_SIZE (tmp), + MPFR_PREC (tmp)-2, + MPFR_PREC (dest) + (rnd_mode == GMP_RNDN))) + break; + MPFR_ZIV_NEXT (loop, prec); + mpfr_set_prec (tmp, prec); + } + MPFR_ZIV_FREE (loop); + if (MPFR_IS_NEG (y)) + MPFR_CHANGE_SIGN (tmp); + inexact = mpfr_set (dest, tmp, rnd_mode); + mpfr_clear (tmp); + return inexact; + } + } MPFR_ASSERTD (MPFR_IS_INF (x)); if (MPFR_IS_NEG (x)) - goto set_pi; + goto set_pi; else - goto set_zero; + goto set_zero; } MPFR_SAVE_EXPO_MARK (expo); @@ -163,43 +163,43 @@ mpfr_atan2 (mpfr_ptr dest, mpfr_srcptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) /* use atan2(y,x) = atan(y/x) */ for (;;) { - mpfr_div (tmp, y, x, GMP_RNDN); /* Error <= ulp (tmp) */ - mpfr_atan (tmp, tmp, GMP_RNDN); /* Error <= 2*ulp (tmp) since - abs(D(arctan)) <= 1 */ - /*FIXME: Error <= ulp(tmp) ? */ - if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - 2, MPFR_PREC (dest), - rnd_mode))) - break; - MPFR_ZIV_NEXT (loop, prec); - mpfr_set_prec (tmp, prec); + mpfr_div (tmp, y, x, GMP_RNDN); /* Error <= ulp (tmp) */ + mpfr_atan (tmp, tmp, GMP_RNDN); /* Error <= 2*ulp (tmp) since + abs(D(arctan)) <= 1 */ + /*FIXME: Error <= ulp(tmp) ? */ + if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - 2, MPFR_PREC (dest), + rnd_mode))) + break; + MPFR_ZIV_NEXT (loop, prec); + mpfr_set_prec (tmp, prec); } else /* x < 0 */ /* Use sign(y)*(PI - atan (|y/x|)) */ { mpfr_init2 (pi, prec); for (;;) - { - mpfr_div (tmp, y, x, GMP_RNDN); /* Error <= ulp (tmp) */ - MPFR_SET_POS (tmp); /* no error */ - mpfr_atan (tmp, tmp, GMP_RNDN); /* Error <= 2*ulp (tmp) since - abs(D(arctan)) <= 1 */ - mpfr_const_pi (pi, GMP_RNDN); /* Error <= ulp(pi) /2 */ - e = MPFR_GET_EXP (tmp); - mpfr_sub (tmp, pi, tmp, GMP_RNDN); /* see above */ - if (MPFR_IS_NEG (y)) - MPFR_CHANGE_SIGN (tmp); - /* Error(tmp) <= (1/2+2^(EXP(pi)-EXP(tmp)-1)+2^(e-EXP(tmp)+1))*ulp - <= 2^(MAX (MAX (EXP(PI)-EXP(tmp)-1, e-EXP(tmp)+1), - -1)+2)*ulp(tmp) */ - e = MAX (MAX (MPFR_GET_EXP (pi)-MPFR_GET_EXP (tmp) - 1, - e - MPFR_GET_EXP (tmp) + 1), -1) + 2; - if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - e, MPFR_PREC (dest), - rnd_mode))) - break; - MPFR_ZIV_NEXT (loop, prec); - mpfr_set_prec (tmp, prec); - mpfr_set_prec (pi, prec); - } + { + mpfr_div (tmp, y, x, GMP_RNDN); /* Error <= ulp (tmp) */ + MPFR_SET_POS (tmp); /* no error */ + mpfr_atan (tmp, tmp, GMP_RNDN); /* Error <= 2*ulp (tmp) since + abs(D(arctan)) <= 1 */ + mpfr_const_pi (pi, GMP_RNDN); /* Error <= ulp(pi) /2 */ + e = MPFR_GET_EXP (tmp); + mpfr_sub (tmp, pi, tmp, GMP_RNDN); /* see above */ + if (MPFR_IS_NEG (y)) + MPFR_CHANGE_SIGN (tmp); + /* Error(tmp) <= (1/2+2^(EXP(pi)-EXP(tmp)-1)+2^(e-EXP(tmp)+1))*ulp + <= 2^(MAX (MAX (EXP(PI)-EXP(tmp)-1, e-EXP(tmp)+1), + -1)+2)*ulp(tmp) */ + e = MAX (MAX (MPFR_GET_EXP (pi)-MPFR_GET_EXP (tmp) - 1, + e - MPFR_GET_EXP (tmp) + 1), -1) + 2; + if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - e, MPFR_PREC (dest), + rnd_mode))) + break; + MPFR_ZIV_NEXT (loop, prec); + mpfr_set_prec (tmp, prec); + mpfr_set_prec (pi, prec); + } mpfr_clear (pi); } MPFR_ZIV_FREE (loop); |