summaryrefslogtreecommitdiff
path: root/src/atan2u.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2021-02-02 15:31:06 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2021-02-02 15:31:06 +0000
commit0a9ec50b24ca5048b0ff4cbd3449017fa026289c (patch)
treec476327f39727f1438516fbebad7052236e3f22d /src/atan2u.c
parent7710b56a9b7d26e3d49bb1c0a889f9e2222d4087 (diff)
downloadmpfr-0a9ec50b24ca5048b0ff4cbd3449017fa026289c.tar.gz
[src/atan2u.c] fixed atan2u with respect to the four quadrants
[tests/tatan2u.c] added corresponding non-regression tests git-svn-id: https://scm.gforge.inria.fr/anonscm/svn/mpfr/trunk@14321 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src/atan2u.c')
-rw-r--r--src/atan2u.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/atan2u.c b/src/atan2u.c
index cccf54d29..4054aa216 100644
--- a/src/atan2u.c
+++ b/src/atan2u.c
@@ -190,9 +190,15 @@ mpfr_atan2u (mpfr_ptr z, mpfr_srcptr y, mpfr_srcptr x, unsigned long u,
{
mpfr_exp_t expt, e;
/* atan2u(-y,x,u) = -atan(y,x,u)
- atan2u(y,x,u) = atan(y/x)*u/(2*pi) for x > 0
- atan2u(y,x,u) = u/2-atan(-y/x)*u/(2*pi) for x < 0 */
+ atan2u(y,x,u) = atan(|y/x|)*u/(2*pi) for x > 0
+ atan2u(y,x,u) = u/2-atan(|y/x|)*u/(2*pi) for x < 0
+ atan2pi atan2u
+ First quadrant: [0,1/2] [0,u/4]
+ Second quadrant: [1/2,1] [u/4,u/2]
+ Third quadrant: [-1,-1/2] [-u/2,-u/4]
+ Fourth quadrant: [-1/2,0] [-u/4,0] */
inex = mpfr_div (tmp, y, x, MPFR_RNDN);
+ MPFR_SET_SIGN (tmp, 1);
expt = MPFR_GET_EXP(tmp);
/* |tmp - y/x| <= e1 := 1/2*ulp(tmp) = 2^(expt-prec-1) */
inex |= mpfr_atanu (tmp, tmp, u, MPFR_RNDN);
@@ -220,6 +226,8 @@ mpfr_atan2u (mpfr_ptr z, mpfr_srcptr y, mpfr_srcptr x, unsigned long u,
now we want error <= 2^(expt-prec+err)
thus err = e-expt */
e -= MPFR_GET_EXP(tmp);
+ if (MPFR_SIGN(y) < 0) /* atan2u is odd with respect to y */
+ MPFR_CHANGE_SIGN(tmp);
if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - e,
MPFR_PREC (z), rnd_mode)))
break;