Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*                                                      powi.c
  2.  *
  3.  *      Real raised to integer power
  4.  *
  5.  *
  6.  *
  7.  * SYNOPSIS:
  8.  *
  9.  * float x, y, __powif();
  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. /*
  41. Cephes Math Library Release 2.8:  June, 2000
  42. Copyright 1984, 1995, 2000 by Stephen L. Moshier
  43. */
  44.  
  45. /*
  46. Modified for float from powi.c and adapted to mingw
  47. 2002-10-01 Danny Smith <dannysmith@users.sourceforge.net>
  48. */
  49.  
  50. #ifdef __MINGW32__
  51. #include "cephes_mconf.h"
  52. #else
  53. #include "mconf.h"
  54. #ifdef ANSIPROT
  55. extern float logf ( float );
  56. extern float frexpf ( float, int * );
  57. extern int signbitf ( float );
  58. #else
  59. float logf(), frexpf();
  60. int signbitf();
  61. #endif
  62. extern float NEGZEROF, INFINITYF, MAXNUMF, MAXLOGF, MINLOGF, LOGE2F;
  63. #endif /* __MINGW32__ */
  64.  
  65. #ifndef _SET_ERRNO
  66. #define _SET_ERRNO(x)
  67. #endif
  68.  
  69. float __powif( float x, int nn )
  70. {
  71. int n, e, sign, asign, lx;
  72. float w, y, s;
  73.  
  74. /* See pow.c for these tests.  */
  75. if( x == 0.0F )
  76.         {
  77.         if( nn == 0 )
  78.                 return( 1.0F );
  79.         else if( nn < 0 )
  80.             return( INFINITYF );
  81.         else
  82.           {
  83.             if( nn & 1 )
  84.               return( x );
  85.             else
  86.               return( 0.0 );
  87.           }
  88.         }
  89.  
  90. if( nn == 0 )
  91.         return( 1.0 );
  92.  
  93. if( nn == -1 )
  94.         return( 1.0/x );
  95.  
  96. if( x < 0.0 )
  97.         {
  98.         asign = -1;
  99.         x = -x;
  100.         }
  101. else
  102.         asign = 0;
  103.  
  104.  
  105. if( nn < 0 )
  106.         {
  107.         sign = -1;
  108.         n = -nn;
  109.         }
  110. else
  111.         {
  112.         sign = 1;
  113.         n = nn;
  114.         }
  115.  
  116. /* Even power will be positive. */
  117. if( (n & 1) == 0 )
  118.         asign = 0;
  119.  
  120. /* Overflow detection */
  121.  
  122. /* Calculate approximate logarithm of answer */
  123. s = frexpf( x, &lx );
  124. e = (lx - 1)*n;
  125. if( (e == 0) || (e > 64) || (e < -64) )
  126.         {
  127.         s = (s - 7.0710678118654752e-1) / (s +  7.0710678118654752e-1);
  128.         s = (2.9142135623730950 * s - 0.5 + lx) * nn * LOGE2F;
  129.         }
  130. else
  131.         {
  132.         s = LOGE2F * e;
  133.         }
  134.  
  135. if( s > MAXLOGF )
  136.         {
  137.         mtherr( "__powif", OVERFLOW );
  138.         _SET_ERRNO(ERANGE);
  139.         y = INFINITYF;
  140.         goto done;
  141.         }
  142.  
  143. #if DENORMAL
  144. if( s < MINLOGF )
  145.         {
  146.         y = 0.0;
  147.         goto done;
  148.         }
  149.  
  150. /* Handle tiny denormal answer, but with less accuracy
  151.  * since roundoff error in 1.0/x will be amplified.
  152.  * The precise demarcation should be the gradual underflow threshold.
  153.  */
  154. if( (s < (-MAXLOGF+2.0)) && (sign < 0) )
  155.         {
  156.         x = 1.0/x;
  157.         sign = -sign;
  158.         }
  159. #else
  160. /* do not produce denormal answer */
  161. if( s < -MAXLOGF )
  162.         return(0.0);
  163. #endif
  164.  
  165.  
  166. /* First bit of the power */
  167. if( n & 1 )
  168.         y = x;
  169.                
  170. else
  171.         y = 1.0;
  172.  
  173. w = x;
  174. n >>= 1;
  175. while( n )
  176.         {
  177.         w = w * w;      /* arg to the 2-to-the-kth power */
  178.         if( n & 1 )     /* if that bit is set, then include in product */
  179.                 y *= w;
  180.         n >>= 1;
  181.         }
  182.  
  183. if( sign < 0 )
  184.         y = 1.0/y;
  185.  
  186. done:
  187.  
  188. if( asign )
  189.         {
  190.         /* odd power of negative number */
  191.         if( y == 0.0 )
  192.                 y = NEGZEROF;
  193.         else
  194.                 y = -y;
  195.         }
  196. return(y);
  197. }
  198.