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

  1. /*                            log10l.c
  2.  *
  3.  *    Common logarithm, long double precision
  4.  *
  5.  *
  6.  *
  7.  * SYNOPSIS:
  8.  *
  9.  * long double x, y, log10l();
  10.  *
  11.  * y = log10l( x );
  12.  *
  13.  *
  14.  *
  15.  * DESCRIPTION:
  16.  *
  17.  * Returns the base 10 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     30000      9.0e-20     2.6e-20
  36.  *    IEEE     exp(+-10000)  30000      6.0e-20     2.3e-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:  January, 1991
  50. Copyright 1984, 1991 by Stephen L. Moshier
  51. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  52. */
  53.  
  54. #include "mconf.h"
  55. static char fname[] = {"log10l"};
  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 = 6.2e-22
  60.  */
  61. #ifdef UNK
  62. static long double P[] = {
  63.  4.9962495940332550844739E-1L,
  64.  1.0767376367209449010438E1L,
  65.  7.7671073698359539859595E1L,
  66.  2.5620629828144409632571E2L,
  67.  4.2401812743503691187826E2L,
  68.  3.4258224542413922935104E2L,
  69.  1.0747524399916215149070E2L,
  70. };
  71. static long double Q[] = {
  72. /* 1.0000000000000000000000E0,*/
  73.  2.3479774160285863271658E1L,
  74.  1.9444210022760132894510E2L,
  75.  7.7952888181207260646090E2L,
  76.  1.6911722418503949084863E3L,
  77.  2.0307734695595183428202E3L,
  78.  1.2695660352705325274404E3L,
  79.  3.2242573199748645407652E2L,
  80. };
  81. #endif
  82.  
  83. #ifdef IBMPC
  84. static short P[] = {
  85. 0xfe72,0xce22,0xd7b9,0xffce,0x3ffd,
  86. 0xb778,0x0e34,0x2c71,0xac47,0x4002,
  87. 0xea8b,0xc751,0x96f8,0x9b57,0x4005,
  88. 0xfeaf,0x6a02,0x67fb,0x801a,0x4007,
  89. 0x6b5a,0xf252,0x51ff,0xd402,0x4007,
  90. 0x39ce,0x9f76,0x8704,0xab4a,0x4007,
  91. 0x1b39,0x740b,0x532e,0xd6f3,0x4005,
  92. };
  93. static short Q[] = {
  94. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  95. 0x2f3a,0xbf26,0x93d5,0xbbd6,0x4003,
  96. 0x13c8,0x031a,0x2d7b,0xc271,0x4006,
  97. 0x449d,0x1993,0xd933,0xc2e1,0x4008,
  98. 0x5b65,0x574e,0x8301,0xd365,0x4009,
  99. 0xa65d,0x3bd2,0xc043,0xfdd8,0x4009,
  100. 0x3b21,0xffea,0x1cf5,0x9eb2,0x4009,
  101. 0x545c,0xd708,0x7e62,0xa136,0x4007,
  102. };
  103. #endif
  104.  
  105. #ifdef MIEEE
  106. static long P[] = {
  107. 0x3ffd0000,0xffced7b9,0xce22fe72,
  108. 0x40020000,0xac472c71,0x0e34b778,
  109. 0x40050000,0x9b5796f8,0xc751ea8b,
  110. 0x40070000,0x801a67fb,0x6a02feaf,
  111. 0x40070000,0xd40251ff,0xf2526b5a,
  112. 0x40070000,0xab4a8704,0x9f7639ce,
  113. 0x40050000,0xd6f3532e,0x740b1b39,
  114. };
  115. static long Q[] = {
  116. /*0x3fff0000,0x80000000,0x00000000,*/
  117. 0x40030000,0xbbd693d5,0xbf262f3a,
  118. 0x40060000,0xc2712d7b,0x031a13c8,
  119. 0x40080000,0xc2e1d933,0x1993449d,
  120. 0x40090000,0xd3658301,0x574e5b65,
  121. 0x40090000,0xfdd8c043,0x3bd2a65d,
  122. 0x40090000,0x9eb21cf5,0xffea3b21,
  123. 0x40070000,0xa1367e62,0xd708545c,
  124. };
  125. #endif
  126.  
  127. /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
  128.  * where z = 2(x-1)/(x+1)
  129.  * 1/sqrt(2) <= x < sqrt(2)
  130.  * Theoretical peak relative error = 6.16e-22
  131.  */
  132.  
  133. #ifdef UNK
  134. static long double R[4] = {
  135.  1.9757429581415468984296E-3L,
  136. -7.1990767473014147232598E-1L,
  137.  1.0777257190312272158094E1L,
  138. -3.5717684488096787370998E1L,
  139. };
  140. static long double S[4] = {
  141. /* 1.00000000000000000000E0L,*/
  142. -2.6201045551331104417768E1L,
  143.  1.9361891836232102174846E2L,
  144. -4.2861221385716144629696E2L,
  145. };
  146. /* log10(2) */
  147. #define L102A 0.3125L
  148. #define L102B -1.1470004336018804786261e-2L
  149. /* log10(e) */
  150. #define L10EA 0.5L
  151. #define L10EB -6.5705518096748172348871e-2L
  152. #endif
  153. #ifdef IBMPC
  154. static short R[20] = {
  155. 0x6ef4,0xf922,0x7763,0x817b,0x3ff6,
  156. 0x15fd,0x1af9,0xde8f,0xb84b,0xbffe,
  157. 0x8b96,0x4f8d,0xa53c,0xac6f,0x4002,
  158. 0x8932,0xb4e3,0xe8ae,0x8ede,0xc004,
  159. };
  160. static short S[15] = {
  161. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  162. 0x7ce4,0x1fc9,0xbdc5,0xd19b,0xc003,
  163. 0x0af3,0x0d10,0x716f,0xc19e,0x4006,
  164. 0x4d7d,0x0f55,0x5d06,0xd64e,0xc007,
  165. };
  166. static short LG102A[] = {0x0000,0x0000,0x0000,0xa000,0x3ffd};
  167. #define L102A *(long double *)LG102A
  168. static short LG102B[] = {0x0cee,0x8601,0xaf60,0xbbec,0xbff8};
  169. #define L102B *(long double *)LG102B
  170. static short LG10EA[] = {0x0000,0x0000,0x0000,0x8000,0x3ffe};
  171. #define L10EA *(long double *)LG10EA
  172. static short LG10EB[] = {0x39ab,0x235e,0x9d5b,0x8690,0xbffb};
  173. #define L10EB *(long double *)LG10EB
  174. #endif
  175.  
  176. #ifdef MIEEE
  177. static long R[12] = {
  178. 0x3ff60000,0x817b7763,0xf9226ef4,
  179. 0xbffe0000,0xb84bde8f,0x1af915fd,
  180. 0x40020000,0xac6fa53c,0x4f8d8b96,
  181. 0xc0040000,0x8edee8ae,0xb4e38932,
  182. };
  183. static long S[9] = {
  184. /*0x3fff0000,0x80000000,0x00000000,*/
  185. 0xc0030000,0xd19bbdc5,0x1fc97ce4,
  186. 0x40060000,0xc19e716f,0x0d100af3,
  187. 0xc0070000,0xd64e5d06,0x0f554d7d,
  188. };
  189. static long LG102A[] = {0x3ffd0000,0xa0000000,0x00000000};
  190. #define L102A *(long double *)LG102A
  191. static long LG102B[] = {0xbff80000,0xbbecaf60,0x86010cee};
  192. #define L102B *(long double *)LG102B
  193. static long LG10EA[] = {0x3ffe8000,0x00000000,0x00000000};
  194. #define L10EA *(long double *)LG10EA
  195. static long LG10EB[] = {0xbffb0000,0x86909d5b,0x235e39ab};
  196. #define L10EB *(long double *)LG10EB
  197. #endif
  198.  
  199.  
  200. #define SQRTH 0.70710678118654752440
  201. long double frexpl(), ldexpl(), polevll(), p1evll();
  202.  
  203.  
  204. long double log10l(x)
  205. long double x;
  206. {
  207. long double y;
  208. VOLATILE long double z;
  209. int e;
  210.  
  211. /* Test for domain */
  212. if( x <= 0.0L )
  213.     {
  214.     if( x == 0.0L )
  215.         mtherr( fname, SING );
  216.     else
  217.         mtherr( fname, DOMAIN );
  218.     return( -4.9314733889673399399914e3L );
  219.     }
  220.  
  221. /* separate mantissa from exponent */
  222.  
  223. /* Note, frexp is used so that denormal numbers
  224.  * will be handled properly.
  225.  */
  226. x = frexpl( x, &e );
  227.  
  228.  
  229. /* logarithm using log(x) = z + z**3 P(z)/Q(z),
  230.  * where z = 2(x-1)/x+1)
  231.  */
  232. if( (e > 2) || (e < -2) )
  233. {
  234. if( x < SQRTH )
  235.     { /* 2( 2x-1 )/( 2x+1 ) */
  236.     e -= 1;
  237.     z = x - 0.5L;
  238.     y = 0.5L * z + 0.5L;
  239.     }    
  240. else
  241.     { /*  2 (x-1)/(x+1)   */
  242.     z = x - 0.5L;
  243.     z -= 0.5L;
  244.     y = 0.5L * x  + 0.5L;
  245.     }
  246. x = z / y;
  247. z = x*x;
  248. y = x * ( z * polevll( z, R, 3 ) / p1evll( z, S, 3 ) );
  249. goto done;
  250. }
  251.  
  252.  
  253. /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
  254.  
  255. if( x < SQRTH )
  256.     {
  257.     e -= 1;
  258.     x = ldexpl( x, 1 ) - 1.0L; /*  2x - 1  */
  259.     }    
  260. else
  261.     {
  262.     x = x - 1.0L;
  263.     }
  264. z = x*x;
  265. y = x * ( z * polevll( x, P, 6 ) / p1evll( x, Q, 7 ) );
  266. y = y - ldexpl( z, -1 );   /* -0.5x^2 + ... */
  267.  
  268. done:
  269.  
  270. /* Multiply log of fraction by log10(e)
  271.  * and base 2 exponent by log10(2).
  272.  *
  273.  * ***CAUTION***
  274.  *
  275.  * This sequence of operations is critical and it may
  276.  * be horribly defeated by some compiler optimizers.
  277.  */
  278. z = y * (L10EB);
  279. z += x * (L10EB);
  280. z += e * (L102B);
  281. z += y * (L10EA);
  282. z += x * (L10EA);
  283. z += e * (L102A);
  284.  
  285. return( z );
  286. }
  287.