log10.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /* log10.c
  2. *
  3. * Common logarithm
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * double x, y, log10();
  10. *
  11. * y = log10( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns logarithm to the base 10 of x.
  18. *
  19. * The argument is separated into its exponent and fractional
  20. * parts. The logarithm of the fraction is approximated by
  21. *
  22. * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
  23. *
  24. *
  25. *
  26. * ACCURACY:
  27. *
  28. * Relative error:
  29. * arithmetic domain # trials peak rms
  30. * IEEE 0.5, 2.0 30000 1.5e-16 5.0e-17
  31. * IEEE 0, MAXNUM 30000 1.4e-16 4.8e-17
  32. * DEC 1, MAXNUM 50000 2.5e-17 6.0e-18
  33. *
  34. * In the tests over the interval [1, MAXNUM], the logarithms
  35. * of the random arguments were uniformly distributed over
  36. * [0, MAXLOG].
  37. *
  38. * ERROR MESSAGES:
  39. *
  40. * log10 singularity: x = 0; returns -INFINITY
  41. * log10 domain: x < 0; returns NAN
  42. */
  43. /*
  44. Cephes Math Library Release 2.8: June, 2000
  45. Copyright 1984, 1995, 2000 by Stephen L. Moshier
  46. */
  47. #include "mconf.h"
  48. static char fname[] = {"log10"};
  49. /* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
  50. * 1/sqrt(2) <= x < sqrt(2)
  51. */
  52. #ifdef UNK
  53. static double P[] = {4.58482948458143443514E-5, 4.98531067254050724270E-1,
  54. 6.56312093769992875930E0, 2.97877425097986925891E1,
  55. 6.06127134467767258030E1, 5.67349287391754285487E1,
  56. 1.98892446572874072159E1};
  57. static double Q[] = {
  58. /* 1.00000000000000000000E0, */
  59. 1.50314182634250003249E1, 8.27410449222435217021E1,
  60. 2.20664384982121929218E2, 3.07254189979530058263E2,
  61. 2.14955586696422947765E2, 5.96677339718622216300E1};
  62. #endif
  63. #ifdef DEC
  64. static unsigned short P[] = {
  65. 0034500, 0046473, 0051374, 0135174, 0037777, 0037566, 0145712,
  66. 0150321, 0040722, 0002426, 0031543, 0123107, 0041356, 0046513,
  67. 0170752, 0004346, 0041562, 0071553, 0023536, 0163343, 0041542,
  68. 0170221, 0024316, 0114216, 0041237, 0016454, 0046611, 0104602};
  69. static unsigned short Q[] = {
  70. /*0040200,0000000,0000000,0000000,*/
  71. 0041160, 0100260, 0067736, 0102424, 0041645, 0075552, 0036563, 0147072,
  72. 0042134, 0125025, 0021132, 0025320, 0042231, 0120211, 0046030, 0103271,
  73. 0042126, 0172241, 0052151, 0120426, 0041556, 0125702, 0072116, 0047103};
  74. #endif
  75. #ifdef IBMPC
  76. static unsigned short P[] = {0x974f, 0x6a5f, 0x09a7, 0x3f08, 0x5a1a, 0xd979,
  77. 0xe7ee, 0x3fdf, 0x74c9, 0xc66c, 0x40a2, 0x401a,
  78. 0x411d, 0x7e3d, 0xc9a9, 0x403d, 0xdcdc, 0x64eb,
  79. 0x4e6d, 0x404e, 0xd312, 0x2519, 0x5e12, 0x404c,
  80. 0x3130, 0x89b1, 0xe3a5, 0x4033};
  81. static unsigned short Q[] = {
  82. /*0x0000,0x0000,0x0000,0x3ff0,*/
  83. 0xd0a2, 0x0dfb, 0x1016, 0x402e, 0x79c7, 0x47ae, 0xaf6d, 0x4054,
  84. 0x455a, 0xa44b, 0x9542, 0x406b, 0x10d7, 0x2983, 0x3411, 0x4073,
  85. 0x3423, 0x2a8d, 0xde94, 0x406a, 0xc9c8, 0x4e89, 0xd578, 0x404d};
  86. #endif
  87. #ifdef MIEEE
  88. static unsigned short P[] = {0x3f08, 0x09a7, 0x6a5f, 0x974f, 0x3fdf, 0xe7ee,
  89. 0xd979, 0x5a1a, 0x401a, 0x40a2, 0xc66c, 0x74c9,
  90. 0x403d, 0xc9a9, 0x7e3d, 0x411d, 0x404e, 0x4e6d,
  91. 0x64eb, 0xdcdc, 0x404c, 0x5e12, 0x2519, 0xd312,
  92. 0x4033, 0xe3a5, 0x89b1, 0x3130};
  93. static unsigned short Q[] = {0x402e, 0x1016, 0x0dfb, 0xd0a2, 0x4054, 0xaf6d,
  94. 0x47ae, 0x79c7, 0x406b, 0x9542, 0xa44b, 0x455a,
  95. 0x4073, 0x3411, 0x2983, 0x10d7, 0x406a, 0xde94,
  96. 0x2a8d, 0x3423, 0x404d, 0xd578, 0x4e89, 0xc9c8};
  97. #endif
  98. #define SQRTH 0.70710678118654752440
  99. #define L102A 3.0078125E-1
  100. #define L102B 2.48745663981195213739E-4
  101. #define L10EA 4.3359375E-1
  102. #define L10EB 7.00731903251827651129E-4
  103. #ifdef ANSIPROT
  104. extern double frexp(double, int *);
  105. extern double ldexp(double, int);
  106. extern double polevl(double, void *, int);
  107. extern double p1evl(double, void *, int);
  108. extern int isnan(double);
  109. extern int isfinite(double);
  110. #else
  111. double frexp(), ldexp(), polevl(), p1evl();
  112. int isnan(), isfinite();
  113. #endif
  114. extern double LOGE2, SQRT2, INFINITY, NAN;
  115. double log10(x) double x;
  116. {
  117. VOLATILE double z;
  118. double y;
  119. #ifdef DEC
  120. short *q;
  121. #endif
  122. int e;
  123. #ifdef NANS
  124. if (isnan(x))
  125. return (x);
  126. #endif
  127. #ifdef INFINITIES
  128. if (x == INFINITY)
  129. return (x);
  130. #endif
  131. /* Test for domain */
  132. if (x <= 0.0) {
  133. if (x == 0.0) {
  134. mtherr(fname, SING);
  135. return (-INFINITY);
  136. } else {
  137. mtherr(fname, DOMAIN);
  138. return (NAN);
  139. }
  140. }
  141. /* separate mantissa from exponent */
  142. #ifdef DEC
  143. q = (short *)&x;
  144. e = *q; /* short containing exponent */
  145. e = ((e >> 7) & 0377) - 0200; /* the exponent */
  146. *q &= 0177; /* strip exponent from x */
  147. *q |= 040000; /* x now between 0.5 and 1 */
  148. #endif
  149. #ifdef IBMPC
  150. x = frexp(x, &e);
  151. /*
  152. q = (short *)&x;
  153. q += 3;
  154. e = *q;
  155. e = ((e >> 4) & 0x0fff) - 0x3fe;
  156. *q &= 0x0f;
  157. *q |= 0x3fe0;
  158. */
  159. #endif
  160. /* Equivalent C language standard library function: */
  161. #ifdef UNK
  162. x = frexp(x, &e);
  163. #endif
  164. #ifdef MIEEE
  165. x = frexp(x, &e);
  166. #endif
  167. /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
  168. if (x < SQRTH) {
  169. e -= 1;
  170. x = ldexp(x, 1) - 1.0; /* 2x - 1 */
  171. } else {
  172. x = x - 1.0;
  173. }
  174. /* rational form */
  175. z = x * x;
  176. y = x * (z * polevl(x, P, 6) / p1evl(x, Q, 6));
  177. y = y - ldexp(z, -1); /* y - 0.5 * x**2 */
  178. /* multiply log of fraction by log10(e)
  179. * and base 2 exponent by log10(2)
  180. */
  181. z = (x + y) * L10EB; /* accumulate terms in order of size */
  182. z += y * L10EA;
  183. z += x * L10EA;
  184. z += e * L102B;
  185. z += e * L102A;
  186. return (z);
  187. }