X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fmath%2Flogl.c;h=5d5365929e62a351c4544bd9e6aace6e02834292;hb=04b8360adbb6487f61aa0c00e53ec3a90a5a0d29;hp=2139b2ab67732bbb3457ca49a87e5ebeafa1193d;hpb=b69f695acedd4ce2798ef9ea28d834ceccc789bd;p=musl diff --git a/src/math/logl.c b/src/math/logl.c index 2139b2ab..5d536592 100644 --- a/src/math/logl.c +++ b/src/math/logl.c @@ -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: @@ -50,11 +50,6 @@ * 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