log2.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /* log2.c
  2. *
  3. * Base 2 logarithm
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * double x, y, log2();
  10. *
  11. * y = log2( 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 base e
  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 2.0e-16 5.5e-17
  36. * IEEE exp(+-700) 40000 1.3e-16 4.6e-17
  37. *
  38. * In the tests over the interval [exp(+-700)], the logarithms
  39. * of the random arguments were uniformly distributed.
  40. *
  41. * ERROR MESSAGES:
  42. *
  43. * log2 singularity: x = 0; returns -INFINITY
  44. * log2 domain: x < 0; returns NAN
  45. */
  46. /*
  47. Cephes Math Library Release 2.8: June, 2000
  48. Copyright 1984, 1995, 2000 by Stephen L. Moshier
  49. */
  50. #include "mconf.h"
  51. static char fname[] = {"log2"};
  52. /* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
  53. * 1/sqrt(2) <= x < sqrt(2)
  54. */
  55. #ifdef UNK
  56. static double P[] = {
  57. 1.01875663804580931796E-4, 4.97494994976747001425E-1,
  58. 4.70579119878881725854E0, 1.44989225341610930846E1,
  59. 1.79368678507819816313E1, 7.70838733755885391666E0,
  60. };
  61. static double Q[] = {
  62. /* 1.00000000000000000000E0, */
  63. 1.12873587189167450590E1, 4.52279145837532221105E1,
  64. 8.29875266912776603211E1, 7.11544750618563894466E1,
  65. 2.31251620126765340583E1,
  66. };
  67. #define LOG2EA 0.44269504088896340735992
  68. #endif
  69. #ifdef DEC
  70. static unsigned short P[] = {
  71. 0037777, 0127270, 0162547, 0057274, 0041001, 0054665, 0164317, 0005341,
  72. 0041451, 0034104, 0031640, 0105773, 0041677, 0011276, 0123617, 0160135,
  73. 0041701, 0126603, 0053215, 0117250, 0041420, 0115777, 0135206, 0030232,
  74. };
  75. static unsigned short Q[] = {
  76. /*0040200,0000000,0000000,0000000,*/
  77. 0041220, 0144332, 0045272, 0174241, 0041742, 0164566, 0035720, 0130431,
  78. 0042246, 0126327, 0166065, 0116357, 0042372, 0033420, 0157525, 0124560,
  79. 0042271, 0167002, 0066537, 0172303, 0041730, 0164777, 0113711, 0044407,
  80. };
  81. static unsigned short L[5] = {0037742, 0124354, 0122560, 0057703};
  82. #define LOG2EA (*(double *)(&L[0]))
  83. #endif
  84. #ifdef IBMPC
  85. static unsigned short P[] = {
  86. 0x1bb0, 0x93c3, 0xb4c2, 0x3f1a, 0x52f2, 0x3f56, 0xd6f5, 0x3fdf,
  87. 0x6911, 0xed92, 0xd2ba, 0x4012, 0xeb2e, 0xc63e, 0xff72, 0x402c,
  88. 0xc84d, 0x924b, 0xefd6, 0x4031, 0xdcf8, 0x7d7e, 0xd563, 0x401e,
  89. };
  90. static unsigned short Q[] = {
  91. /*0x0000,0x0000,0x0000,0x3ff0,*/
  92. 0xef8e, 0xae97, 0x9320, 0x4026, 0xc033, 0x4e19, 0x9d2c,
  93. 0x4046, 0xbdbd, 0xa326, 0xbf33, 0x4054, 0xae21, 0xeb5e,
  94. 0xc9e2, 0x4051, 0x25b2, 0x9e1f, 0x200a, 0x4037,
  95. };
  96. static unsigned short L[5] = {0x0bf8, 0x94ae, 0x551d, 0x3fdc};
  97. #define LOG2EA (*(double *)(&L[0]))
  98. #endif
  99. #ifdef MIEEE
  100. static unsigned short P[] = {
  101. 0x3f1a, 0xb4c2, 0x93c3, 0x1bb0, 0x3fdf, 0xd6f5, 0x3f56, 0x52f2,
  102. 0x4012, 0xd2ba, 0xed92, 0x6911, 0x402c, 0xff72, 0xc63e, 0xeb2e,
  103. 0x4031, 0xefd6, 0x924b, 0xc84d, 0x401e, 0xd563, 0x7d7e, 0xdcf8,
  104. };
  105. static unsigned short Q[] = {
  106. /*0x3ff0,0x0000,0x0000,0x0000,*/
  107. 0x4026, 0x9320, 0xae97, 0xef8e, 0x4046, 0x9d2c, 0x4e19,
  108. 0xc033, 0x4054, 0xbf33, 0xa326, 0xbdbd, 0x4051, 0xc9e2,
  109. 0xeb5e, 0xae21, 0x4037, 0x200a, 0x9e1f, 0x25b2,
  110. };
  111. static unsigned short L[5] = {0x3fdc, 0x551d, 0x94ae, 0x0bf8};
  112. #define LOG2EA (*(double *)(&L[0]))
  113. #endif
  114. /* Coefficients for log(x) = z + z**3 P(z)/Q(z),
  115. * where z = 2(x-1)/(x+1)
  116. * 1/sqrt(2) <= x < sqrt(2)
  117. */
  118. #ifdef UNK
  119. static double R[3] = {
  120. -7.89580278884799154124E-1,
  121. 1.63866645699558079767E1,
  122. -6.41409952958715622951E1,
  123. };
  124. static double S[3] = {
  125. /* 1.00000000000000000000E0,*/
  126. -3.56722798256324312549E1,
  127. 3.12093766372244180303E2,
  128. -7.69691943550460008604E2,
  129. };
  130. /* log2(e) - 1 */
  131. #define LOG2EA 0.44269504088896340735992
  132. #endif
  133. #ifdef DEC
  134. static unsigned short R[12] = {
  135. 0140112, 0020756, 0161540, 0072035, 0041203, 0013743,
  136. 0114023, 0155527, 0141600, 0044060, 0104421, 0050400,
  137. };
  138. static unsigned short S[12] = {
  139. /*0040200,0000000,0000000,0000000,*/
  140. 0141416, 0130152, 0017543, 0064122, 0042234, 0006000,
  141. 0104527, 0020155, 0142500, 0066110, 0146631, 0174731,
  142. };
  143. /* log2(e) - 1 */
  144. #define LOG2EA 0.44269504088896340735992L
  145. #endif
  146. #ifdef IBMPC
  147. static unsigned short R[12] = {
  148. 0x0e84, 0xdc6c, 0x443d, 0xbfe9, 0x7b6b, 0x7302,
  149. 0x62fc, 0x4030, 0x2a20, 0x1122, 0x0906, 0xc050,
  150. };
  151. static unsigned short S[12] = {
  152. /*0x0000,0x0000,0x0000,0x3ff0,*/
  153. 0x6d0a, 0x43ec, 0xd60d, 0xc041, 0xe40e, 0x112a,
  154. 0x8180, 0x4073, 0x3f3b, 0x19b3, 0x0d89, 0xc088,
  155. };
  156. #endif
  157. #ifdef MIEEE
  158. static unsigned short R[12] = {
  159. 0xbfe9, 0x443d, 0xdc6c, 0x0e84, 0x4030, 0x62fc,
  160. 0x7302, 0x7b6b, 0xc050, 0x0906, 0x1122, 0x2a20,
  161. };
  162. static unsigned short S[12] = {
  163. /*0x3ff0,0x0000,0x0000,0x0000,*/
  164. 0xc041, 0xd60d, 0x43ec, 0x6d0a, 0x4073, 0x8180,
  165. 0x112a, 0xe40e, 0xc088, 0x0d89, 0x19b3, 0x3f3b,
  166. };
  167. #endif
  168. #ifdef ANSIPROT
  169. extern double frexp(double, int *);
  170. extern double ldexp(double, int);
  171. extern double polevl(double, void *, int);
  172. extern double p1evl(double, void *, int);
  173. extern int isnan(double);
  174. extern int isfinite(double);
  175. #else
  176. double frexp(), ldexp(), polevl(), p1evl();
  177. int isnan(), isfinite();
  178. #endif
  179. #define SQRTH 0.70710678118654752440
  180. extern double LOGE2, INFINITY, NAN;
  181. double log2(x) double x;
  182. {
  183. int e;
  184. double y;
  185. VOLATILE double z;
  186. #ifdef DEC
  187. short *q;
  188. #endif
  189. #ifdef NANS
  190. if (isnan(x))
  191. return (x);
  192. #endif
  193. #ifdef INFINITIES
  194. if (x == INFINITY)
  195. return (x);
  196. #endif
  197. /* Test for domain */
  198. if (x <= 0.0) {
  199. if (x == 0.0) {
  200. mtherr(fname, SING);
  201. return (-INFINITY);
  202. } else {
  203. mtherr(fname, DOMAIN);
  204. return (NAN);
  205. }
  206. }
  207. /* separate mantissa from exponent */
  208. #ifdef DEC
  209. q = (short *)&x;
  210. e = *q; /* short containing exponent */
  211. e = ((e >> 7) & 0377) - 0200; /* the exponent */
  212. *q &= 0177; /* strip exponent from x */
  213. *q |= 040000; /* x now between 0.5 and 1 */
  214. #endif
  215. /* Note, frexp is used so that denormal numbers
  216. * will be handled properly.
  217. */
  218. #ifdef IBMPC
  219. x = frexp(x, &e);
  220. /*
  221. q = (short *)&x;
  222. q += 3;
  223. e = *q;
  224. e = ((e >> 4) & 0x0fff) - 0x3fe;
  225. *q &= 0x0f;
  226. *q |= 0x3fe0;
  227. */
  228. #endif
  229. /* Equivalent C language standard library function: */
  230. #ifdef UNK
  231. x = frexp(x, &e);
  232. #endif
  233. #ifdef MIEEE
  234. x = frexp(x, &e);
  235. #endif
  236. /* logarithm using log(x) = z + z**3 P(z)/Q(z),
  237. * where z = 2(x-1)/x+1)
  238. */
  239. if ((e > 2) || (e < -2)) {
  240. if (x < SQRTH) { /* 2( 2x-1 )/( 2x+1 ) */
  241. e -= 1;
  242. z = x - 0.5;
  243. y = 0.5 * z + 0.5;
  244. } else { /* 2 (x-1)/(x+1) */
  245. z = x - 0.5;
  246. z -= 0.5;
  247. y = 0.5 * x + 0.5;
  248. }
  249. x = z / y;
  250. z = x * x;
  251. y = x * (z * polevl(z, R, 2) / p1evl(z, S, 3));
  252. goto ldone;
  253. }
  254. /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
  255. if (x < SQRTH) {
  256. e -= 1;
  257. x = ldexp(x, 1) - 1.0; /* 2x - 1 */
  258. } else {
  259. x = x - 1.0;
  260. }
  261. z = x * x;
  262. #if DEC
  263. y = x * (z * polevl(x, P, 5) / p1evl(x, Q, 6)) - ldexp(z, -1);
  264. #else
  265. y = x * (z * polevl(x, P, 5) / p1evl(x, Q, 5)) - ldexp(z, -1);
  266. #endif
  267. ldone:
  268. /* Multiply log of fraction by log2(e)
  269. * and base 2 exponent by 1
  270. *
  271. * ***CAUTION***
  272. *
  273. * This sequence of operations is critical and it may
  274. * be horribly defeated by some compiler optimizers.
  275. */
  276. z = y * LOG2EA;
  277. z += x * LOG2EA;
  278. z += y;
  279. z += x;
  280. z += e;
  281. return (z);
  282. }