re-enable vdso clock_gettime on arm (32-bit) with workaround
[musl] / src / math / logl.c
index 2139b2a..5d53659 100644 (file)
@@ -35,9 +35,9 @@
  *
  *     log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
  *
- * Otherwise, setting  z = 2(x-1)/x+1),
+ * Otherwise, setting  z = 2(x-1)/(x+1),
  *
- *     log(x) = z + z**3 P(z)/Q(z).
+ *     log(x) = log(1+z/2) - log(1-z/2) = z + z**3 P(z)/Q(z).
  *
  *
  * ACCURACY:
  * In the tests over the interval exp(+-10000), the logarithms
  * of the random arguments were uniformly distributed over
  * [-10000, +10000].
- *
- * ERROR MESSAGES:
- *
- * log singularity:  x = 0; returns -INFINITY
- * log domain:       x < 0; returns NAN
  */
 
 #include "libm.h"
@@ -69,7 +64,7 @@ long double logl(long double x)
  * 1/sqrt(2) <= x < sqrt(2)
  * Theoretical peak relative error = 2.32e-20
  */
-static long double P[] = {
+static const long double P[] = {
  4.5270000862445199635215E-5L,
  4.9854102823193375972212E-1L,
  6.5787325942061044846969E0L,
@@ -78,7 +73,7 @@ static long double P[] = {
  5.7112963590585538103336E1L,
  2.0039553499201281259648E1L,
 };
-static long double Q[] = {
+static const long double Q[] = {
 /* 1.0000000000000000000000E0,*/
  1.5062909083469192043167E1L,
  8.3047565967967209469434E1L,
@@ -93,13 +88,13 @@ static long double Q[] = {
  * 1/sqrt(2) <= x < sqrt(2)
  * Theoretical peak relative error = 6.16e-22
  */
-static long double R[4] = {
+static const long double R[4] = {
  1.9757429581415468984296E-3L,
 -7.1990767473014147232598E-1L,
  1.0777257190312272158094E1L,
 -3.5717684488096787370998E1L,
 };
-static long double S[4] = {
+static const long double S[4] = {
 /* 1.00000000000000000000E0L,*/
 -2.6201045551331104417768E1L,
  1.9361891836232102174846E2L,
@@ -119,10 +114,10 @@ long double logl(long double x)
                return x;
        if (x == INFINITY)
                return x;
-       if (x <= 0.0L) {
-               if (x == 0.0L)
-                       return -INFINITY;
-               return NAN;
+       if (x <= 0.0) {
+               if (x == 0.0)
+                       return -1/(x*x); /* -inf with divbyzero */
+               return 0/0.0f; /* nan with invalid */
        }
 
        /* separate mantissa from exponent */
@@ -132,17 +127,17 @@ long double logl(long double x)
        x = frexpl(x, &e);
 
        /* logarithm using log(x) = z + z**3 P(z)/Q(z),
-        * where z = 2(x-1)/x+1)
+        * where z = 2(x-1)/(x+1)
         */
        if (e > 2 || e < -2) {
                if (x < SQRTH) {  /* 2(2x-1)/(2x+1) */
                        e -= 1;
-                       z = x - 0.5L;
-                       y = 0.5L * z + 0.5L;
+                       z = x - 0.5;
+                       y = 0.5 * z + 0.5;
                } else {  /*  2 (x-1)/(x+1)   */
-                       z = x - 0.5L;
-                       z -= 0.5L;
-                       y = 0.5L * x  + 0.5L;
+                       z = x - 0.5;
+                       z -= 0.5;
+                       y = 0.5 * x  + 0.5;
                }
                x = z / y;
                z = x*x;
@@ -156,14 +151,14 @@ long double logl(long double x)
        /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
        if (x < SQRTH) {
                e -= 1;
-               x = ldexpl(x, 1) - 1.0L; /*  2x - 1  */
+               x = 2.0*x - 1.0;
        } else {
-               x = x - 1.0L;
+               x = x - 1.0;
        }
        z = x*x;
        y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6));
        y = y + e * C2;
-       z = y - ldexpl(z, -1);   /*  y - 0.5 * z  */
+       z = y - 0.5*z;
        /* Note, the sum of above terms does not exceed x/4,
         * so it contributes at most about 1/4 lsb to the error.
         */
@@ -171,4 +166,10 @@ long double logl(long double x)
        z = z + e * C1; /* This sum has an error of 1/2 lsb. */
        return z;
 }
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double logl(long double x)
+{
+       return log(x);
+}
 #endif