xref: /plan9/sys/src/ape/lib/ap/math/atan.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier 	floating-point arctangent
33e12c5d1SDavid du Colombier 
43e12c5d1SDavid du Colombier 	atan returns the value of the arctangent of its
53e12c5d1SDavid du Colombier 	argument in the range [-pi/2,pi/2].
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier 	atan2 returns the arctangent of arg1/arg2
83e12c5d1SDavid du Colombier 	in the range [-pi,pi].
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier 	there are no error returns.
113e12c5d1SDavid du Colombier 
123e12c5d1SDavid du Colombier 	coefficients are #5077 from Hart & Cheney. (19.56D)
133e12c5d1SDavid du Colombier */
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier #include <math.h>
163e12c5d1SDavid du Colombier 
173e12c5d1SDavid du Colombier #define sq2p1 2.414213562373095048802e0
183e12c5d1SDavid du Colombier #define sq2m1  .414213562373095048802e0
193e12c5d1SDavid du Colombier #define pio2 1.570796326794896619231e0
203e12c5d1SDavid du Colombier #define pio4  .785398163397448309615e0
213e12c5d1SDavid du Colombier #define p4  .161536412982230228262e2
223e12c5d1SDavid du Colombier #define p3  .26842548195503973794141e3
233e12c5d1SDavid du Colombier #define p2  .11530293515404850115428136e4
243e12c5d1SDavid du Colombier #define p1  .178040631643319697105464587e4
253e12c5d1SDavid du Colombier #define p0  .89678597403663861959987488e3
263e12c5d1SDavid du Colombier #define q4  .5895697050844462222791e2
273e12c5d1SDavid du Colombier #define q3  .536265374031215315104235e3
283e12c5d1SDavid du Colombier #define q2  .16667838148816337184521798e4
293e12c5d1SDavid du Colombier #define q1  .207933497444540981287275926e4
303e12c5d1SDavid du Colombier #define q0  .89678597403663861962481162e3
313e12c5d1SDavid du Colombier 
323e12c5d1SDavid du Colombier 
333e12c5d1SDavid du Colombier /*
343e12c5d1SDavid du Colombier 	xatan evaluates a series valid in the
353e12c5d1SDavid du Colombier 	range [-0.414...,+0.414...].
363e12c5d1SDavid du Colombier  */
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier static
393e12c5d1SDavid du Colombier double
xatan(double arg)403e12c5d1SDavid du Colombier xatan(double arg)
413e12c5d1SDavid du Colombier {
423e12c5d1SDavid du Colombier 	double argsq, value;
433e12c5d1SDavid du Colombier 
44*7dd7cddfSDavid du Colombier 	/* get denormalized add in following if range arg**10 is much smaller
45*7dd7cddfSDavid du Colombier 	    than q1, so check for that case
46*7dd7cddfSDavid du Colombier 	*/
47*7dd7cddfSDavid du Colombier 	if(-.01 < arg && arg < .01)
48*7dd7cddfSDavid du Colombier 		value = p0/q0;
49*7dd7cddfSDavid du Colombier 	else {
503e12c5d1SDavid du Colombier 		argsq = arg*arg;
513e12c5d1SDavid du Colombier 		value = ((((p4*argsq + p3)*argsq + p2)*argsq + p1)*argsq + p0);
523e12c5d1SDavid du Colombier 		value = value/(((((argsq + q4)*argsq + q3)*argsq + q2)*argsq + q1)*argsq + q0);
53*7dd7cddfSDavid du Colombier 	}
543e12c5d1SDavid du Colombier 	return value*arg;
553e12c5d1SDavid du Colombier }
563e12c5d1SDavid du Colombier 
573e12c5d1SDavid du Colombier /*
583e12c5d1SDavid du Colombier 	satan reduces its argument (known to be positive)
593e12c5d1SDavid du Colombier 	to the range [0,0.414...] and calls xatan.
603e12c5d1SDavid du Colombier  */
613e12c5d1SDavid du Colombier 
623e12c5d1SDavid du Colombier static
633e12c5d1SDavid du Colombier double
satan(double arg)643e12c5d1SDavid du Colombier satan(double arg)
653e12c5d1SDavid du Colombier {
663e12c5d1SDavid du Colombier 
673e12c5d1SDavid du Colombier 	if(arg < sq2m1)
683e12c5d1SDavid du Colombier 		return xatan(arg);
693e12c5d1SDavid du Colombier 	if(arg > sq2p1)
703e12c5d1SDavid du Colombier 		return pio2 - xatan(1.0/arg);
713e12c5d1SDavid du Colombier 	return pio4 + xatan((arg-1.0)/(arg+1.0));
723e12c5d1SDavid du Colombier }
733e12c5d1SDavid du Colombier 
743e12c5d1SDavid du Colombier /*
753e12c5d1SDavid du Colombier 	atan makes its argument positive and
763e12c5d1SDavid du Colombier 	calls the inner routine satan.
773e12c5d1SDavid du Colombier  */
783e12c5d1SDavid du Colombier 
793e12c5d1SDavid du Colombier double
atan(double arg)803e12c5d1SDavid du Colombier atan(double arg)
813e12c5d1SDavid du Colombier {
823e12c5d1SDavid du Colombier 
833e12c5d1SDavid du Colombier 	if(arg > 0)
843e12c5d1SDavid du Colombier 		return satan(arg);
853e12c5d1SDavid du Colombier 	return -satan(-arg);
863e12c5d1SDavid du Colombier }
87