142212Sbostic /*-
2*61285Sbostic * Copyright (c) 1990, 1993
3*61285Sbostic * The Regents of the University of California. All rights reserved.
442212Sbostic *
542212Sbostic * This code is derived from software contributed to Berkeley by
642212Sbostic * the Systems Programming Group of the University of Utah Computer
742212Sbostic * Science Department.
842212Sbostic *
942212Sbostic * %sccs.include.redist.c%
1042212Sbostic */
1142212Sbostic
1242212Sbostic #ifndef lint
13*61285Sbostic static char sccsid[] = "@(#)atan2.c 8.1 (Berkeley) 06/04/93";
1442212Sbostic #endif /* not lint */
1542212Sbostic
1642212Sbostic /*
1742212Sbostic * ATAN2(Y,X)
1842212Sbostic * RETURN ARG (X+iY)
1942212Sbostic * DOUBLE PRECISION (IEEE DOUBLE 53 BITS)
2042212Sbostic *
2142212Sbostic * Scaled down version to weed out special cases. "Normal" cases are
2242212Sbostic * handled by calling atan2__A(), an assembly coded support routine in
2342212Sbostic * support.s.
2442212Sbostic *
2542212Sbostic * Required system supported functions :
2642212Sbostic * copysign(x,y)
2742212Sbostic * atan2__A(y,x)
2842212Sbostic *
2942212Sbostic * Method :
3042212Sbostic * 1. Deal with special cases
3142212Sbostic * 2. Call atan2__A() to do the others
3242212Sbostic *
3342212Sbostic * Special cases:
3442212Sbostic * Notations: atan2(y,x) == ARG (x+iy) == ARG(x,y).
3542212Sbostic *
3642212Sbostic * ARG( NAN , (anything) ) is NaN;
3742212Sbostic * ARG( (anything), NaN ) is NaN;
3842212Sbostic * ARG(+(anything but NaN), +-0) is +-0 ;
3942212Sbostic * ARG(-(anything but NaN), +-0) is +-PI ;
4042212Sbostic * ARG( 0, +-(anything but 0 and NaN) ) is +-PI/2;
4142212Sbostic * ARG( +INF,+-(anything but INF and NaN) ) is +-0 ;
4242212Sbostic * ARG( -INF,+-(anything but INF and NaN) ) is +-PI;
4342212Sbostic * ARG( +INF,+-INF ) is +-PI/4 ;
4442212Sbostic * ARG( -INF,+-INF ) is +-3PI/4;
4542212Sbostic * ARG( (anything but,0,NaN, and INF),+-INF ) is +-PI/2;
4642212Sbostic *
4742212Sbostic * Accuracy:
4842212Sbostic * atan2(y,x) returns (PI/pi) * the exact ARG (x+iy) nearly rounded,
4942212Sbostic * where
5042212Sbostic *
5142212Sbostic * in decimal:
5242212Sbostic * pi = 3.141592653589793 23846264338327 .....
5342212Sbostic * 53 bits PI = 3.141592653589793 115997963 ..... ,
5442212Sbostic * 56 bits PI = 3.141592653589793 227020265 ..... ,
5542212Sbostic *
5642212Sbostic * in hexadecimal:
5742212Sbostic * pi = 3.243F6A8885A308D313198A2E....
5842212Sbostic * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps
5942212Sbostic * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps
6042212Sbostic *
6142212Sbostic * In a test run with 356,000 random argument on [-1,1] * [-1,1] on a
6242212Sbostic * VAX, the maximum observed error was 1.41 ulps (units of the last place)
6342212Sbostic * compared with (PI/pi)*(the exact ARG(x+iy)).
6442212Sbostic *
6542212Sbostic * Note:
6642212Sbostic * We use machine PI (the true pi rounded) in place of the actual
6742212Sbostic * value of pi for all the trig and inverse trig functions. In general,
6842212Sbostic * if trig is one of sin, cos, tan, then computed trig(y) returns the
6942212Sbostic * exact trig(y*pi/PI) nearly rounded; correspondingly, computed arctrig
7042212Sbostic * returns the exact arctrig(y)*PI/pi nearly rounded. These guarantee the
7142212Sbostic * trig functions have period PI, and trig(arctrig(x)) returns x for
7242212Sbostic * all critical values x.
7342212Sbostic *
7442212Sbostic * Constants:
7542212Sbostic * The hexadecimal values are the intended ones for the following constants.
7642212Sbostic * The decimal values may be used, provided that the compiler will convert
7742212Sbostic * from decimal to binary accurately enough to produce the hexadecimal values
7842212Sbostic * shown.
7942212Sbostic */
8042212Sbostic
8142212Sbostic static double
8242212Sbostic PIo4 = 7.8539816339744827900E-1 , /*Hex 2^ -1 * 1.921FB54442D18 */
8342212Sbostic PIo2 = 1.5707963267948965580E0 , /*Hex 2^ 0 * 1.921FB54442D18 */
8442212Sbostic PI = 3.1415926535897931160E0 ; /*Hex 2^ 1 * 1.921FB54442D18 */
8542212Sbostic
atan2(y,x)8642212Sbostic double atan2(y,x)
8742212Sbostic double y,x;
8842212Sbostic {
8942212Sbostic static double zero=0, one=1;
9042212Sbostic double copysign(),atan2__A(),signy,signx;
9142212Sbostic int finite();
9242212Sbostic
9342212Sbostic /* if x or y is NAN */
9442212Sbostic if(x!=x) return(x); if(y!=y) return(y);
9542212Sbostic
9642212Sbostic /* copy down the sign of y and x */
9742212Sbostic signy = copysign(one,y);
9842212Sbostic signx = copysign(one,x);
9942212Sbostic
10042212Sbostic /* when y = 0 */
10142212Sbostic if(y==zero) return((signx==one)?y:copysign(PI,signy));
10242212Sbostic
10342212Sbostic /* when x = 0 */
10442212Sbostic if(x==zero) return(copysign(PIo2,signy));
10542212Sbostic
10642212Sbostic /* when x is INF */
10742212Sbostic if(!finite(x))
10842212Sbostic if(!finite(y))
10942212Sbostic return(copysign((signx==one)?PIo4:3*PIo4,signy));
11042212Sbostic else
11142212Sbostic return(copysign((signx==one)?zero:PI,signy));
11242212Sbostic
11342212Sbostic /* when y is INF */
11442212Sbostic if(!finite(y)) return(copysign(PIo2,signy));
11542212Sbostic
11642212Sbostic /* else let atan2__A do the work */
11742212Sbostic return(atan2__A(y,x));
11842212Sbostic }
119