log2.c 7.0 KB

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