e_log10l.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /* $OpenBSD: e_log10l.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */
  2. /*
  3. * Copyright (c) 2008 Stephen L. Moshier <[email protected]>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /* log10l.c
  18. *
  19. * Common logarithm, 128-bit long double precision
  20. *
  21. *
  22. *
  23. * SYNOPSIS:
  24. *
  25. * long double x, y, log10l();
  26. *
  27. * y = log10l( x );
  28. *
  29. *
  30. *
  31. * DESCRIPTION:
  32. *
  33. * Returns the base 10 logarithm of x.
  34. *
  35. * The argument is separated into its exponent and fractional
  36. * parts. If the exponent is between -1 and +1, the logarithm
  37. * of the fraction is approximated by
  38. *
  39. * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
  40. *
  41. * Otherwise, setting z = 2(x-1)/x+1),
  42. *
  43. * log(x) = z + z^3 P(z)/Q(z).
  44. *
  45. *
  46. *
  47. * ACCURACY:
  48. *
  49. * Relative error:
  50. * arithmetic domain # trials peak rms
  51. * IEEE 0.5, 2.0 30000 2.3e-34 4.9e-35
  52. * IEEE exp(+-10000) 30000 1.0e-34 4.1e-35
  53. *
  54. * In the tests over the interval exp(+-10000), the logarithms
  55. * of the random arguments were uniformly distributed over
  56. * [-10000, +10000].
  57. *
  58. */
  59. #include <openlibm_math.h>
  60. #include "math_private.h"
  61. /* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
  62. * 1/sqrt(2) <= x < sqrt(2)
  63. * Theoretical peak relative error = 5.3e-37,
  64. * relative peak error spread = 2.3e-14
  65. */
  66. static const long double P[13] =
  67. {
  68. 1.313572404063446165910279910527789794488E4L,
  69. 7.771154681358524243729929227226708890930E4L,
  70. 2.014652742082537582487669938141683759923E5L,
  71. 3.007007295140399532324943111654767187848E5L,
  72. 2.854829159639697837788887080758954924001E5L,
  73. 1.797628303815655343403735250238293741397E5L,
  74. 7.594356839258970405033155585486712125861E4L,
  75. 2.128857716871515081352991964243375186031E4L,
  76. 3.824952356185897735160588078446136783779E3L,
  77. 4.114517881637811823002128927449878962058E2L,
  78. 2.321125933898420063925789532045674660756E1L,
  79. 4.998469661968096229986658302195402690910E-1L,
  80. 1.538612243596254322971797716843006400388E-6L
  81. };
  82. static const long double Q[12] =
  83. {
  84. 3.940717212190338497730839731583397586124E4L,
  85. 2.626900195321832660448791748036714883242E5L,
  86. 7.777690340007566932935753241556479363645E5L,
  87. 1.347518538384329112529391120390701166528E6L,
  88. 1.514882452993549494932585972882995548426E6L,
  89. 1.158019977462989115839826904108208787040E6L,
  90. 6.132189329546557743179177159925690841200E5L,
  91. 2.248234257620569139969141618556349415120E5L,
  92. 5.605842085972455027590989944010492125825E4L,
  93. 9.147150349299596453976674231612674085381E3L,
  94. 9.104928120962988414618126155557301584078E2L,
  95. 4.839208193348159620282142911143429644326E1L
  96. /* 1.000000000000000000000000000000000000000E0L, */
  97. };
  98. /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
  99. * where z = 2(x-1)/(x+1)
  100. * 1/sqrt(2) <= x < sqrt(2)
  101. * Theoretical peak relative error = 1.1e-35,
  102. * relative peak error spread 1.1e-9
  103. */
  104. static const long double R[6] =
  105. {
  106. 1.418134209872192732479751274970992665513E5L,
  107. -8.977257995689735303686582344659576526998E4L,
  108. 2.048819892795278657810231591630928516206E4L,
  109. -2.024301798136027039250415126250455056397E3L,
  110. 8.057002716646055371965756206836056074715E1L,
  111. -8.828896441624934385266096344596648080902E-1L
  112. };
  113. static const long double S[6] =
  114. {
  115. 1.701761051846631278975701529965589676574E6L,
  116. -1.332535117259762928288745111081235577029E6L,
  117. 4.001557694070773974936904547424676279307E5L,
  118. -5.748542087379434595104154610899551484314E4L,
  119. 3.998526750980007367835804959888064681098E3L,
  120. -1.186359407982897997337150403816839480438E2L
  121. /* 1.000000000000000000000000000000000000000E0L, */
  122. };
  123. static const long double
  124. /* log10(2) */
  125. L102A = 0.3125L,
  126. L102B = -1.14700043360188047862611052755069732318101185E-2L,
  127. /* log10(e) */
  128. L10EA = 0.5L,
  129. L10EB = -6.570551809674817234887108108339491770560299E-2L,
  130. /* sqrt(2)/2 */
  131. SQRTH = 7.071067811865475244008443621048490392848359E-1L;
  132. /* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
  133. static long double
  134. neval (long double x, const long double *p, int n)
  135. {
  136. long double y;
  137. p += n;
  138. y = *p--;
  139. do
  140. {
  141. y = y * x + *p--;
  142. }
  143. while (--n > 0);
  144. return y;
  145. }
  146. /* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
  147. static long double
  148. deval (long double x, const long double *p, int n)
  149. {
  150. long double y;
  151. p += n;
  152. y = x + *p--;
  153. do
  154. {
  155. y = y * x + *p--;
  156. }
  157. while (--n > 0);
  158. return y;
  159. }
  160. long double
  161. log10l(long double x)
  162. {
  163. long double z;
  164. long double y;
  165. int e;
  166. int64_t hx, lx;
  167. /* Test for domain */
  168. GET_LDOUBLE_WORDS64 (hx, lx, x);
  169. if (((hx & 0x7fffffffffffffffLL) | lx) == 0)
  170. return (-1.0L / (x - x));
  171. if (hx < 0)
  172. return (x - x) / (x - x);
  173. if (hx >= 0x7fff000000000000LL)
  174. return (x + x);
  175. /* separate mantissa from exponent */
  176. /* Note, frexp is used so that denormal numbers
  177. * will be handled properly.
  178. */
  179. x = frexpl (x, &e);
  180. /* logarithm using log(x) = z + z**3 P(z)/Q(z),
  181. * where z = 2(x-1)/x+1)
  182. */
  183. if ((e > 2) || (e < -2))
  184. {
  185. if (x < SQRTH)
  186. { /* 2( 2x-1 )/( 2x+1 ) */
  187. e -= 1;
  188. z = x - 0.5L;
  189. y = 0.5L * z + 0.5L;
  190. }
  191. else
  192. { /* 2 (x-1)/(x+1) */
  193. z = x - 0.5L;
  194. z -= 0.5L;
  195. y = 0.5L * x + 0.5L;
  196. }
  197. x = z / y;
  198. z = x * x;
  199. y = x * (z * neval (z, R, 5) / deval (z, S, 5));
  200. goto done;
  201. }
  202. /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
  203. if (x < SQRTH)
  204. {
  205. e -= 1;
  206. x = 2.0 * x - 1.0L; /* 2x - 1 */
  207. }
  208. else
  209. {
  210. x = x - 1.0L;
  211. }
  212. z = x * x;
  213. y = x * (z * neval (x, P, 12) / deval (x, Q, 11));
  214. y = y - 0.5 * z;
  215. done:
  216. /* Multiply log of fraction by log10(e)
  217. * and base 2 exponent by log10(2).
  218. */
  219. z = y * L10EB;
  220. z += x * L10EB;
  221. z += e * L102B;
  222. z += y * L10EA;
  223. z += x * L10EA;
  224. z += e * L102A;
  225. return (z);
  226. }