exp2l.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* exp2l.c
  2. *
  3. * Base 2 exponential function, long double precision
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double x, y, exp2l();
  10. *
  11. * y = exp2l( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns 2 raised to the x power.
  18. *
  19. * Range reduction is accomplished by separating the argument
  20. * into an integer k and fraction f such that
  21. * x k f
  22. * 2 = 2 2.
  23. *
  24. * A Pade' form
  25. *
  26. * 1 + 2x P(x**2) / (Q(x**2) - x P(x**2) )
  27. *
  28. * approximates 2**x in the basic range [-0.5, 0.5].
  29. *
  30. *
  31. * ACCURACY:
  32. *
  33. * Relative error:
  34. * arithmetic domain # trials peak rms
  35. * IEEE +-16300 300000 9.1e-20 2.6e-20
  36. *
  37. *
  38. * See exp.c for comments on error amplification.
  39. *
  40. *
  41. * ERROR MESSAGES:
  42. *
  43. * message condition value returned
  44. * exp2l underflow x < -16382 0.0
  45. * exp2l overflow x >= 16384 MAXNUM
  46. *
  47. */
  48. /*
  49. Cephes Math Library Release 2.7: May, 1998
  50. Copyright 1984, 1991, 1998 by Stephen L. Moshier
  51. */
  52. #include <math.h>
  53. #ifdef UNK
  54. static long double P[] = {
  55. 6.0614853552242266094567E1L,
  56. 3.0286971917562792508623E4L,
  57. 2.0803843631901852422887E6L,
  58. };
  59. static long double Q[] = {
  60. /* 1.0000000000000000000000E0,*/
  61. 1.7492876999891839021063E3L,
  62. 3.2772515434906797273099E5L,
  63. 6.0027204078348487957118E6L,
  64. };
  65. #endif
  66. #ifdef IBMPC
  67. static short P[] = {
  68. 0xffd8,0x6ad6,0x9c2b,0xf275,0x4004, XPD
  69. 0x3426,0x2dc5,0xf19f,0xec9d,0x400d, XPD
  70. 0x7ec0,0xd041,0x02e7,0xfdf4,0x4013, XPD
  71. };
  72. static short Q[] = {
  73. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  74. 0x575b,0x9b93,0x34d6,0xdaa9,0x4009, XPD
  75. 0xe38d,0x6d74,0xa4f0,0xa005,0x4011, XPD
  76. 0xb37e,0xcfba,0x40d0,0xb730,0x4015, XPD
  77. };
  78. #endif
  79. #ifdef MIEEE
  80. static long P[] = {
  81. 0x40040000,0xf2759c2b,0x6ad6ffd8,
  82. 0x400d0000,0xec9df19f,0x2dc53426,
  83. 0x40130000,0xfdf402e7,0xd0417ec0,
  84. };
  85. static long Q[] = {
  86. /*0x3fff0000,0x80000000,0x00000000,*/
  87. 0x40090000,0xdaa934d6,0x9b93575b,
  88. 0x40110000,0xa005a4f0,0x6d74e38d,
  89. 0x40150000,0xb73040d0,0xcfbab37e,
  90. };
  91. #endif
  92. #define MAXL2L 16384.0L
  93. #define MINL2L -16382.0L
  94. extern long double MAXNUML;
  95. #ifdef ANSIPROT
  96. extern long double polevll ( long double, void *, int );
  97. extern long double p1evll ( long double, void *, int );
  98. extern long double floorl ( long double );
  99. extern long double ldexpl ( long double, int );
  100. extern int isnanl ( long double );
  101. #else
  102. long double polevll(), p1evll(), floorl(), ldexpl(), isnanl();
  103. #endif
  104. #ifdef INFINITIES
  105. extern long double INFINITYL;
  106. #endif
  107. long double exp2l(x)
  108. long double x;
  109. {
  110. long double px, xx;
  111. int n;
  112. #ifdef NANS
  113. if( isnanl(x) )
  114. return(x);
  115. #endif
  116. if( x > MAXL2L)
  117. {
  118. #ifdef INFINITIES
  119. return( INFINITYL );
  120. #else
  121. mtherr( "exp2l", OVERFLOW );
  122. return( MAXNUML );
  123. #endif
  124. }
  125. if( x < MINL2L )
  126. {
  127. #ifndef INFINITIES
  128. mtherr( "exp2l", UNDERFLOW );
  129. #endif
  130. return(0.0L);
  131. }
  132. xx = x; /* save x */
  133. /* separate into integer and fractional parts */
  134. px = floorl(x+0.5L);
  135. n = px;
  136. x = x - px;
  137. /* rational approximation
  138. * exp2(x) = 1.0 + 2xP(xx)/(Q(xx) - P(xx))
  139. * where xx = x**2
  140. */
  141. xx = x * x;
  142. px = x * polevll( xx, P, 2 );
  143. x = px / ( p1evll( xx, Q, 3 ) - px );
  144. x = 1.0L + ldexpl( x, 1 );
  145. /* scale by power of 2 */
  146. x = ldexpl( x, n );
  147. return(x);
  148. }