e_log2l.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /* $OpenBSD: e_log2l.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. /* log2l.c
  18. * Base 2 logarithm, 128-bit long double precision
  19. *
  20. *
  21. *
  22. * SYNOPSIS:
  23. *
  24. * long double x, y, log2l();
  25. *
  26. * y = log2l( x );
  27. *
  28. *
  29. *
  30. * DESCRIPTION:
  31. *
  32. * Returns the base 2 logarithm of x.
  33. *
  34. * The argument is separated into its exponent and fractional
  35. * parts. If the exponent is between -1 and +1, the (natural)
  36. * logarithm of the fraction is approximated by
  37. *
  38. * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
  39. *
  40. * Otherwise, setting z = 2(x-1)/x+1),
  41. *
  42. * log(x) = z + z^3 P(z)/Q(z).
  43. *
  44. *
  45. *
  46. * ACCURACY:
  47. *
  48. * Relative error:
  49. * arithmetic domain # trials peak rms
  50. * IEEE 0.5, 2.0 100,000 2.6e-34 4.9e-35
  51. * IEEE exp(+-10000) 100,000 9.6e-35 4.0e-35
  52. *
  53. * In the tests over the interval exp(+-10000), the logarithms
  54. * of the random arguments were uniformly distributed over
  55. * [-10000, +10000].
  56. *
  57. */
  58. #include <openlibm_math.h>
  59. #include "math_private.h"
  60. /* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
  61. * 1/sqrt(2) <= x < sqrt(2)
  62. * Theoretical peak relative error = 5.3e-37,
  63. * relative peak error spread = 2.3e-14
  64. */
  65. static const long double P[13] =
  66. {
  67. 1.313572404063446165910279910527789794488E4L,
  68. 7.771154681358524243729929227226708890930E4L,
  69. 2.014652742082537582487669938141683759923E5L,
  70. 3.007007295140399532324943111654767187848E5L,
  71. 2.854829159639697837788887080758954924001E5L,
  72. 1.797628303815655343403735250238293741397E5L,
  73. 7.594356839258970405033155585486712125861E4L,
  74. 2.128857716871515081352991964243375186031E4L,
  75. 3.824952356185897735160588078446136783779E3L,
  76. 4.114517881637811823002128927449878962058E2L,
  77. 2.321125933898420063925789532045674660756E1L,
  78. 4.998469661968096229986658302195402690910E-1L,
  79. 1.538612243596254322971797716843006400388E-6L
  80. };
  81. static const long double Q[12] =
  82. {
  83. 3.940717212190338497730839731583397586124E4L,
  84. 2.626900195321832660448791748036714883242E5L,
  85. 7.777690340007566932935753241556479363645E5L,
  86. 1.347518538384329112529391120390701166528E6L,
  87. 1.514882452993549494932585972882995548426E6L,
  88. 1.158019977462989115839826904108208787040E6L,
  89. 6.132189329546557743179177159925690841200E5L,
  90. 2.248234257620569139969141618556349415120E5L,
  91. 5.605842085972455027590989944010492125825E4L,
  92. 9.147150349299596453976674231612674085381E3L,
  93. 9.104928120962988414618126155557301584078E2L,
  94. 4.839208193348159620282142911143429644326E1L
  95. /* 1.000000000000000000000000000000000000000E0L, */
  96. };
  97. /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
  98. * where z = 2(x-1)/(x+1)
  99. * 1/sqrt(2) <= x < sqrt(2)
  100. * Theoretical peak relative error = 1.1e-35,
  101. * relative peak error spread 1.1e-9
  102. */
  103. static const long double R[6] =
  104. {
  105. 1.418134209872192732479751274970992665513E5L,
  106. -8.977257995689735303686582344659576526998E4L,
  107. 2.048819892795278657810231591630928516206E4L,
  108. -2.024301798136027039250415126250455056397E3L,
  109. 8.057002716646055371965756206836056074715E1L,
  110. -8.828896441624934385266096344596648080902E-1L
  111. };
  112. static const long double S[6] =
  113. {
  114. 1.701761051846631278975701529965589676574E6L,
  115. -1.332535117259762928288745111081235577029E6L,
  116. 4.001557694070773974936904547424676279307E5L,
  117. -5.748542087379434595104154610899551484314E4L,
  118. 3.998526750980007367835804959888064681098E3L,
  119. -1.186359407982897997337150403816839480438E2L
  120. /* 1.000000000000000000000000000000000000000E0L, */
  121. };
  122. static const long double
  123. /* log2(e) - 1 */
  124. LOG2EA = 4.4269504088896340735992468100189213742664595E-1L,
  125. /* sqrt(2)/2 */
  126. SQRTH = 7.071067811865475244008443621048490392848359E-1L;
  127. /* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
  128. static long double
  129. neval (long double x, const long double *p, int n)
  130. {
  131. long double y;
  132. p += n;
  133. y = *p--;
  134. do
  135. {
  136. y = y * x + *p--;
  137. }
  138. while (--n > 0);
  139. return y;
  140. }
  141. /* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
  142. static long double
  143. deval (long double x, const long double *p, int n)
  144. {
  145. long double y;
  146. p += n;
  147. y = x + *p--;
  148. do
  149. {
  150. y = y * x + *p--;
  151. }
  152. while (--n > 0);
  153. return y;
  154. }
  155. long double
  156. log2l(long double x)
  157. {
  158. long double z;
  159. long double y;
  160. int e;
  161. int64_t hx, lx;
  162. /* Test for domain */
  163. GET_LDOUBLE_WORDS64 (hx, lx, x);
  164. if (((hx & 0x7fffffffffffffffLL) | lx) == 0)
  165. return (-1.0L / (x - x));
  166. if (hx < 0)
  167. return (x - x) / (x - x);
  168. if (hx >= 0x7fff000000000000LL)
  169. return (x + x);
  170. /* separate mantissa from exponent */
  171. /* Note, frexp is used so that denormal numbers
  172. * will be handled properly.
  173. */
  174. x = frexpl (x, &e);
  175. /* logarithm using log(x) = z + z**3 P(z)/Q(z),
  176. * where z = 2(x-1)/x+1)
  177. */
  178. if ((e > 2) || (e < -2))
  179. {
  180. if (x < SQRTH)
  181. { /* 2( 2x-1 )/( 2x+1 ) */
  182. e -= 1;
  183. z = x - 0.5L;
  184. y = 0.5L * z + 0.5L;
  185. }
  186. else
  187. { /* 2 (x-1)/(x+1) */
  188. z = x - 0.5L;
  189. z -= 0.5L;
  190. y = 0.5L * x + 0.5L;
  191. }
  192. x = z / y;
  193. z = x * x;
  194. y = x * (z * neval (z, R, 5) / deval (z, S, 5));
  195. goto done;
  196. }
  197. /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
  198. if (x < SQRTH)
  199. {
  200. e -= 1;
  201. x = 2.0 * x - 1.0L; /* 2x - 1 */
  202. }
  203. else
  204. {
  205. x = x - 1.0L;
  206. }
  207. z = x * x;
  208. y = x * (z * neval (x, P, 12) / deval (x, Q, 11));
  209. y = y - 0.5 * z;
  210. done:
  211. /* Multiply log of fraction by log2(e)
  212. * and base 2 exponent by 1
  213. */
  214. z = y * LOG2EA;
  215. z += x * LOG2EA;
  216. z += y;
  217. z += x;
  218. z += e;
  219. return (z);
  220. }