summaryrefslogtreecommitdiff
path: root/libm/float/sinf.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-05-10 00:40:28 +0000
committerEric Andersen <andersen@codepoet.org>2001-05-10 00:40:28 +0000
commit1077fa4d772832f77a677ce7fb7c2d513b959e3f (patch)
tree579bee13fb0b58d2800206366ec2caecbb15f3fc /libm/float/sinf.c
parent22358dd7ce7bb49792204b698f01a6f69b9c8e08 (diff)
uClibc now has a math library. muahahahaha!
-Erik
Diffstat (limited to 'libm/float/sinf.c')
-rw-r--r--libm/float/sinf.c283
1 files changed, 283 insertions, 0 deletions
diff --git a/libm/float/sinf.c b/libm/float/sinf.c
new file mode 100644
index 000000000..2f1bb45b8
--- /dev/null
+++ b/libm/float/sinf.c
@@ -0,0 +1,283 @@
+/* sinf.c
+ *
+ * Circular sine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float x, y, sinf();
+ *
+ * y = sinf( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Range reduction is into intervals of pi/4. The reduction
+ * error is nearly eliminated by contriving an extended precision
+ * modular arithmetic.
+ *
+ * Two polynomial approximating functions are employed.
+ * Between 0 and pi/4 the sine is approximated by
+ * x + x**3 P(x**2).
+ * Between pi/4 and pi/2 the cosine is represented as
+ * 1 - x**2 Q(x**2).
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -4096,+4096 100,000 1.2e-7 3.0e-8
+ * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8
+ *
+ * ERROR MESSAGES:
+ *
+ * message condition value returned
+ * sin total loss x > 2^24 0.0
+ *
+ * Partial loss of accuracy begins to occur at x = 2^13
+ * = 8192. Results may be meaningless for x >= 2^24
+ * The routine as implemented flags a TLOSS error
+ * for x >= 2^24 and returns 0.0.
+ */
+
+/* cosf.c
+ *
+ * Circular cosine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float x, y, cosf();
+ *
+ * y = cosf( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Range reduction is into intervals of pi/4. The reduction
+ * error is nearly eliminated by contriving an extended precision
+ * modular arithmetic.
+ *
+ * Two polynomial approximating functions are employed.
+ * Between 0 and pi/4 the cosine is approximated by
+ * 1 - x**2 Q(x**2).
+ * Between pi/4 and pi/2 the sine is represented as
+ * x + x**3 P(x**2).
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8
+ */
+
+/*
+Cephes Math Library Release 2.2: June, 1992
+Copyright 1985, 1987, 1988, 1992 by Stephen L. Moshier
+Direct inquiries to 30 Frost Street, Cambridge, MA 02140
+*/
+
+
+/* Single precision circular sine
+ * test interval: [-pi/4, +pi/4]
+ * trials: 10000
+ * peak relative error: 6.8e-8
+ * rms relative error: 2.6e-8
+ */
+#include <math.h>
+
+
+static float FOPI = 1.27323954473516;
+
+extern float PIO4F;
+/* Note, these constants are for a 32-bit significand: */
+/*
+static float DP1 = 0.7853851318359375;
+static float DP2 = 1.30315311253070831298828125e-5;
+static float DP3 = 3.03855025325309630e-11;
+static float lossth = 65536.;
+*/
+
+/* These are for a 24-bit significand: */
+static float DP1 = 0.78515625;
+static float DP2 = 2.4187564849853515625e-4;
+static float DP3 = 3.77489497744594108e-8;
+static float lossth = 8192.;
+static float T24M1 = 16777215.;
+
+static float sincof[] = {
+-1.9515295891E-4,
+ 8.3321608736E-3,
+-1.6666654611E-1
+};
+static float coscof[] = {
+ 2.443315711809948E-005,
+-1.388731625493765E-003,
+ 4.166664568298827E-002
+};
+
+float sinf( float xx )
+{
+float *p;
+float x, y, z;
+register unsigned long j;
+register int sign;
+
+sign = 1;
+x = xx;
+if( xx < 0 )
+ {
+ sign = -1;
+ x = -xx;
+ }
+if( x > T24M1 )
+ {
+ mtherr( "sinf", TLOSS );
+ return(0.0);
+ }
+j = FOPI * x; /* integer part of x/(PI/4) */
+y = j;
+/* map zeros to origin */
+if( j & 1 )
+ {
+ j += 1;
+ y += 1.0;
+ }
+j &= 7; /* octant modulo 360 degrees */
+/* reflect in x axis */
+if( j > 3)
+ {
+ sign = -sign;
+ j -= 4;
+ }
+
+if( x > lossth )
+ {
+ mtherr( "sinf", PLOSS );
+ x = x - y * PIO4F;
+ }
+else
+ {
+/* Extended precision modular arithmetic */
+ x = ((x - y * DP1) - y * DP2) - y * DP3;
+ }
+/*einits();*/
+z = x * x;
+if( (j==1) || (j==2) )
+ {
+/* measured relative error in +/- pi/4 is 7.8e-8 */
+/*
+ y = (( 2.443315711809948E-005 * z
+ - 1.388731625493765E-003) * z
+ + 4.166664568298827E-002) * z * z;
+*/
+ p = coscof;
+ y = *p++;
+ y = y * z + *p++;
+ y = y * z + *p++;
+ y *= z * z;
+ y -= 0.5 * z;
+ y += 1.0;
+ }
+else
+ {
+/* Theoretical relative error = 3.8e-9 in [-pi/4, +pi/4] */
+/*
+ y = ((-1.9515295891E-4 * z
+ + 8.3321608736E-3) * z
+ - 1.6666654611E-1) * z * x;
+ y += x;
+*/
+ p = sincof;
+ y = *p++;
+ y = y * z + *p++;
+ y = y * z + *p++;
+ y *= z * x;
+ y += x;
+ }
+/*einitd();*/
+if(sign < 0)
+ y = -y;
+return( y);
+}
+
+
+/* Single precision circular cosine
+ * test interval: [-pi/4, +pi/4]
+ * trials: 10000
+ * peak relative error: 8.3e-8
+ * rms relative error: 2.2e-8
+ */
+
+float cosf( float xx )
+{
+float x, y, z;
+int j, sign;
+
+/* make argument positive */
+sign = 1;
+x = xx;
+if( x < 0 )
+ x = -x;
+
+if( x > T24M1 )
+ {
+ mtherr( "cosf", TLOSS );
+ return(0.0);
+ }
+
+j = FOPI * x; /* integer part of x/PIO4 */
+y = j;
+/* integer and fractional part modulo one octant */
+if( j & 1 ) /* map zeros to origin */
+ {
+ j += 1;
+ y += 1.0;
+ }
+j &= 7;
+if( j > 3)
+ {
+ j -=4;
+ sign = -sign;
+ }
+
+if( j > 1 )
+ sign = -sign;
+
+if( x > lossth )
+ {
+ mtherr( "cosf", PLOSS );
+ x = x - y * PIO4F;
+ }
+else
+/* Extended precision modular arithmetic */
+ x = ((x - y * DP1) - y * DP2) - y * DP3;
+
+z = x * x;
+
+if( (j==1) || (j==2) )
+ {
+ y = (((-1.9515295891E-4 * z
+ + 8.3321608736E-3) * z
+ - 1.6666654611E-1) * z * x)
+ + x;
+ }
+else
+ {
+ y = (( 2.443315711809948E-005 * z
+ - 1.388731625493765E-003) * z
+ + 4.166664568298827E-002) * z * z;
+ y -= 0.5 * z;
+ y += 1.0;
+ }
+if(sign < 0)
+ y = -y;
+return( y );
+}
+