Home | History | Annotate | Line # | Download | only in math
      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