log10l.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /* log10l.c
  2. *
  3. * Common logarithm, long double precision
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double x, y, log10l();
  10. *
  11. * y = log10l( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns the base 10 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 logarithm
  21. * 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 9.0e-20 2.6e-20
  36. * IEEE exp(+-10000) 30000 6.0e-20 2.3e-20
  37. *
  38. * In the tests over the interval exp(+-10000), the logarithms
  39. * of the random arguments were uniformly distributed over
  40. * [-10000, +10000].
  41. *
  42. * ERROR MESSAGES:
  43. *
  44. * log singularity: x = 0; returns MINLOG
  45. * log domain: x < 0; returns MINLOG
  46. */
  47. /*
  48. Cephes Math Library Release 2.2: January, 1991
  49. Copyright 1984, 1991 by Stephen L. Moshier
  50. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  51. */
  52. #include <math.h>
  53. static char fname[] = {"log10l"};
  54. /* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
  55. * 1/sqrt(2) <= x < sqrt(2)
  56. * Theoretical peak relative error = 6.2e-22
  57. */
  58. #ifdef UNK
  59. static long double P[] = {
  60. 4.9962495940332550844739E-1L,
  61. 1.0767376367209449010438E1L,
  62. 7.7671073698359539859595E1L,
  63. 2.5620629828144409632571E2L,
  64. 4.2401812743503691187826E2L,
  65. 3.4258224542413922935104E2L,
  66. 1.0747524399916215149070E2L,
  67. };
  68. static long double Q[] = {
  69. /* 1.0000000000000000000000E0,*/
  70. 2.3479774160285863271658E1L,
  71. 1.9444210022760132894510E2L,
  72. 7.7952888181207260646090E2L,
  73. 1.6911722418503949084863E3L,
  74. 2.0307734695595183428202E3L,
  75. 1.2695660352705325274404E3L,
  76. 3.2242573199748645407652E2L,
  77. };
  78. #endif
  79. #ifdef IBMPC
  80. static short P[] = {
  81. 0xfe72,0xce22,0xd7b9,0xffce,0x3ffd, XPD
  82. 0xb778,0x0e34,0x2c71,0xac47,0x4002, XPD
  83. 0xea8b,0xc751,0x96f8,0x9b57,0x4005, XPD
  84. 0xfeaf,0x6a02,0x67fb,0x801a,0x4007, XPD
  85. 0x6b5a,0xf252,0x51ff,0xd402,0x4007, XPD
  86. 0x39ce,0x9f76,0x8704,0xab4a,0x4007, XPD
  87. 0x1b39,0x740b,0x532e,0xd6f3,0x4005, XPD
  88. };
  89. static short Q[] = {
  90. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  91. 0x2f3a,0xbf26,0x93d5,0xbbd6,0x4003, XPD
  92. 0x13c8,0x031a,0x2d7b,0xc271,0x4006, XPD
  93. 0x449d,0x1993,0xd933,0xc2e1,0x4008, XPD
  94. 0x5b65,0x574e,0x8301,0xd365,0x4009, XPD
  95. 0xa65d,0x3bd2,0xc043,0xfdd8,0x4009, XPD
  96. 0x3b21,0xffea,0x1cf5,0x9eb2,0x4009, XPD
  97. 0x545c,0xd708,0x7e62,0xa136,0x4007, XPD
  98. };
  99. #endif
  100. #ifdef MIEEE
  101. static long P[] = {
  102. 0x3ffd0000,0xffced7b9,0xce22fe72,
  103. 0x40020000,0xac472c71,0x0e34b778,
  104. 0x40050000,0x9b5796f8,0xc751ea8b,
  105. 0x40070000,0x801a67fb,0x6a02feaf,
  106. 0x40070000,0xd40251ff,0xf2526b5a,
  107. 0x40070000,0xab4a8704,0x9f7639ce,
  108. 0x40050000,0xd6f3532e,0x740b1b39,
  109. };
  110. static long Q[] = {
  111. /*0x3fff0000,0x80000000,0x00000000,*/
  112. 0x40030000,0xbbd693d5,0xbf262f3a,
  113. 0x40060000,0xc2712d7b,0x031a13c8,
  114. 0x40080000,0xc2e1d933,0x1993449d,
  115. 0x40090000,0xd3658301,0x574e5b65,
  116. 0x40090000,0xfdd8c043,0x3bd2a65d,
  117. 0x40090000,0x9eb21cf5,0xffea3b21,
  118. 0x40070000,0xa1367e62,0xd708545c,
  119. };
  120. #endif
  121. /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
  122. * where z = 2(x-1)/(x+1)
  123. * 1/sqrt(2) <= x < sqrt(2)
  124. * Theoretical peak relative error = 6.16e-22
  125. */
  126. #ifdef UNK
  127. static long double R[4] = {
  128. 1.9757429581415468984296E-3L,
  129. -7.1990767473014147232598E-1L,
  130. 1.0777257190312272158094E1L,
  131. -3.5717684488096787370998E1L,
  132. };
  133. static long double S[4] = {
  134. /* 1.00000000000000000000E0L,*/
  135. -2.6201045551331104417768E1L,
  136. 1.9361891836232102174846E2L,
  137. -4.2861221385716144629696E2L,
  138. };
  139. /* log10(2) */
  140. #define L102A 0.3125L
  141. #define L102B -1.1470004336018804786261e-2L
  142. /* log10(e) */
  143. #define L10EA 0.5L
  144. #define L10EB -6.5705518096748172348871e-2L
  145. #endif
  146. #ifdef IBMPC
  147. static short R[] = {
  148. 0x6ef4,0xf922,0x7763,0x817b,0x3ff6, XPD
  149. 0x15fd,0x1af9,0xde8f,0xb84b,0xbffe, XPD
  150. 0x8b96,0x4f8d,0xa53c,0xac6f,0x4002, XPD
  151. 0x8932,0xb4e3,0xe8ae,0x8ede,0xc004, XPD
  152. };
  153. static short S[] = {
  154. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  155. 0x7ce4,0x1fc9,0xbdc5,0xd19b,0xc003, XPD
  156. 0x0af3,0x0d10,0x716f,0xc19e,0x4006, XPD
  157. 0x4d7d,0x0f55,0x5d06,0xd64e,0xc007, XPD
  158. };
  159. static short LG102A[] = {0x0000,0x0000,0x0000,0xa000,0x3ffd, XPD};
  160. #define L102A *(long double *)LG102A
  161. static short LG102B[] = {0x0cee,0x8601,0xaf60,0xbbec,0xbff8, XPD};
  162. #define L102B *(long double *)LG102B
  163. static short LG10EA[] = {0x0000,0x0000,0x0000,0x8000,0x3ffe, XPD};
  164. #define L10EA *(long double *)LG10EA
  165. static short LG10EB[] = {0x39ab,0x235e,0x9d5b,0x8690,0xbffb, XPD};
  166. #define L10EB *(long double *)LG10EB
  167. #endif
  168. #ifdef MIEEE
  169. static long R[12] = {
  170. 0x3ff60000,0x817b7763,0xf9226ef4,
  171. 0xbffe0000,0xb84bde8f,0x1af915fd,
  172. 0x40020000,0xac6fa53c,0x4f8d8b96,
  173. 0xc0040000,0x8edee8ae,0xb4e38932,
  174. };
  175. static long S[9] = {
  176. /*0x3fff0000,0x80000000,0x00000000,*/
  177. 0xc0030000,0xd19bbdc5,0x1fc97ce4,
  178. 0x40060000,0xc19e716f,0x0d100af3,
  179. 0xc0070000,0xd64e5d06,0x0f554d7d,
  180. };
  181. static long LG102A[] = {0x3ffd0000,0xa0000000,0x00000000};
  182. #define L102A *(long double *)LG102A
  183. static long LG102B[] = {0xbff80000,0xbbecaf60,0x86010cee};
  184. #define L102B *(long double *)LG102B
  185. static long LG10EA[] = {0x3ffe0000,0x80000000,0x00000000};
  186. #define L10EA *(long double *)LG10EA
  187. static long LG10EB[] = {0xbffb0000,0x86909d5b,0x235e39ab};
  188. #define L10EB *(long double *)LG10EB
  189. #endif
  190. #define SQRTH 0.70710678118654752440L
  191. #ifdef ANSIPROT
  192. extern long double frexpl ( long double, int * );
  193. extern long double ldexpl ( long double, int );
  194. extern long double polevll ( long double, void *, int );
  195. extern long double p1evll ( long double, void *, int );
  196. extern int isnanl ( long double );
  197. #else
  198. long double frexpl(), ldexpl(), polevll(), p1evll(), isnanl();
  199. #endif
  200. #ifdef INFINITIES
  201. extern long double INFINITYL;
  202. #endif
  203. #ifdef NANS
  204. extern long double NANL;
  205. #endif
  206. long double log10l(x)
  207. long double x;
  208. {
  209. long double y;
  210. VOLATILE long double z;
  211. int e;
  212. #ifdef NANS
  213. if( isnanl(x) )
  214. return(x);
  215. #endif
  216. /* Test for domain */
  217. if( x <= 0.0L )
  218. {
  219. if( x == 0.0L )
  220. {
  221. mtherr( fname, SING );
  222. #ifdef INFINITIES
  223. return(-INFINITYL);
  224. #else
  225. return( -4.9314733889673399399914e3L );
  226. #endif
  227. }
  228. else
  229. {
  230. mtherr( fname, DOMAIN );
  231. #ifdef NANS
  232. return(NANL);
  233. #else
  234. return( -4.9314733889673399399914e3L );
  235. #endif
  236. }
  237. }
  238. #ifdef INFINITIES
  239. if( x == INFINITYL )
  240. return(INFINITYL);
  241. #endif
  242. /* separate mantissa from exponent */
  243. /* Note, frexp is used so that denormal numbers
  244. * will be handled properly.
  245. */
  246. x = frexpl( x, &e );
  247. /* logarithm using log(x) = z + z**3 P(z)/Q(z),
  248. * where z = 2(x-1)/x+1)
  249. */
  250. if( (e > 2) || (e < -2) )
  251. {
  252. if( x < SQRTH )
  253. { /* 2( 2x-1 )/( 2x+1 ) */
  254. e -= 1;
  255. z = x - 0.5L;
  256. y = 0.5L * z + 0.5L;
  257. }
  258. else
  259. { /* 2 (x-1)/(x+1) */
  260. z = x - 0.5L;
  261. z -= 0.5L;
  262. y = 0.5L * x + 0.5L;
  263. }
  264. x = z / y;
  265. z = x*x;
  266. y = x * ( z * polevll( z, R, 3 ) / p1evll( z, S, 3 ) );
  267. goto done;
  268. }
  269. /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
  270. if( x < SQRTH )
  271. {
  272. e -= 1;
  273. x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */
  274. }
  275. else
  276. {
  277. x = x - 1.0L;
  278. }
  279. z = x*x;
  280. y = x * ( z * polevll( x, P, 6 ) / p1evll( x, Q, 7 ) );
  281. y = y - ldexpl( z, -1 ); /* -0.5x^2 + ... */
  282. done:
  283. /* Multiply log of fraction by log10(e)
  284. * and base 2 exponent by log10(2).
  285. *
  286. * ***CAUTION***
  287. *
  288. * This sequence of operations is critical and it may
  289. * be horribly defeated by some compiler optimizers.
  290. */
  291. z = y * (L10EB);
  292. z += x * (L10EB);
  293. z += e * (L102B);
  294. z += y * (L10EA);
  295. z += x * (L10EA);
  296. z += e * (L102A);
  297. return( z );
  298. }