powi.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /* powi.c
  2. *
  3. * Real raised to integer power
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * double x, y, powi();
  10. * int n;
  11. *
  12. * y = powi( x, n );
  13. *
  14. *
  15. *
  16. * DESCRIPTION:
  17. *
  18. * Returns argument x raised to the nth power.
  19. * The routine efficiently decomposes n as a sum of powers of
  20. * two. The desired power is a product of two-to-the-kth
  21. * powers of x. Thus to compute the 32767 power of x requires
  22. * 28 multiplications instead of 32767 multiplications.
  23. *
  24. *
  25. *
  26. * ACCURACY:
  27. *
  28. *
  29. * Relative error:
  30. * arithmetic x domain n domain # trials peak rms
  31. * DEC .04,26 -26,26 100000 2.7e-16 4.3e-17
  32. * IEEE .04,26 -26,26 50000 2.0e-15 3.8e-16
  33. * IEEE 1,2 -1022,1023 50000 8.6e-14 1.6e-14
  34. *
  35. * Returns MAXNUM on overflow, zero on underflow.
  36. *
  37. */
  38. /* powi.c */
  39. /*
  40. Cephes Math Library Release 2.8: June, 2000
  41. Copyright 1984, 1995, 2000 by Stephen L. Moshier
  42. */
  43. #include <math.h>
  44. #ifdef ANSIPROT
  45. extern double log ( double );
  46. extern double frexp ( double, int * );
  47. extern int signbit ( double );
  48. #else
  49. double log(), frexp();
  50. int signbit();
  51. #endif
  52. extern double NEGZERO, INFINITY, MAXNUM, MAXLOG, MINLOG, LOGE2;
  53. double powi( x, nn )
  54. double x;
  55. int nn;
  56. {
  57. int n, e, sign, asign, lx;
  58. double w, y, s;
  59. /* See pow.c for these tests. */
  60. if( x == 0.0 )
  61. {
  62. if( nn == 0 )
  63. return( 1.0 );
  64. else if( nn < 0 )
  65. return( INFINITY );
  66. else
  67. {
  68. if( nn & 1 )
  69. return( x );
  70. else
  71. return( 0.0 );
  72. }
  73. }
  74. if( nn == 0 )
  75. return( 1.0 );
  76. if( nn == -1 )
  77. return( 1.0/x );
  78. if( x < 0.0 )
  79. {
  80. asign = -1;
  81. x = -x;
  82. }
  83. else
  84. asign = 0;
  85. if( nn < 0 )
  86. {
  87. sign = -1;
  88. n = -nn;
  89. }
  90. else
  91. {
  92. sign = 1;
  93. n = nn;
  94. }
  95. /* Even power will be positive. */
  96. if( (n & 1) == 0 )
  97. asign = 0;
  98. /* Overflow detection */
  99. /* Calculate approximate logarithm of answer */
  100. s = frexp( x, &lx );
  101. e = (lx - 1)*n;
  102. if( (e == 0) || (e > 64) || (e < -64) )
  103. {
  104. s = (s - 7.0710678118654752e-1) / (s + 7.0710678118654752e-1);
  105. s = (2.9142135623730950 * s - 0.5 + lx) * nn * LOGE2;
  106. }
  107. else
  108. {
  109. s = LOGE2 * e;
  110. }
  111. if( s > MAXLOG )
  112. {
  113. mtherr( "powi", OVERFLOW );
  114. y = INFINITY;
  115. goto done;
  116. }
  117. #if DENORMAL
  118. if( s < MINLOG )
  119. {
  120. y = 0.0;
  121. goto done;
  122. }
  123. /* Handle tiny denormal answer, but with less accuracy
  124. * since roundoff error in 1.0/x will be amplified.
  125. * The precise demarcation should be the gradual underflow threshold.
  126. */
  127. if( (s < (-MAXLOG+2.0)) && (sign < 0) )
  128. {
  129. x = 1.0/x;
  130. sign = -sign;
  131. }
  132. #else
  133. /* do not produce denormal answer */
  134. if( s < -MAXLOG )
  135. return(0.0);
  136. #endif
  137. /* First bit of the power */
  138. if( n & 1 )
  139. y = x;
  140. else
  141. y = 1.0;
  142. w = x;
  143. n >>= 1;
  144. while( n )
  145. {
  146. w = w * w; /* arg to the 2-to-the-kth power */
  147. if( n & 1 ) /* if that bit is set, then include in product */
  148. y *= w;
  149. n >>= 1;
  150. }
  151. if( sign < 0 )
  152. y = 1.0/y;
  153. done:
  154. if( asign )
  155. {
  156. /* odd power of negative number */
  157. if( y == 0.0 )
  158. y = NEGZERO;
  159. else
  160. y = -y;
  161. }
  162. return(y);
  163. }