LCOV - code coverage report
Current view: top level - ld80 - e_logl.c (source / functions) Coverage Total Hit
Test: app.info Lines: 0.0 % 36 0
Test Date: 2024-01-11 15:52:50 Functions: 0.0 % 1 0
Branches: 0.0 % 16 0

             Branch data     Line data    Source code
       1                 :             : /*      $OpenBSD: e_logl.c,v 1.3 2013/11/12 20:35:19 martynas Exp $     */
       2                 :             : 
       3                 :             : /*
       4                 :             :  * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
       5                 :             :  *
       6                 :             :  * Permission to use, copy, modify, and distribute this software for any
       7                 :             :  * purpose with or without fee is hereby granted, provided that the above
       8                 :             :  * copyright notice and this permission notice appear in all copies.
       9                 :             :  *
      10                 :             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11                 :             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12                 :             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13                 :             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14                 :             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15                 :             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16                 :             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17                 :             :  */
      18                 :             : 
      19                 :             : /*                                                      logl.c
      20                 :             :  *
      21                 :             :  *      Natural logarithm, long double precision
      22                 :             :  *
      23                 :             :  *
      24                 :             :  *
      25                 :             :  * SYNOPSIS:
      26                 :             :  *
      27                 :             :  * long double x, y, logl();
      28                 :             :  *
      29                 :             :  * y = logl( x );
      30                 :             :  *
      31                 :             :  *
      32                 :             :  *
      33                 :             :  * DESCRIPTION:
      34                 :             :  *
      35                 :             :  * Returns the base e (2.718...) logarithm of x.
      36                 :             :  *
      37                 :             :  * The argument is separated into its exponent and fractional
      38                 :             :  * parts.  If the exponent is between -1 and +1, the logarithm
      39                 :             :  * of the fraction is approximated by
      40                 :             :  *
      41                 :             :  *     log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
      42                 :             :  *
      43                 :             :  * Otherwise, setting  z = 2(x-1)/x+1),
      44                 :             :  *
      45                 :             :  *     log(x) = z + z**3 P(z)/Q(z).
      46                 :             :  *
      47                 :             :  *
      48                 :             :  *
      49                 :             :  * ACCURACY:
      50                 :             :  *
      51                 :             :  *                      Relative error:
      52                 :             :  * arithmetic   domain     # trials      peak         rms
      53                 :             :  *    IEEE      0.5, 2.0    150000      8.71e-20    2.75e-20
      54                 :             :  *    IEEE     exp(+-10000) 100000      5.39e-20    2.34e-20
      55                 :             :  *
      56                 :             :  * In the tests over the interval exp(+-10000), the logarithms
      57                 :             :  * of the random arguments were uniformly distributed over
      58                 :             :  * [-10000, +10000].
      59                 :             :  *
      60                 :             :  * ERROR MESSAGES:
      61                 :             :  *
      62                 :             :  * log singularity:  x = 0; returns -INFINITY
      63                 :             :  * log domain:       x < 0; returns NAN
      64                 :             :  */
      65                 :             : 
      66                 :             : #include <openlibm_math.h>
      67                 :             : 
      68                 :             : #include "math_private.h"
      69                 :             : 
      70                 :             : /* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
      71                 :             :  * 1/sqrt(2) <= x < sqrt(2)
      72                 :             :  * Theoretical peak relative error = 2.32e-20
      73                 :             :  */
      74                 :             : static long double P[] = {
      75                 :             :  4.5270000862445199635215E-5L,
      76                 :             :  4.9854102823193375972212E-1L,
      77                 :             :  6.5787325942061044846969E0L,
      78                 :             :  2.9911919328553073277375E1L,
      79                 :             :  6.0949667980987787057556E1L,
      80                 :             :  5.7112963590585538103336E1L,
      81                 :             :  2.0039553499201281259648E1L,
      82                 :             : };
      83                 :             : static long double Q[] = {
      84                 :             : /* 1.0000000000000000000000E0,*/
      85                 :             :  1.5062909083469192043167E1L,
      86                 :             :  8.3047565967967209469434E1L,
      87                 :             :  2.2176239823732856465394E2L,
      88                 :             :  3.0909872225312059774938E2L,
      89                 :             :  2.1642788614495947685003E2L,
      90                 :             :  6.0118660497603843919306E1L,
      91                 :             : };
      92                 :             : 
      93                 :             : /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
      94                 :             :  * where z = 2(x-1)/(x+1)
      95                 :             :  * 1/sqrt(2) <= x < sqrt(2)
      96                 :             :  * Theoretical peak relative error = 6.16e-22
      97                 :             :  */
      98                 :             : 
      99                 :             : static long double R[4] = {
     100                 :             :  1.9757429581415468984296E-3L,
     101                 :             : -7.1990767473014147232598E-1L,
     102                 :             :  1.0777257190312272158094E1L,
     103                 :             : -3.5717684488096787370998E1L,
     104                 :             : };
     105                 :             : static long double S[4] = {
     106                 :             : /* 1.00000000000000000000E0L,*/
     107                 :             : -2.6201045551331104417768E1L,
     108                 :             :  1.9361891836232102174846E2L,
     109                 :             : -4.2861221385716144629696E2L,
     110                 :             : };
     111                 :             : static const long double C1 = 6.9314575195312500000000E-1L;
     112                 :             : static const long double C2 = 1.4286068203094172321215E-6L;
     113                 :             : 
     114                 :             : #define SQRTH 0.70710678118654752440L
     115                 :             : 
     116                 :             : long double
     117                 :           0 : logl(long double x)
     118                 :             : {
     119                 :             : long double y, z;
     120                 :             : int e;
     121                 :             : 
     122         [ #  # ]:           0 : if( isnan(x) )
     123                 :           0 :         return(x);
     124         [ #  # ]:           0 : if( x == INFINITY )
     125                 :           0 :         return(x);
     126                 :             : /* Test for domain */
     127         [ #  # ]:           0 : if( x <= 0.0L )
     128                 :             :         {
     129         [ #  # ]:           0 :         if( x == 0.0L )
     130                 :           0 :                 return( -INFINITY );
     131                 :             :         else
     132                 :           0 :                 return( NAN );
     133                 :             :         }
     134                 :             : 
     135                 :             : /* separate mantissa from exponent */
     136                 :             : 
     137                 :             : /* Note, frexp is used so that denormal numbers
     138                 :             :  * will be handled properly.
     139                 :             :  */
     140                 :           0 : x = frexpl( x, &e );
     141                 :             : 
     142                 :             : /* logarithm using log(x) = z + z**3 P(z)/Q(z),
     143                 :             :  * where z = 2(x-1)/x+1)
     144                 :             :  */
     145   [ #  #  #  # ]:           0 : if( (e > 2) || (e < -2) )
     146                 :             : {
     147         [ #  # ]:           0 : if( x < SQRTH )
     148                 :             :         { /* 2( 2x-1 )/( 2x+1 ) */
     149                 :           0 :         e -= 1;
     150                 :           0 :         z = x - 0.5L;
     151                 :           0 :         y = 0.5L * z + 0.5L;
     152                 :             :         }       
     153                 :             : else
     154                 :             :         { /*  2 (x-1)/(x+1)   */
     155                 :           0 :         z = x - 0.5L;
     156                 :           0 :         z -= 0.5L;
     157                 :           0 :         y = 0.5L * x  + 0.5L;
     158                 :             :         }
     159                 :           0 : x = z / y;
     160                 :           0 : z = x*x;
     161                 :           0 : z = x * ( z * __polevll( z, R, 3 ) / __p1evll( z, S, 3 ) );
     162                 :           0 : z = z + e * C2;
     163                 :           0 : z = z + x;
     164                 :           0 : z = z + e * C1;
     165                 :           0 : return( z );
     166                 :             : }
     167                 :             : 
     168                 :             : 
     169                 :             : /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
     170                 :             : 
     171         [ #  # ]:           0 : if( x < SQRTH )
     172                 :             :         {
     173                 :           0 :         e -= 1;
     174                 :           0 :         x = ldexpl( x, 1 ) - 1.0L; /*  2x - 1  */
     175                 :             :         }       
     176                 :             : else
     177                 :             :         {
     178                 :           0 :         x = x - 1.0L;
     179                 :             :         }
     180                 :           0 : z = x*x;
     181                 :           0 : y = x * ( z * __polevll( x, P, 6 ) / __p1evll( x, Q, 6 ) );
     182                 :           0 : y = y + e * C2;
     183                 :           0 : z = y - ldexpl( z, -1 );   /*  y - 0.5 * z  */
     184                 :             : /* Note, the sum of above terms does not exceed x/4,
     185                 :             :  * so it contributes at most about 1/4 lsb to the error.
     186                 :             :  */
     187                 :           0 : z = z + x;
     188                 :           0 : z = z + e * C1; /* This sum has an error of 1/2 lsb. */
     189                 :           0 : return( z );
     190                 :             : }
        

Generated by: LCOV version 2.0-115.g950771e