1 1.1 mrg /* log10l.c 2 1.1 mrg * 3 1.1 mrg * Common logarithm, 128-bit long double precision 4 1.1 mrg * 5 1.1 mrg * 6 1.1 mrg * 7 1.1 mrg * SYNOPSIS: 8 1.1 mrg * 9 1.1 mrg * long double x, y, log10l(); 10 1.1 mrg * 11 1.1 mrg * y = log10l( x ); 12 1.1 mrg * 13 1.1 mrg * 14 1.1 mrg * 15 1.1 mrg * DESCRIPTION: 16 1.1 mrg * 17 1.1 mrg * Returns the base 10 logarithm of x. 18 1.1 mrg * 19 1.1 mrg * The argument is separated into its exponent and fractional 20 1.1 mrg * parts. If the exponent is between -1 and +1, the logarithm 21 1.1 mrg * of the fraction is approximated by 22 1.1 mrg * 23 1.1 mrg * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). 24 1.1 mrg * 25 1.1 mrg * Otherwise, setting z = 2(x-1)/x+1), 26 1.1 mrg * 27 1.1 mrg * log(x) = z + z^3 P(z)/Q(z). 28 1.1 mrg * 29 1.1 mrg * 30 1.1 mrg * 31 1.1 mrg * ACCURACY: 32 1.1 mrg * 33 1.1 mrg * Relative error: 34 1.1 mrg * arithmetic domain # trials peak rms 35 1.1 mrg * IEEE 0.5, 2.0 30000 2.3e-34 4.9e-35 36 1.1 mrg * IEEE exp(+-10000) 30000 1.0e-34 4.1e-35 37 1.1 mrg * 38 1.1 mrg * In the tests over the interval exp(+-10000), the logarithms 39 1.1 mrg * of the random arguments were uniformly distributed over 40 1.1 mrg * [-10000, +10000]. 41 1.1 mrg * 42 1.1 mrg */ 43 1.1 mrg 44 1.1 mrg /* 45 1.1 mrg Cephes Math Library Release 2.2: January, 1991 46 1.1 mrg Copyright 1984, 1991 by Stephen L. Moshier 47 1.1 mrg Adapted for glibc November, 2001 48 1.1 mrg 49 1.1 mrg This library is free software; you can redistribute it and/or 50 1.1 mrg modify it under the terms of the GNU Lesser General Public 51 1.1 mrg License as published by the Free Software Foundation; either 52 1.1 mrg version 2.1 of the License, or (at your option) any later version. 53 1.1 mrg 54 1.1 mrg This library is distributed in the hope that it will be useful, 55 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 56 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 57 1.1 mrg Lesser General Public License for more details. 58 1.1 mrg 59 1.1 mrg You should have received a copy of the GNU Lesser General Public 60 1.1 mrg License along with this library; if not, see <http://www.gnu.org/licenses/>. 61 1.1 mrg */ 62 1.1 mrg 63 1.1 mrg #include "quadmath-imp.h" 64 1.1 mrg 65 1.1 mrg /* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x) 66 1.1 mrg * 1/sqrt(2) <= x < sqrt(2) 67 1.1 mrg * Theoretical peak relative error = 5.3e-37, 68 1.1 mrg * relative peak error spread = 2.3e-14 69 1.1 mrg */ 70 1.1 mrg static const __float128 P[13] = 71 1.1 mrg { 72 1.1 mrg 1.313572404063446165910279910527789794488E4Q, 73 1.1 mrg 7.771154681358524243729929227226708890930E4Q, 74 1.1 mrg 2.014652742082537582487669938141683759923E5Q, 75 1.1 mrg 3.007007295140399532324943111654767187848E5Q, 76 1.1 mrg 2.854829159639697837788887080758954924001E5Q, 77 1.1 mrg 1.797628303815655343403735250238293741397E5Q, 78 1.1 mrg 7.594356839258970405033155585486712125861E4Q, 79 1.1 mrg 2.128857716871515081352991964243375186031E4Q, 80 1.1 mrg 3.824952356185897735160588078446136783779E3Q, 81 1.1 mrg 4.114517881637811823002128927449878962058E2Q, 82 1.1 mrg 2.321125933898420063925789532045674660756E1Q, 83 1.1 mrg 4.998469661968096229986658302195402690910E-1Q, 84 1.1 mrg 1.538612243596254322971797716843006400388E-6Q 85 1.1 mrg }; 86 1.1 mrg static const __float128 Q[12] = 87 1.1 mrg { 88 1.1 mrg 3.940717212190338497730839731583397586124E4Q, 89 1.1 mrg 2.626900195321832660448791748036714883242E5Q, 90 1.1 mrg 7.777690340007566932935753241556479363645E5Q, 91 1.1 mrg 1.347518538384329112529391120390701166528E6Q, 92 1.1 mrg 1.514882452993549494932585972882995548426E6Q, 93 1.1 mrg 1.158019977462989115839826904108208787040E6Q, 94 1.1 mrg 6.132189329546557743179177159925690841200E5Q, 95 1.1 mrg 2.248234257620569139969141618556349415120E5Q, 96 1.1 mrg 5.605842085972455027590989944010492125825E4Q, 97 1.1 mrg 9.147150349299596453976674231612674085381E3Q, 98 1.1 mrg 9.104928120962988414618126155557301584078E2Q, 99 1.1 mrg 4.839208193348159620282142911143429644326E1Q 100 1.1 mrg /* 1.000000000000000000000000000000000000000E0L, */ 101 1.1 mrg }; 102 1.1 mrg 103 1.1 mrg /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), 104 1.1 mrg * where z = 2(x-1)/(x+1) 105 1.1 mrg * 1/sqrt(2) <= x < sqrt(2) 106 1.1 mrg * Theoretical peak relative error = 1.1e-35, 107 1.1 mrg * relative peak error spread 1.1e-9 108 1.1 mrg */ 109 1.1 mrg static const __float128 R[6] = 110 1.1 mrg { 111 1.1 mrg 1.418134209872192732479751274970992665513E5Q, 112 1.1 mrg -8.977257995689735303686582344659576526998E4Q, 113 1.1 mrg 2.048819892795278657810231591630928516206E4Q, 114 1.1 mrg -2.024301798136027039250415126250455056397E3Q, 115 1.1 mrg 8.057002716646055371965756206836056074715E1Q, 116 1.1 mrg -8.828896441624934385266096344596648080902E-1Q 117 1.1 mrg }; 118 1.1 mrg static const __float128 S[6] = 119 1.1 mrg { 120 1.1 mrg 1.701761051846631278975701529965589676574E6Q, 121 1.1 mrg -1.332535117259762928288745111081235577029E6Q, 122 1.1 mrg 4.001557694070773974936904547424676279307E5Q, 123 1.1 mrg -5.748542087379434595104154610899551484314E4Q, 124 1.1 mrg 3.998526750980007367835804959888064681098E3Q, 125 1.1 mrg -1.186359407982897997337150403816839480438E2Q 126 1.1 mrg /* 1.000000000000000000000000000000000000000E0L, */ 127 1.1 mrg }; 128 1.1 mrg 129 1.1 mrg static const __float128 130 1.1 mrg /* log10(2) */ 131 1.1 mrg L102A = 0.3125Q, 132 1.1 mrg L102B = -1.14700043360188047862611052755069732318101185E-2Q, 133 1.1 mrg /* log10(e) */ 134 1.1 mrg L10EA = 0.5Q, 135 1.1 mrg L10EB = -6.570551809674817234887108108339491770560299E-2Q, 136 1.1 mrg /* sqrt(2)/2 */ 137 1.1 mrg SQRTH = 7.071067811865475244008443621048490392848359E-1Q; 138 1.1 mrg 139 1.1 mrg 140 1.1 mrg 141 1.1 mrg /* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */ 142 1.1 mrg 143 1.1 mrg static __float128 144 1.1 mrg neval (__float128 x, const __float128 *p, int n) 145 1.1 mrg { 146 1.1 mrg __float128 y; 147 1.1 mrg 148 1.1 mrg p += n; 149 1.1 mrg y = *p--; 150 1.1 mrg do 151 1.1 mrg { 152 1.1 mrg y = y * x + *p--; 153 1.1 mrg } 154 1.1 mrg while (--n > 0); 155 1.1 mrg return y; 156 1.1 mrg } 157 1.1 mrg 158 1.1 mrg 159 1.1 mrg /* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */ 160 1.1 mrg 161 1.1 mrg static __float128 162 1.1 mrg deval (__float128 x, const __float128 *p, int n) 163 1.1 mrg { 164 1.1 mrg __float128 y; 165 1.1 mrg 166 1.1 mrg p += n; 167 1.1 mrg y = x + *p--; 168 1.1 mrg do 169 1.1 mrg { 170 1.1 mrg y = y * x + *p--; 171 1.1 mrg } 172 1.1 mrg while (--n > 0); 173 1.1 mrg return y; 174 1.1 mrg } 175 1.1 mrg 176 1.1 mrg 177 1.1 mrg 178 1.1 mrg __float128 179 1.1 mrg log10q (__float128 x) 180 1.1 mrg { 181 1.1 mrg __float128 z; 182 1.1 mrg __float128 y; 183 1.1 mrg int e; 184 1.1 mrg int64_t hx, lx; 185 1.1 mrg 186 1.1 mrg /* Test for domain */ 187 1.1 mrg GET_FLT128_WORDS64 (hx, lx, x); 188 1.1 mrg if (((hx & 0x7fffffffffffffffLL) | lx) == 0) 189 1.1 mrg return (-1 / fabsq (x)); /* log10l(+-0)=-inf */ 190 1.1 mrg if (hx < 0) 191 1.1 mrg return (x - x) / (x - x); 192 1.1 mrg if (hx >= 0x7fff000000000000LL) 193 1.1 mrg return (x + x); 194 1.1 mrg 195 1.1 mrg if (x == 1) 196 1.1 mrg return 0; 197 1.1 mrg 198 1.1 mrg /* separate mantissa from exponent */ 199 1.1 mrg 200 1.1 mrg /* Note, frexp is used so that denormal numbers 201 1.1 mrg * will be handled properly. 202 1.1 mrg */ 203 1.1 mrg x = frexpq (x, &e); 204 1.1 mrg 205 1.1 mrg 206 1.1 mrg /* logarithm using log(x) = z + z**3 P(z)/Q(z), 207 1.1 mrg * where z = 2(x-1)/x+1) 208 1.1 mrg */ 209 1.1 mrg if ((e > 2) || (e < -2)) 210 1.1 mrg { 211 1.1 mrg if (x < SQRTH) 212 1.1 mrg { /* 2( 2x-1 )/( 2x+1 ) */ 213 1.1 mrg e -= 1; 214 1.1 mrg z = x - 0.5Q; 215 1.1 mrg y = 0.5Q * z + 0.5Q; 216 1.1 mrg } 217 1.1 mrg else 218 1.1 mrg { /* 2 (x-1)/(x+1) */ 219 1.1 mrg z = x - 0.5Q; 220 1.1 mrg z -= 0.5Q; 221 1.1 mrg y = 0.5Q * x + 0.5Q; 222 1.1 mrg } 223 1.1 mrg x = z / y; 224 1.1 mrg z = x * x; 225 1.1 mrg y = x * (z * neval (z, R, 5) / deval (z, S, 5)); 226 1.1 mrg goto done; 227 1.1 mrg } 228 1.1 mrg 229 1.1 mrg 230 1.1 mrg /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ 231 1.1 mrg 232 1.1 mrg if (x < SQRTH) 233 1.1 mrg { 234 1.1 mrg e -= 1; 235 1.1 mrg x = 2.0 * x - 1; /* 2x - 1 */ 236 1.1 mrg } 237 1.1 mrg else 238 1.1 mrg { 239 1.1 mrg x = x - 1; 240 1.1 mrg } 241 1.1 mrg z = x * x; 242 1.1 mrg y = x * (z * neval (x, P, 12) / deval (x, Q, 11)); 243 1.1 mrg y = y - 0.5 * z; 244 1.1 mrg 245 1.1 mrg done: 246 1.1 mrg 247 1.1 mrg /* Multiply log of fraction by log10(e) 248 1.1 mrg * and base 2 exponent by log10(2). 249 1.1 mrg */ 250 1.1 mrg z = y * L10EB; 251 1.1 mrg z += x * L10EB; 252 1.1 mrg z += e * L102B; 253 1.1 mrg z += y * L10EA; 254 1.1 mrg z += x * L10EA; 255 1.1 mrg z += e * L102A; 256 1.1 mrg return (z); 257 1.1 mrg } 258