home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / math / cephes / ldouble / logl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-17  |  5.9 KB  |  262 lines

  1. /*                            logl.c
  2.  *
  3.  *    Natural logarithm, long double precision
  4.  *
  5.  *
  6.  *
  7.  * SYNOPSIS:
  8.  *
  9.  * long double x, y, logl();
  10.  *
  11.  * y = logl( x );
  12.  *
  13.  *
  14.  *
  15.  * DESCRIPTION:
  16.  *
  17.  * Returns the base e (2.718...) logarithm of x.
  18.  *
  19.  * The argument is separated into its exponent and fractional
  20.  * parts.  If the exponent is between -1 and +1, the logarithm
  21.  * of the fraction is approximated by
  22.  *
  23.  *     log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
  24.  *
  25.  * Otherwise, setting  z = 2(x-1)/x+1),
  26.  * 
  27.  *     log(x) = z + z**3 P(z)/Q(z).
  28.  *
  29.  *
  30.  *
  31.  * ACCURACY:
  32.  *
  33.  *                      Relative error:
  34.  * arithmetic   domain     # trials      peak         rms
  35.  *    IEEE      0.5, 2.0    150000      8.71e-20    2.75e-20
  36.  *    IEEE     exp(+-10000) 100000      5.39e-20    2.34e-20
  37.  *
  38.  * In the tests over the interval exp(+-10000), the logarithms
  39.  * of the random arguments were uniformly distributed over
  40.  * [-10000, +10000].
  41.  *
  42.  * ERROR MESSAGES:
  43.  *
  44.  * log singularity:  x = 0; returns MINLOG
  45.  * log domain:       x < 0; returns MINLOG
  46.  */
  47.  
  48. /*
  49. Cephes Math Library Release 2.2:  December, 1990
  50. Copyright 1984, 1990 by Stephen L. Moshier
  51. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  52. */
  53.  
  54. #include "mconf.h"
  55. static char fname[] = {"logl"};
  56.  
  57. /* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
  58.  * 1/sqrt(2) <= x < sqrt(2)
  59.  * Theoretical peak relative error = 2.32e-20
  60.  */
  61. #ifdef UNK
  62. static long double P[] = {
  63.  4.5270000862445199635215E-5,
  64.  4.9854102823193375972212E-1,
  65.  6.5787325942061044846969E0,
  66.  2.9911919328553073277375E1,
  67.  6.0949667980987787057556E1,
  68.  5.7112963590585538103336E1,
  69.  2.0039553499201281259648E1,
  70. };
  71. static long double Q[] = {
  72. /* 1.0000000000000000000000E0,*/
  73.  1.5062909083469192043167E1,
  74.  8.3047565967967209469434E1,
  75.  2.2176239823732856465394E2,
  76.  3.0909872225312059774938E2,
  77.  2.1642788614495947685003E2,
  78.  6.0118660497603843919306E1,
  79. };
  80. #endif
  81.  
  82. #ifdef IBMPC
  83. static short P[] = {
  84. 0x51b9,0x9cae,0x4b15,0xbde0,0x3ff0,
  85. 0x19cf,0xf0d4,0xc507,0xff40,0x3ffd,
  86. 0x9942,0xa7d2,0xfa37,0xd284,0x4001,
  87. 0x4add,0x65ce,0x9c5c,0xef4b,0x4003,
  88. 0x8445,0x619a,0x75c3,0xf3cc,0x4004,
  89. 0x81ab,0x3cd0,0xacba,0xe473,0x4004,
  90. 0x4cbf,0xcc18,0x016c,0xa051,0x4003,
  91. };
  92. static short Q[] = {
  93. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  94. 0xb8b7,0x81f1,0xacf4,0xf101,0x4002,
  95. 0xbc31,0x09a4,0x5a91,0xa618,0x4005,
  96. 0xaeec,0xe7da,0x2c87,0xddc3,0x4006,
  97. 0x2bde,0x4845,0xa2ee,0x9a8c,0x4007,
  98. 0x3120,0x4703,0x89f2,0xd86d,0x4006,
  99. 0x7347,0x3224,0x8223,0xf079,0x4004,
  100. };
  101. #endif
  102.  
  103. #ifdef MIEEE
  104. static long P[] = {
  105. 0x3ff00000,0xbde04b15,0x9cae51b9,
  106. 0x3ffd0000,0xff40c507,0xf0d419cf,
  107. 0x40010000,0xd284fa37,0xa7d29942,
  108. 0x40030000,0xef4b9c5c,0x65ce4add,
  109. 0x40040000,0xf3cc75c3,0x619a8445,
  110. 0x40040000,0xe473acba,0x3cd081ab,
  111. 0x40030000,0xa051016c,0xcc184cbf,
  112. };
  113. static long Q[] = {
  114. /*0x3fff0000,0x80000000,0x00000000,*/
  115. 0x40020000,0xf101acf4,0x81f1b8b7,
  116. 0x40050000,0xa6185a91,0x09a4bc31,
  117. 0x40060000,0xddc32c87,0xe7daaeec,
  118. 0x40070000,0x9a8ca2ee,0x48452bde,
  119. 0x40060000,0xd86d89f2,0x47033120,
  120. 0x40040000,0xf0798223,0x32247347,
  121. };
  122. #endif
  123.  
  124. /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
  125.  * where z = 2(x-1)/(x+1)
  126.  * 1/sqrt(2) <= x < sqrt(2)
  127.  * Theoretical peak relative error = 6.16e-22
  128.  */
  129.  
  130. #ifdef UNK
  131. static long double R[4] = {
  132.  1.9757429581415468984296E-3L,
  133. -7.1990767473014147232598E-1L,
  134.  1.0777257190312272158094E1L,
  135. -3.5717684488096787370998E1L,
  136. };
  137. static long double S[4] = {
  138. /* 1.00000000000000000000E0L,*/
  139. -2.6201045551331104417768E1L,
  140.  1.9361891836232102174846E2L,
  141. -4.2861221385716144629696E2L,
  142. };
  143. static long double C1 = 6.9314575195312500000000E-1;
  144. static long double C2 = 1.4286068203094172321215E-6;
  145. #endif
  146. #ifdef IBMPC
  147. static short R[20] = {
  148. 0x6ef4,0xf922,0x7763,0x817b,0x3ff6,
  149. 0x15fd,0x1af9,0xde8f,0xb84b,0xbffe,
  150. 0x8b96,0x4f8d,0xa53c,0xac6f,0x4002,
  151. 0x8932,0xb4e3,0xe8ae,0x8ede,0xc004,
  152. };
  153. static short S[15] = {
  154. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  155. 0x7ce4,0x1fc9,0xbdc5,0xd19b,0xc003,
  156. 0x0af3,0x0d10,0x716f,0xc19e,0x4006,
  157. 0x4d7d,0x0f55,0x5d06,0xd64e,0xc007,
  158. };
  159. static short sc1[] = {0x0000,0x0000,0x0000,0xb172,0x3ffe};
  160. #define C1 (*(long double *)sc1)
  161. static short sc2[] = {0x4f1e,0xcd5e,0x8e7b,0xbfbe,0x3feb};
  162. #define C2 (*(long double *)sc2)
  163. #endif
  164. #ifdef MIEEE
  165. static long R[12] = {
  166. 0x3ff60000,0x817b7763,0xf9226ef4,
  167. 0xbffe0000,0xb84bde8f,0x1af915fd,
  168. 0x40020000,0xac6fa53c,0x4f8d8b96,
  169. 0xc0040000,0x8edee8ae,0xb4e38932,
  170. };
  171. static long S[9] = {
  172. /*0x3fff0000,0x80000000,0x00000000,*/
  173. 0xc0030000,0xd19bbdc5,0x1fc97ce4,
  174. 0x40060000,0xc19e716f,0x0d100af3,
  175. 0xc0070000,0xd64e5d06,0x0f554d7d,
  176. };
  177. static long sc1[] = {0x3ffe0000,0xb1720000,0x00000000};
  178. #define C1 (*(long double *)sc1)
  179. static long sc2[] = {0x3feb0000,0xbfbe8e7b,0xcd5e4f1e};
  180. #define C2 (*(long double *)sc2)
  181. #endif
  182.  
  183.  
  184. #define SQRTH 0.70710678118654752440
  185. extern long double MINLOGL;
  186. long double frexpl(), ldexpl(), polevll(), p1evll();
  187.  
  188.  
  189. long double logl(x)
  190. long double x;
  191. {
  192. long double y, z;
  193. int e;
  194.  
  195. /* Test for domain */
  196. if( x <= 0.0L )
  197.     {
  198.     if( x == 0.0L )
  199.         mtherr( fname, SING );
  200.     else
  201.         mtherr( fname, DOMAIN );
  202.     return( MINLOGL );
  203.     }
  204.  
  205. /* separate mantissa from exponent */
  206.  
  207. /* Note, frexp is used so that denormal numbers
  208.  * will be handled properly.
  209.  */
  210. x = frexpl( x, &e );
  211.  
  212.  
  213. /* logarithm using log(x) = z + z**3 P(z)/Q(z),
  214.  * where z = 2(x-1)/x+1)
  215.  */
  216. if( (e > 2) || (e < -2) )
  217. {
  218. if( x < SQRTH )
  219.     { /* 2( 2x-1 )/( 2x+1 ) */
  220.     e -= 1;
  221.     z = x - 0.5L;
  222.     y = 0.5L * z + 0.5L;
  223.     }    
  224. else
  225.     { /*  2 (x-1)/(x+1)   */
  226.     z = x - 0.5L;
  227.     z -= 0.5L;
  228.     y = 0.5L * x  + 0.5L;
  229.     }
  230. x = z / y;
  231. z = x*x;
  232. z = x * ( z * polevll( z, R, 3 ) / p1evll( z, S, 3 ) );
  233. z = z + e * C2;
  234. z = z + x;
  235. z = z + e * C1;
  236. return( z );
  237. }
  238.  
  239.  
  240. /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
  241.  
  242. if( x < SQRTH )
  243.     {
  244.     e -= 1;
  245.     x = ldexpl( x, 1 ) - 1.0L; /*  2x - 1  */
  246.     }    
  247. else
  248.     {
  249.     x = x - 1.0L;
  250.     }
  251. z = x*x;
  252. y = x * ( z * polevll( x, P, 6 ) / p1evll( x, Q, 6 ) );
  253. y = y + e * C2;
  254. z = y - ldexpl( z, -1 );   /*  y - 0.5 * z  */
  255. /* Note, the sum of above terms does not exceed x/4,
  256.  * so it contributes at most about 1/4 lsb to the error.
  257.  */
  258. z = z + x;
  259. z = z + e * C1; /* This sum has an error of 1/2 lsb. */
  260. return( z );
  261. }
  262.