summaryrefslogtreecommitdiff
path: root/libm/float/logf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libm/float/logf.c')
-rw-r--r--libm/float/logf.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/libm/float/logf.c b/libm/float/logf.c
new file mode 100644
index 000000000..750138564
--- /dev/null
+++ b/libm/float/logf.c
@@ -0,0 +1,128 @@
+/* logf.c
+ *
+ * Natural logarithm
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float x, y, logf();
+ *
+ * y = logf( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base e (2.718...) logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts. If the exponent is between -1 and +1, the logarithm
+ * of the fraction is approximated by
+ *
+ * log(1+x) = x - 0.5 x**2 + x**3 P(x)
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE 0.5, 2.0 100000 7.6e-8 2.7e-8
+ * IEEE 1, MAXNUMF 100000 2.6e-8
+ *
+ * In the tests over the interval [1, MAXNUM], the logarithms
+ * of the random arguments were uniformly distributed over
+ * [0, MAXLOGF].
+ *
+ * ERROR MESSAGES:
+ *
+ * logf singularity: x = 0; returns MINLOG
+ * logf domain: x < 0; returns MINLOG
+ */
+
+/*
+Cephes Math Library Release 2.2: June, 1992
+Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
+Direct inquiries to 30 Frost Street, Cambridge, MA 02140
+*/
+
+/* Single precision natural logarithm
+ * test interval: [sqrt(2)/2, sqrt(2)]
+ * trials: 10000
+ * peak relative error: 7.1e-8
+ * rms relative error: 2.7e-8
+ */
+
+#include <math.h>
+extern float MINLOGF, SQRTHF;
+
+
+float frexpf( float, int * );
+
+float logf( float xx )
+{
+register float y;
+float x, z, fe;
+int e;
+
+x = xx;
+fe = 0.0;
+/* Test for domain */
+if( x <= 0.0 )
+ {
+ if( x == 0.0 )
+ mtherr( "logf", SING );
+ else
+ mtherr( "logf", DOMAIN );
+ return( MINLOGF );
+ }
+
+x = frexpf( x, &e );
+if( x < SQRTHF )
+ {
+ e -= 1;
+ x = x + x - 1.0; /* 2x - 1 */
+ }
+else
+ {
+ x = x - 1.0;
+ }
+z = x * x;
+/* 3.4e-9 */
+/*
+p = logfcof;
+y = *p++ * x;
+for( i=0; i<8; i++ )
+ {
+ y += *p++;
+ y *= x;
+ }
+y *= z;
+*/
+
+y =
+(((((((( 7.0376836292E-2 * x
+- 1.1514610310E-1) * x
++ 1.1676998740E-1) * x
+- 1.2420140846E-1) * x
++ 1.4249322787E-1) * x
+- 1.6668057665E-1) * x
++ 2.0000714765E-1) * x
+- 2.4999993993E-1) * x
++ 3.3333331174E-1) * x * z;
+
+if( e )
+ {
+ fe = e;
+ y += -2.12194440e-4 * fe;
+ }
+
+y += -0.5 * z; /* y - 0.5 x^2 */
+z = x + y; /* ... + x */
+
+if( e )
+ z += 0.693359375 * fe;
+
+return( z );
+}