/* pow.c
*
* Power function
*
*
*
* SYNOPSIS:
*
* double x, y, z, pow();
*
* z = pow( x, y );
*
*
*
* DESCRIPTION:
*
* Computes x raised to the yth power. Analytically,
*
* x**y = exp( y log(x) ).
*
* Following Cody and Waite, this program uses a lookup table
* of 2**-i/16 and pseudo extended precision arithmetic to
* obtain an extra three bits of accuracy in both the logarithm
* and the exponential.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE -26,26 30000 4.2e-16 7.7e-17
* DEC -26,26 60000 4.8e-17 9.1e-18
* 1/26 < x < 26, with log(x) uniformly distributed.
* -26 < y < 26, y uniformly distributed.
* IEEE 0,8700 30000 1.5e-14 2.1e-15
* 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed.
*
*
* ERROR MESSAGES:
*
* message condition value returned
* pow overflow x**y > MAXNUM INFINITY
* pow underflow x**y < 1/MAXNUM 0.0
* pow domain x<0 and y noninteger 0.0
*
*/
/*
Cephes Math Library Release 2.8: June, 2000
Copyright 1984, 1995, 2000 by Stephen L. Moshier
*/
#include "mconf.h"
static char fname[] = {"pow" };
#define SQRTH 0 .70710678118654752440
#ifdef UNK
static double P[] = {4 .97778295871696322025 E-1 , 3 .73336776063286838734 E0,
7 .69994162726912503298 E0, 4 .66651806774358464979 E0};
static double Q[] = {
/* 1.00000000000000000000E0, */
9 .33340916416696166113 E0, 2 .79999886606328401649 E1,
3 .35994905342304405431 E1, 1 .39995542032307539578 E1};
/* 2^(-i/16), IEEE precision */
static double A[] = {1 .00000000000000000000 E0, 9 .57603280698573700036 E-1 ,
9 .17004043204671215328 E-1 , 8 .78126080186649726755 E-1 ,
8 .40896415253714502036 E-1 , 8 .05245165974627141736 E-1 ,
7 .71105412703970372057 E-1 , 7 .38413072969749673113 E-1 ,
7 .07106781186547572737 E-1 , 6 .77127773468446325644 E-1 ,
6 .48419777325504820276 E-1 , 6 .20928906036742001007 E-1 ,
5 .94603557501360513449 E-1 , 5 .69394317378345782288 E-1 ,
5 .45253866332628844837 E-1 , 5 .22136891213706877402 E-1 ,
5 .00000000000000000000 E-1 };
static double B[] = {0 .00000000000000000000 E0, 1 .64155361212281360176 E-17 ,
4 .09950501029074826006 E-17 , 3 .97491740484881042808 E-17 ,
-4 .83364665672645672553 E-17 , 1 .26912513974441574796 E-17 ,
1 .99100761573282305549 E-17 , -1 .52339103990623557348 E-17 ,
0 .00000000000000000000 E0};
static double R[] = {1 .49664108433729301083 E-5 , 1 .54010762792771901396 E-4 ,
1 .33335476964097721140 E-3 , 9 .61812908476554225149 E-3 ,
5 .55041086645832347466 E-2 , 2 .40226506959099779976 E-1 ,
6 .93147180559945308821 E-1 };
#define douba(k) A[k]
#define doubb(k) B[k]
#define MEXP 16383 .0
#ifdef DENORMAL
#define MNEXP -17183 .0
#else
#define MNEXP -16383 .0
#endif
#endif
#ifdef DEC
static unsigned short P[] = {
0037776 , 0156313 , 0175332 , 0163602 , 0040556 , 0167577 , 0052366 , 0174245 ,
0040766 , 0062753 , 0175707 , 0055564 , 0040625 , 0052035 , 0131344 , 0155636 ,
};
static unsigned short Q[] = {
/*0040200,0000000,0000000,0000000,*/
0041025 , 0052644 , 0154404 , 0105155 , 0041337 , 0177772 , 0007016 , 0047646 ,
0041406 , 0062740 , 0154273 , 0020020 , 0041137 , 0177054 , 0106127 , 0044555 ,
};
static unsigned short A[] = {
0040200 , 0000000 , 0000000 , 0000000 , 0040165 , 0022575 , 0012444 , 0103314 ,
0040152 , 0140306 , 0163735 , 0022071 , 0040140 , 0146336 , 0166052 , 0112341 ,
0040127 , 0042374 , 0145326 , 0116553 , 0040116 , 0022214 , 0012437 , 0102201 ,
0040105 , 0063452 , 0010525 , 0003333 , 0040075 , 0004243 , 0117530 , 0006067 ,
0040065 , 0002363 , 0031771 , 0157145 , 0040055 , 0054076 , 0165102 , 0120513 ,
0040045 , 0177326 , 0124661 , 0050471 , 0040036 , 0172462 , 0060221 , 0120422 ,
0040030 , 0033760 , 0050615 , 0134251 , 0040021 , 0141723 , 0071653 , 0010703 ,
0040013 , 0112701 , 0161752 , 0105727 , 0040005 , 0125303 , 0063714 , 0044173 ,
0040000 , 0000000 , 0000000 , 0000000 };
static unsigned short B[] = {
0000000 , 0000000 , 0000000 , 0000000 , 0021473 , 0040265 , 0153315 , 0140671 ,
0121074 , 0062627 , 0042146 , 0176454 , 0121413 , 0003524 , 0136332 , 0066212 ,
0121767 , 0046404 , 0166231 , 0012553 , 0121257 , 0015024 , 0002357 , 0043574 ,
0021736 , 0106532 , 0043060 , 0056206 , 0121310 , 0020334 , 0165705 , 0035326 ,
0000000 , 0000000 , 0000000 , 0000000 };
static unsigned short R[] = {
0034173 , 0014076 , 0137624 , 0115771 , 0035041 , 0076763 , 0003744 ,
0111311 , 0035656 , 0141766 , 0041127 , 0074351 , 0036435 , 0112533 ,
0073611 , 0116664 , 0037143 , 0054106 , 0134040 , 0152223 , 0037565 ,
0176757 , 0176026 , 0025551 , 0040061 , 0071027 , 0173721 , 0147572 };
/*
static double R[] = {
0.14928852680595608186e-4,
0.15400290440989764601e-3,
0.13333541313585784703e-2,
0.96181290595172416964e-2,
0.55504108664085595326e-1,
0.24022650695909537056e0,
0.69314718055994529629e0
};
*/
#define douba(k) (*(double *)&A[(k) << 2 ])
#define doubb(k) (*(double *)&B[(k) << 2 ])
#define MEXP 2031 .0
#define MNEXP -2031 .0
#endif
#ifdef IBMPC
static unsigned short P[] = {
0 x5cf0, 0 x7f5b, 0 xdb99, 0 x3fdf, 0 xdf15, 0 xea9e, 0 xddef, 0 x400d,
0 xeb6f, 0 x7f78, 0 xccbd, 0 x401e, 0 x9b74, 0 xb65c, 0 xaa83, 0 x4012,
};
static unsigned short Q[] = {
/*0x0000,0x0000,0x0000,0x3ff0,*/
0 x914e, 0 x9b20, 0 xaab4, 0 x4022, 0 xc9f5, 0 x41c1, 0 xffff, 0 x403b,
0 x6402, 0 x1b17, 0 xccbc, 0 x4040, 0 xe92e, 0 x918a, 0 xffc5, 0 x402b,
};
static unsigned short A[] = {
0 x0000, 0 x0000, 0 x0000, 0 x3ff0, 0 x90da, 0 xa2a4, 0 xa4af, 0 x3fee, 0 xa487,
0 xdcfb, 0 x5818, 0 x3fed, 0 x529c, 0 xdd85, 0 x199b, 0 x3fec, 0 xd3ad, 0 x995a,
0 xe89f, 0 x3fea, 0 xf090, 0 x82a3, 0 xc491, 0 x3fe9, 0 xa0db, 0 x422a, 0 xace5,
0 x3fe8, 0 x0187, 0 x73eb, 0 xa114, 0 x3fe7, 0 x3bcd, 0 x667f, 0 xa09e, 0 x3fe6,
0 x5429, 0 xdd48, 0 xab07, 0 x3fe5, 0 x2a27, 0 xd536, 0 xbfda, 0 x3fe4, 0 x3422,
0 x4c12, 0 xdea6, 0 x3fe3, 0 xb715, 0 x0a31, 0 x06fe, 0 x3fe3, 0 x6238, 0 x6e75,
0 x387a, 0 x3fe2, 0 x517b, 0 x3c7d, 0 x72b8, 0 x3fe1, 0 x890f, 0 x6cf9, 0 xb558,
0 x3fe0, 0 x0000, 0 x0000, 0 x0000, 0 x3fe0};
static unsigned short B[] = {
0 x0000, 0 x0000, 0 x0000, 0 x0000, 0 x3707, 0 xd75b, 0 xed02, 0 x3c72, 0 xcc81,
0 x345d, 0 xa1cd, 0 x3c87, 0 x4b27, 0 x5686, 0 xe9f1, 0 x3c86, 0 x6456, 0 x13b2,
0 xdd34, 0 xbc8b, 0 x42e2, 0 xafec, 0 x4397, 0 x3c6d, 0 x82e4, 0 xd231, 0 xf46a,
0 x3c76, 0 x8a76, 0 xb9d7, 0 x9041, 0 xbc71, 0 x0000, 0 x0000, 0 x0000, 0 x0000};
static unsigned short R[] = {0 x937f, 0 xd7f2, 0 x6307, 0 x3eef, 0 x9259, 0 x60fc,
0 x2fbe, 0 x3f24, 0 xef1d, 0 xc84a, 0 xd87e, 0 x3f55,
0 x33b7, 0 x6ef1, 0 xb2ab, 0 x3f83, 0 x1a92, 0 xd704,
0 x6b08, 0 x3fac, 0 xc56d, 0 xff82, 0 xbfbd, 0 x3fce,
0 x39ef, 0 xfefa, 0 x2e42, 0 x3fe6};
#define douba(k) (*(double *)&A[(k) << 2 ])
#define doubb(k) (*(double *)&B[(k) << 2 ])
#define MEXP 16383 .0
#ifdef DENORMAL
#define MNEXP -17183 .0
#else
#define MNEXP -16383 .0
#endif
#endif
#ifdef MIEEE
static unsigned short P[] = {0 x3fdf, 0 xdb99, 0 x7f5b, 0 x5cf0, 0 x400d, 0 xddef,
0 xea9e, 0 xdf15, 0 x401e, 0 xccbd, 0 x7f78, 0 xeb6f,
0 x4012, 0 xaa83, 0 xb65c, 0 x9b74};
static unsigned short Q[] = {0 x4022, 0 xaab4, 0 x9b20, 0 x914e, 0 x403b, 0 xffff,
0 x41c1, 0 xc9f5, 0 x4040, 0 xccbc, 0 x1b17, 0 x6402,
0 x402b, 0 xffc5, 0 x918a, 0 xe92e};
static unsigned short A[] = {
0 x3ff0, 0 x0000, 0 x0000, 0 x0000, 0 x3fee, 0 xa4af, 0 xa2a4, 0 x90da, 0 x3fed,
0 x5818, 0 xdcfb, 0 xa487, 0 x3fec, 0 x199b, 0 xdd85, 0 x529c, 0 x3fea, 0 xe89f,
0 x995a, 0 xd3ad, 0 x3fe9, 0 xc491, 0 x82a3, 0 xf090, 0 x3fe8, 0 xace5, 0 x422a,
0 xa0db, 0 x3fe7, 0 xa114, 0 x73eb, 0 x0187, 0 x3fe6, 0 xa09e, 0 x667f, 0 x3bcd,
0 x3fe5, 0 xab07, 0 xdd48, 0 x5429, 0 x3fe4, 0 xbfda, 0 xd536, 0 x2a27, 0 x3fe3,
0 xdea6, 0 x4c12, 0 x3422, 0 x3fe3, 0 x06fe, 0 x0a31, 0 xb715, 0 x3fe2, 0 x387a,
0 x6e75, 0 x6238, 0 x3fe1, 0 x72b8, 0 x3c7d, 0 x517b, 0 x3fe0, 0 xb558, 0 x6cf9,
0 x890f, 0 x3fe0, 0 x0000, 0 x0000, 0 x0000};
static unsigned short B[] = {
0 x0000, 0 x0000, 0 x0000, 0 x0000, 0 x3c72, 0 xed02, 0 xd75b, 0 x3707, 0 x3c87,
0 xa1cd, 0 x345d, 0 xcc81, 0 x3c86, 0 xe9f1, 0 x5686, 0 x4b27, 0 xbc8b, 0 xdd34,
0 x13b2, 0 x6456, 0 x3c6d, 0 x4397, 0 xafec, 0 x42e2, 0 x3c76, 0 xf46a, 0 xd231,
0 x82e4, 0 xbc71, 0 x9041, 0 xb9d7, 0 x8a76, 0 x0000, 0 x0000, 0 x0000, 0 x0000};
static unsigned short R[] = {0 x3eef, 0 x6307, 0 xd7f2, 0 x937f, 0 x3f24, 0 x2fbe,
0 x60fc, 0 x9259, 0 x3f55, 0 xd87e, 0 xc84a, 0 xef1d,
0 x3f83, 0 xb2ab, 0 x6ef1, 0 x33b7, 0 x3fac, 0 x6b08,
0 xd704, 0 x1a92, 0 x3fce, 0 xbfbd, 0 xff82, 0 xc56d,
0 x3fe6, 0 x2e42, 0 xfefa, 0 x39ef};
#define douba(k) (*(double *)&A[(k) << 2 ])
#define doubb(k) (*(double *)&B[(k) << 2 ])
#define MEXP 16383 .0
#ifdef DENORMAL
#define MNEXP -17183 .0
#else
#define MNEXP -16383 .0
#endif
#endif
/* log2(e) - 1 */
#define LOG2EA 0 .44269504088896340736
#define F W
#define Fa Wa
#define Fb Wb
#define G W
#define Ga Wa
#define Gb u
#define H W
#define Ha Wb
#define Hb Wb
#ifdef ANSIPROT
extern double floor(double );
extern double fabs(double );
extern double frexp(double , int *);
extern double ldexp(double , int );
extern double polevl(double , void *, int );
extern double p1evl(double , void *, int );
extern double powi(double , int );
extern int signbit(double );
extern int isnan(double );
extern int isfinite(double );
static double reduc(double );
#else
double floor(), fabs(), frexp(), ldexp();
double polevl(), p1evl(), powi();
int signbit(), isnan(), isfinite();
static double reduc();
#endif
extern double MAXNUM;
#ifdef INFINITIES
extern double INFINITY;
#endif
#ifdef NANS
extern double NAN;
#endif
#ifdef MINUSZERO
extern double NEGZERO;
#endif
double pow(x, y) double x, y;
{
double w, z, W, Wa, Wb, ya, yb, u;
/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */
double aw, ay, wy;
int e, i, nflg, iyflg, yoddint;
if (y == 0 .0 )
return (1 .0 );
#ifdef NANS
if (isnan(x))
return (x);
if (isnan(y))
return (y);
#endif
if (y == 1 .0 )
return (x);
#ifdef INFINITIES
if (!isfinite(y) && (x == 1 .0 || x == -1 .0 )) {
mtherr("pow" , DOMAIN);
#ifdef NANS
return (NAN);
#else
return (INFINITY);
#endif
}
#endif
if (x == 1 .0 )
return (1 .0 );
if (y >= MAXNUM) {
#ifdef INFINITIES
if (x > 1 .0 )
return (INFINITY);
#else
if (x > 1 .0 )
return (MAXNUM);
#endif
if (x > 0 .0 && x < 1 .0 )
return (0 .0 );
if (x < -1 .0 ) {
#ifdef INFINITIES
return (INFINITY);
#else
return (MAXNUM);
#endif
}
if (x > -1 .0 && x < 0 .0 )
return (0 .0 );
}
if (y <= -MAXNUM) {
if (x > 1 .0 )
return (0 .0 );
#ifdef INFINITIES
if (x > 0 .0 && x < 1 .0 )
return (INFINITY);
#else
if (x > 0 .0 && x < 1 .0 )
return (MAXNUM);
#endif
if (x < -1 .0 )
return (0 .0 );
#ifdef INFINITIES
if (x > -1 .0 && x < 0 .0 )
return (INFINITY);
#else
if (x > -1 .0 && x < 0 .0 )
return (MAXNUM);
#endif
}
if (x >= MAXNUM) {
#if INFINITIES
if (y > 0 .0 )
return (INFINITY);
#else
if (y > 0 .0 )
return (MAXNUM);
#endif
return (0 .0 );
}
/* Set iyflg to 1 if y is an integer. */
iyflg = 0 ;
w = floor(y);
if (w == y)
iyflg = 1 ;
/* Test for odd integer y. */
yoddint = 0 ;
if (iyflg) {
ya = fabs(y);
ya = floor(0 .5 * ya);
yb = 0 .5 * fabs(w);
if (ya != yb)
yoddint = 1 ;
}
if (x <= -MAXNUM) {
if (y > 0 .0 ) {
#ifdef INFINITIES
if (yoddint)
return (-INFINITY);
return (INFINITY);
#else
if (yoddint)
return (-MAXNUM);
return (MAXNUM);
#endif
}
if (y < 0 .0 ) {
#ifdef MINUSZERO
if (yoddint)
return (NEGZERO);
#endif
return (0 .0 );
}
}
nflg = 0 ; /* flag = 1 if x<0 raised to integer power */
if (x <= 0 .0 ) {
if (x == 0 .0 ) {
if (y < 0 .0 ) {
#ifdef MINUSZERO
if (signbit(x) && yoddint)
return (-INFINITY);
#endif
#ifdef INFINITIES
return (INFINITY);
#else
return (MAXNUM);
#endif
}
if (y > 0 .0 ) {
#ifdef MINUSZERO
if (signbit(x) && yoddint)
return (NEGZERO);
#endif
return (0 .0 );
}
return (1 .0 );
} else {
if (iyflg == 0 ) { /* noninteger power of negative number */
mtherr(fname, DOMAIN);
#ifdef NANS
return (NAN);
#else
return (0 .0 L);
#endif
}
nflg = 1 ;
}
}
/* Integer power of an integer. */
if (iyflg) {
i = w;
w = floor(x);
if ((w == x) && (fabs(y) < 32768 .0 )) {
w = powi(x, (int )y);
return (w);
}
}
if (nflg)
x = fabs(x);
/* For results close to 1, use a series expansion. */
w = x - 1 .0 ;
aw = fabs(w);
ay = fabs(y);
wy = w * y;
ya = fabs(wy);
if ((aw <= 1 .0 e-3 && ay <= 1 .0 ) || (ya <= 1 .0 e-3 && ay >= 1 .0 )) {
z = (((((w * (y - 5 .) / 720 . + 1 . / 120 .) * w * (y - 4 .) + 1 . / 24 .) * w *
(y - 3 .) +
1 . / 6 .) *
w * (y - 2 .) +
0 .5 ) *
w * (y - 1 .)) *
wy +
wy + 1 .;
goto done;
}
/* These are probably too much trouble. */
#if 0
w = y * log(x);
if (aw > 1 .0 e-3 && fabs(w) < 1 .0 e-3 )
{
z = ((((((
w/7 . + 1 .)*w/6 . + 1 .)*w/5 . + 1 .)*w/4 . + 1 .)*w/3 . + 1 .)*w/2 . + 1 .)*w + 1 .;
goto done;
}
if (ya <= 1 .0 e-3 && aw <= 1 .0 e-4 )
{
z = (((((
wy*1 ./720 .
+ (-w*1 ./48 . + 1 ./120 .) )*wy
+ ((w*17 ./144 . - 1 ./12 .)*w + 1 ./24 .) )*wy
+ (((-w*5 ./16 . + 7 ./24 .)*w - 1 ./4 .)*w + 1 ./6 .) )*wy
+ ((((w*137 ./360 . - 5 ./12 .)*w + 11 ./24 .)*w - 1 ./2 .)*w + 1 ./2 .) )*wy
+ (((((-w*1 ./6 . + 1 ./5 .)*w - 1 ./4 )*w + 1 ./3 .)*w -1 ./2 .)*w ) )*wy
+ wy + 1 .0 ;
goto done;
}
#endif
/* separate significand from exponent */
x = frexp(x, &e);
#if 0
/* For debugging, check for gross overflow. */
if ( (e * y) > (MEXP + 1024 ) )
goto overflow;
#endif
/* Find significand of x in antilog table A[]. */
i = 1 ;
if (x <= douba(9 ))
i = 9 ;
if (x <= douba(i + 4 ))
i += 4 ;
if (x <= douba(i + 2 ))
i += 2 ;
if (x >= douba(1 ))
i = -1 ;
i += 1 ;
/* Find (x - A[i])/A[i]
* in order to compute log(x/A[i]):
*
* log(x) = log( a x/a ) = log(a) + log(x/a)
*
* log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a
*/
x -= douba(i);
x -= doubb(i / 2 );
x /= douba(i);
/* rational approximation for log(1+v):
*
* log(1+v) = v - v**2/2 + v**3 P(v) / Q(v)
*/
z = x * x;
w = x * (z * polevl(x, P, 3 ) / p1evl(x, Q, 4 ));
w = w - ldexp(z, -1 ); /* w - 0.5 * z */
/* Convert to base 2 logarithm:
* multiply by log2(e)
*/
w = w + LOG2EA * w;
/* Note x was not yet added in
* to above rational approximation,
* so do it now, while multiplying
* by log2(e).
*/
z = w + LOG2EA * x;
z = z + x;
/* Compute exponent term of the base 2 logarithm. */
w = -i;
w = ldexp(w, -4 ); /* divide by 16 */
w += e;
/* Now base 2 log of x is w + z. */
/* Multiply base 2 log by y, in extended precision. */
/* separate y into large part ya
* and small part yb less than 1/16
*/
ya = reduc(y);
yb = y - ya;
F = z * y + w * yb;
Fa = reduc(F);
Fb = F - Fa;
G = Fa + w * ya;
Ga = reduc(G);
Gb = G - Ga;
H = Fb + Gb;
Ha = reduc(H);
w = ldexp(Ga + Ha, 4 );
/* Test the power of 2 for overflow */
if (w > MEXP) {
#ifndef INFINITIES
mtherr(fname, OVERFLOW);
#endif
#ifdef INFINITIES
if (nflg && yoddint)
return (-INFINITY);
return (INFINITY);
#else
if (nflg && yoddint)
return (-MAXNUM);
return (MAXNUM);
#endif
}
if (w < (MNEXP - 1 )) {
#ifndef DENORMAL
mtherr(fname, UNDERFLOW);
#endif
#ifdef MINUSZERO
if (nflg && yoddint)
return (NEGZERO);
#endif
return (0 .0 );
}
e = w;
Hb = H - Ha;
if (Hb > 0 .0 ) {
e += 1 ;
Hb -= 0 .0625 ;
}
/* Now the product y * log2(x) = Hb + e/16.0.
*
* Compute base 2 exponential of Hb,
* where -0.0625 <= Hb <= 0.
*/
z = Hb * polevl(Hb, R, 6 ); /* z = 2**Hb - 1 */
/* Express e/16 as an integer plus a negative number of 16ths.
* Find lookup table entry for the fractional power of 2.
*/
if (e < 0 )
i = 0 ;
else
i = 1 ;
i = e / 16 + i;
e = 16 * i - e;
w = douba(e);
z = w + w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */
z = ldexp(z, i); /* multiply by integer power of 2 */
done:
/* Negate if odd integer power of negative number */
if (nflg && yoddint) {
#ifdef MINUSZERO
if (z == 0 .0 )
z = NEGZERO;
else
#endif
z = -z;
}
return (z);
}
/* Find a multiple of 1/16 that is within 1/16 of x. */
static double reduc(x) double x;
{
double t;
t = ldexp(x, 4 );
t = floor(t);
t = ldexp(t, -4 );
return (t);
}
Messung V0.5 in Prozent C=94 H=85 G=89
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-09)
¤
*© Formatika GbR, Deutschland