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

  1. /*                            log2l.c
  2.  *
  3.  *    Base 2 logarithm, long double precision
  4.  *
  5.  *
  6.  *
  7.  * SYNOPSIS:
  8.  *
  9.  * long double x, y, log2l();
  10.  *
  11.  * y = log2l( x );
  12.  *
  13.  *
  14.  *
  15.  * DESCRIPTION:
  16.  *
  17.  * Returns the base 2 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 (natural)
  21.  * logarithm 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.8e-20     2.7e-20
  36.  *    IEEE     exp(+-10000)  70000      5.4e-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[] = {"log2l"};
  56.  
  57. /* Coefficients for ln(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. #ifdef UNK
  133. static long double R[4] = {
  134.  1.9757429581415468984296E-3L,
  135. -7.1990767473014147232598E-1L,
  136.  1.0777257190312272158094E1L,
  137. -3.5717684488096787370998E1L,
  138. };
  139. static long double S[4] = {
  140. /* 1.00000000000000000000E0L,*/
  141. -2.6201045551331104417768E1L,
  142.  1.9361891836232102174846E2L,
  143. -4.2861221385716144629696E2L,
  144. };
  145. /* log2(e) - 1 */
  146. #define LOG2EA 4.4269504088896340735992e-1L
  147. #endif
  148. #ifdef IBMPC
  149. static short R[20] = {
  150. 0x6ef4,0xf922,0x7763,0x817b,0x3ff6,
  151. 0x15fd,0x1af9,0xde8f,0xb84b,0xbffe,
  152. 0x8b96,0x4f8d,0xa53c,0xac6f,0x4002,
  153. 0x8932,0xb4e3,0xe8ae,0x8ede,0xc004,
  154. };
  155. static short S[15] = {
  156. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  157. 0x7ce4,0x1fc9,0xbdc5,0xd19b,0xc003,
  158. 0x0af3,0x0d10,0x716f,0xc19e,0x4006,
  159. 0x4d7d,0x0f55,0x5d06,0xd64e,0xc007,
  160. };
  161. static short LG2EA[] = {0xc2ef,0x705f,0xeca5,0xe2a8,0x3ffd};
  162. #define LOG2EA *(long double *)LG2EA
  163. #endif
  164.  
  165. #ifdef MIEEE
  166. static long R[12] = {
  167. 0x3ff60000,0x817b7763,0xf9226ef4,
  168. 0xbffe0000,0xb84bde8f,0x1af915fd,
  169. 0x40020000,0xac6fa53c,0x4f8d8b96,
  170. 0xc0040000,0x8edee8ae,0xb4e38932,
  171. };
  172. static long S[9] = {
  173. /*0x3fff0000,0x80000000,0x00000000,*/
  174. 0xc0030000,0xd19bbdc5,0x1fc97ce4,
  175. 0x40060000,0xc19e716f,0x0d100af3,
  176. 0xc0070000,0xd64e5d06,0x0f554d7d,
  177. };
  178. static long LG2EA[] = {0x3ffd0000,0xe2a8eca5,0x705fc2ef};
  179. #define LOG2EA *(long double *)LG2EA
  180. #endif
  181.  
  182.  
  183. #define SQRTH 0.70710678118654752440
  184. extern long double MINLOGL;
  185. long double frexpl(), ldexpl(), polevll(), p1evll();
  186.  
  187.  
  188. long double log2l(x)
  189. long double x;
  190. {
  191. VOLATILE long double z;
  192. long double y;
  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( -16384.0L );
  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. y = x * ( z * polevll( z, R, 3 ) / p1evll( z, S, 3 ) );
  233. goto done;
  234. }
  235.  
  236.  
  237. /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
  238.  
  239. if( x < SQRTH )
  240.     {
  241.     e -= 1;
  242.     x = ldexpl( x, 1 ) - 1.0L; /*  2x - 1  */
  243.     }    
  244. else
  245.     {
  246.     x = x - 1.0L;
  247.     }
  248. z = x*x;
  249. y = x * ( z * polevll( x, P, 6 ) / p1evll( x, Q, 7 ) );
  250. y = y - ldexpl( z, -1 );   /* -0.5x^2 + ... */
  251.  
  252. done:
  253.  
  254. /* Multiply log of fraction by log2(e)
  255.  * and base 2 exponent by 1
  256.  *
  257.  * ***CAUTION***
  258.  *
  259.  * This sequence of operations is critical and it may
  260.  * be horribly defeated by some compiler optimizers.
  261.  */
  262. z = y * LOG2EA;
  263. z += x * LOG2EA;
  264. z += y;
  265. z += x;
  266. z += e;
  267. return( z );
  268. }
  269.  
  270.