summaryrefslogtreecommitdiff
path: root/libm/float/atanf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libm/float/atanf.c')
-rw-r--r--libm/float/atanf.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/libm/float/atanf.c b/libm/float/atanf.c
new file mode 100644
index 000000000..321e3be39
--- /dev/null
+++ b/libm/float/atanf.c
@@ -0,0 +1,190 @@
+/* atanf.c
+ *
+ * Inverse circular tangent
+ * (arctangent)
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float x, y, atanf();
+ *
+ * y = atanf( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns radian angle between -pi/2 and +pi/2 whose tangent
+ * is x.
+ *
+ * Range reduction is from four intervals into the interval
+ * from zero to tan( pi/8 ). A polynomial approximates
+ * the function in this basic interval.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10, 10 100000 1.9e-7 4.1e-8
+ *
+ */
+ /* atan2f()
+ *
+ * Quadrant correct inverse circular tangent
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float x, y, z, atan2f();
+ *
+ * z = atan2f( y, x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns radian angle whose tangent is y/x.
+ * Define compile time symbol ANSIC = 1 for ANSI standard,
+ * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range
+ * 0 to 2PI, args (x,y).
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10, 10 100000 1.9e-7 4.1e-8
+ * See atan.c.
+ *
+ */
+
+/* atan.c */
+
+
+/*
+Cephes Math Library Release 2.2: June, 1992
+Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier
+Direct inquiries to 30 Frost Street, Cambridge, MA 02140
+*/
+
+/* Single precision circular arcsine
+ * test interval: [-tan(pi/8), +tan(pi/8)]
+ * trials: 10000
+ * peak relative error: 7.7e-8
+ * rms relative error: 2.9e-8
+ */
+#include <math.h>
+extern float PIF, PIO2F, PIO4F;
+
+float atanf( float xx )
+{
+float x, y, z;
+int sign;
+
+x = xx;
+
+/* make argument positive and save the sign */
+if( xx < 0.0 )
+ {
+ sign = -1;
+ x = -xx;
+ }
+else
+ {
+ sign = 1;
+ x = xx;
+ }
+/* range reduction */
+if( x > 2.414213562373095 ) /* tan 3pi/8 */
+ {
+ y = PIO2F;
+ x = -( 1.0/x );
+ }
+
+else if( x > 0.4142135623730950 ) /* tan pi/8 */
+ {
+ y = PIO4F;
+ x = (x-1.0)/(x+1.0);
+ }
+else
+ y = 0.0;
+
+z = x * x;
+y +=
+((( 8.05374449538e-2 * z
+ - 1.38776856032E-1) * z
+ + 1.99777106478E-1) * z
+ - 3.33329491539E-1) * z * x
+ + x;
+
+if( sign < 0 )
+ y = -y;
+
+return( y );
+}
+
+
+
+
+float atan2f( float y, float x )
+{
+float z, w;
+int code;
+
+
+code = 0;
+
+if( x < 0.0 )
+ code = 2;
+if( y < 0.0 )
+ code |= 1;
+
+if( x == 0.0 )
+ {
+ if( code & 1 )
+ {
+#if ANSIC
+ return( -PIO2F );
+#else
+ return( 3.0*PIO2F );
+#endif
+ }
+ if( y == 0.0 )
+ return( 0.0 );
+ return( PIO2F );
+ }
+
+if( y == 0.0 )
+ {
+ if( code & 2 )
+ return( PIF );
+ return( 0.0 );
+ }
+
+
+switch( code )
+ {
+ default:
+#if ANSIC
+ case 0:
+ case 1: w = 0.0; break;
+ case 2: w = PIF; break;
+ case 3: w = -PIF; break;
+#else
+ case 0: w = 0.0; break;
+ case 1: w = 2.0 * PIF; break;
+ case 2:
+ case 3: w = PIF; break;
+#endif
+ }
+
+z = atanf( y/x );
+
+return( w + z );
+}
+