src/libm/e_pow.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 21 Apr 2016 03:16:44 -0400
changeset 11729 d1ce8396c356
parent 11711 8a982ed61896
child 12420 4a6c91d9cc33
permissions -rw-r--r--
Initial shot at a renderer target for Apple's Metal API.

This isn't complete, but is enough to run testsprite2. It's currently
Mac-only; with a little work to figure out how to properly glue in a Metal
layer to a UIView, this will likely work on iOS, too.

This is only wired up to the configure script right now, and disabled by
default. CMake and Xcode still need their bits filled in as appropriate.
slouken@2756
     1
/*
slouken@2756
     2
 * ====================================================
slouken@2756
     3
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
slouken@2756
     4
 *
slouken@2756
     5
 * Developed at SunPro, a Sun Microsystems, Inc. business.
slouken@2756
     6
 * Permission to use, copy, modify, and distribute this
slouken@2756
     7
 * software is freely granted, provided that this notice
slouken@2756
     8
 * is preserved.
slouken@2756
     9
 * ====================================================
slouken@2756
    10
 */
slouken@2756
    11
slouken@2756
    12
/* __ieee754_pow(x,y) return x**y
slouken@2756
    13
 *
slouken@2756
    14
 *		      n
slouken@2756
    15
 * Method:  Let x =  2   * (1+f)
slouken@2756
    16
 *	1. Compute and return log2(x) in two pieces:
slouken@2756
    17
 *		log2(x) = w1 + w2,
slouken@2756
    18
 *	   where w1 has 53-24 = 29 bit trailing zeros.
slouken@2756
    19
 *	2. Perform y*log2(x) = n+y' by simulating muti-precision
slouken@2756
    20
 *	   arithmetic, where |y'|<=0.5.
slouken@2756
    21
 *	3. Return x**y = 2**n*exp(y'*log2)
slouken@2756
    22
 *
slouken@2756
    23
 * Special cases:
slouken@11683
    24
 *	1.  +-1 ** anything  is 1.0
slouken@11683
    25
 *	2.  +-1 ** +-INF     is 1.0
slouken@11683
    26
 *	3.  (anything) ** 0  is 1
slouken@11683
    27
 *	4.  (anything) ** 1  is itself
slouken@11683
    28
 *	5.  (anything) ** NAN is NAN
slouken@11683
    29
 *	6.  NAN ** (anything except 0) is NAN
slouken@11683
    30
 *	7.  +-(|x| > 1) **  +INF is +INF
slouken@11683
    31
 *	8.  +-(|x| > 1) **  -INF is +0
slouken@11683
    32
 *	9.  +-(|x| < 1) **  +INF is +0
slouken@11683
    33
 *	10  +-(|x| < 1) **  -INF is +INF
slouken@11683
    34
 *	11. +0 ** (+anything except 0, NAN)               is +0
slouken@11683
    35
 *	12. -0 ** (+anything except 0, NAN, odd integer)  is +0
slouken@11683
    36
 *	13. +0 ** (-anything except 0, NAN)               is +INF
slouken@11683
    37
 *	14. -0 ** (-anything except 0, NAN, odd integer)  is +INF
slouken@11683
    38
 *	15. -0 ** (odd integer) = -( +0 ** (odd integer) )
slouken@11683
    39
 *	16. +INF ** (+anything except 0,NAN) is +INF
slouken@11683
    40
 *	17. +INF ** (-anything except 0,NAN) is +0
slouken@11683
    41
 *	18. -INF ** (anything)  = -0 ** (-anything)
slouken@11683
    42
 *	19. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
slouken@11683
    43
 *	20. (-anything except 0 and inf) ** (non-integer) is NAN
slouken@2756
    44
 *
slouken@2756
    45
 * Accuracy:
slouken@2756
    46
 *	pow(x,y) returns x**y nearly rounded. In particular
slouken@2756
    47
 *			pow(integer,integer)
slouken@2756
    48
 *	always returns the correct integer provided it is
slouken@2756
    49
 *	representable.
slouken@2756
    50
 *
slouken@2756
    51
 * Constants :
slouken@2756
    52
 * The hexadecimal values are the intended ones for the following
slouken@2756
    53
 * constants. The decimal values may be used, provided that the
slouken@2756
    54
 * compiler will convert from decimal to binary accurately enough
slouken@2756
    55
 * to produce the hexadecimal values shown.
slouken@2756
    56
 */
slouken@2756
    57
slouken@6044
    58
#include "math_libm.h"
slouken@2756
    59
#include "math_private.h"
slouken@2756
    60
slouken@11711
    61
#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */
slouken@11711
    62
/* C4756: overflow in constant arithmetic */
slouken@11711
    63
#pragma warning ( disable : 4756 )
slouken@11711
    64
#endif
slouken@11711
    65
slouken@11683
    66
static const double
slouken@11683
    67
bp[] = {1.0, 1.5,},
slouken@11683
    68
dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
slouken@11683
    69
dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
slouken@11683
    70
zero    =  0.0,
slouken@11683
    71
one	=  1.0,
slouken@11683
    72
two	=  2.0,
slouken@11683
    73
two53	=  9007199254740992.0,	/* 0x43400000, 0x00000000 */
slouken@11683
    74
huge	=  1.0e300,
slouken@11683
    75
tiny    =  1.0e-300,
slouken@11683
    76
	/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
slouken@11683
    77
L1  =  5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
slouken@11683
    78
L2  =  4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
slouken@11683
    79
L3  =  3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
slouken@11683
    80
L4  =  2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
slouken@11683
    81
L5  =  2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
slouken@11683
    82
L6  =  2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
slouken@11683
    83
P1   =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
slouken@11683
    84
P2   = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
slouken@11683
    85
P3   =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
slouken@11683
    86
P4   = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
slouken@11683
    87
P5   =  4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
slouken@11683
    88
lg2  =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
slouken@11683
    89
lg2_h  =  6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
slouken@11683
    90
lg2_l  = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
slouken@11683
    91
ovt =  8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
slouken@11683
    92
cp    =  9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
slouken@11683
    93
cp_h  =  9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
slouken@11683
    94
cp_l  = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
slouken@11683
    95
ivln2    =  1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
slouken@11683
    96
ivln2_h  =  1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
slouken@11683
    97
ivln2_l  =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
slouken@11683
    98
slouken@11683
    99
double attribute_hidden __ieee754_pow(double x, double y)
slouken@11683
   100
{
slouken@11683
   101
	double z,ax,z_h,z_l,p_h,p_l;
slouken@11683
   102
	double y1,t1,t2,r,s,t,u,v,w;
slouken@11683
   103
	int32_t i,j,k,yisint,n;
slouken@11683
   104
	int32_t hx,hy,ix,iy;
slouken@11683
   105
	u_int32_t lx,ly;
slouken@11683
   106
slouken@11683
   107
	EXTRACT_WORDS(hx,lx,x);
slouken@11683
   108
    /* x==1: 1**y = 1 (even if y is NaN) */
slouken@11683
   109
	if (hx==0x3ff00000 && lx==0) {
slouken@11683
   110
		return x;
slouken@11683
   111
	}
slouken@11683
   112
	ix = hx&0x7fffffff;
slouken@11683
   113
slouken@11683
   114
	EXTRACT_WORDS(hy,ly,y);
slouken@11683
   115
	iy = hy&0x7fffffff;
slouken@11683
   116
slouken@11683
   117
    /* y==zero: x**0 = 1 */
slouken@11683
   118
	if((iy|ly)==0) return one;
slouken@11683
   119
slouken@11683
   120
    /* +-NaN return x+y */
slouken@11683
   121
	if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
slouken@11683
   122
	   iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
slouken@11683
   123
		return x+y;
slouken@11683
   124
slouken@11683
   125
    /* determine if y is an odd int when x < 0
slouken@11683
   126
     * yisint = 0	... y is not an integer
slouken@11683
   127
     * yisint = 1	... y is an odd int
slouken@11683
   128
     * yisint = 2	... y is an even int
slouken@11683
   129
     */
slouken@11683
   130
	yisint  = 0;
slouken@11683
   131
	if(hx<0) {
slouken@11683
   132
	    if(iy>=0x43400000) yisint = 2; /* even integer y */
slouken@11683
   133
	    else if(iy>=0x3ff00000) {
slouken@11683
   134
		k = (iy>>20)-0x3ff;	   /* exponent */
slouken@11683
   135
		if(k>20) {
slouken@11683
   136
		    j = ly>>(52-k);
slouken@11683
   137
		    if((j<<(52-k))==ly) yisint = 2-(j&1);
slouken@11683
   138
		} else if(ly==0) {
slouken@11683
   139
		    j = iy>>(20-k);
slouken@11683
   140
		    if((j<<(20-k))==iy) yisint = 2-(j&1);
slouken@11683
   141
		}
slouken@11683
   142
	    }
slouken@11683
   143
	}
slouken@11683
   144
slouken@11683
   145
    /* special value of y */
slouken@11683
   146
	if(ly==0) {
slouken@11683
   147
	    if (iy==0x7ff00000) {       /* y is +-inf */
slouken@11683
   148
	        if (((ix-0x3ff00000)|lx)==0)
slouken@11683
   149
		    return one;	        /* +-1**+-inf is 1 (yes, weird rule) */
slouken@11683
   150
	        if (ix >= 0x3ff00000)   /* (|x|>1)**+-inf = inf,0 */
slouken@11683
   151
		    return (hy>=0) ? y : zero;
slouken@11683
   152
	        /* (|x|<1)**-,+inf = inf,0 */
slouken@11683
   153
		return (hy<0) ? -y : zero;
slouken@11683
   154
	    }
slouken@11683
   155
	    if(iy==0x3ff00000) {	/* y is  +-1 */
slouken@11683
   156
		if(hy<0) return one/x; else return x;
slouken@11683
   157
	    }
slouken@11683
   158
	    if(hy==0x40000000) return x*x; /* y is  2 */
slouken@11683
   159
	    if(hy==0x3fe00000) {	/* y is  0.5 */
slouken@11683
   160
		if(hx>=0)	/* x >= +0 */
slouken@11683
   161
		    return __ieee754_sqrt(x);
slouken@11683
   162
	    }
slouken@11683
   163
	}
slouken@11683
   164
slouken@11683
   165
	ax   = fabs(x);
slouken@11683
   166
    /* special value of x */
slouken@11683
   167
	if(lx==0) {
slouken@11683
   168
	    if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
slouken@11683
   169
		z = ax;			/*x is +-0,+-inf,+-1*/
slouken@11683
   170
		if(hy<0) z = one/z;	/* z = (1/|x|) */
slouken@11683
   171
		if(hx<0) {
slouken@11683
   172
		    if(((ix-0x3ff00000)|yisint)==0) {
slouken@11683
   173
			z = (z-z)/(z-z); /* (-1)**non-int is NaN */
slouken@11683
   174
		    } else if(yisint==1)
slouken@11683
   175
			z = -z;		/* (x<0)**odd = -(|x|**odd) */
slouken@11683
   176
		}
slouken@11683
   177
		return z;
slouken@11683
   178
	    }
slouken@11683
   179
	}
slouken@11683
   180
slouken@11683
   181
    /* (x<0)**(non-int) is NaN */
slouken@11683
   182
	if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x);
slouken@11683
   183
slouken@11683
   184
    /* |y| is huge */
slouken@11683
   185
	if(iy>0x41e00000) { /* if |y| > 2**31 */
slouken@11683
   186
	    if(iy>0x43f00000){	/* if |y| > 2**64, must o/uflow */
slouken@11683
   187
		if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
slouken@11683
   188
		if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
slouken@11683
   189
	    }
slouken@11683
   190
	/* over/underflow if x is not close to one */
slouken@11683
   191
	    if(ix<0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
slouken@11683
   192
	    if(ix>0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
slouken@11683
   193
	/* now |1-x| is tiny <= 2**-20, suffice to compute
slouken@11683
   194
	   log(x) by x-x^2/2+x^3/3-x^4/4 */
slouken@11683
   195
	    t = x-1;		/* t has 20 trailing zeros */
slouken@11683
   196
	    w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
slouken@11683
   197
	    u = ivln2_h*t;	/* ivln2_h has 21 sig. bits */
slouken@11683
   198
	    v = t*ivln2_l-w*ivln2;
slouken@11683
   199
	    t1 = u+v;
slouken@11683
   200
	    SET_LOW_WORD(t1,0);
slouken@11683
   201
	    t2 = v-(t1-u);
slouken@11683
   202
	} else {
slouken@11683
   203
	    double s2,s_h,s_l,t_h,t_l;
slouken@11683
   204
	    n = 0;
slouken@11683
   205
	/* take care subnormal number */
slouken@11683
   206
	    if(ix<0x00100000)
slouken@11683
   207
		{ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); }
slouken@11683
   208
	    n  += ((ix)>>20)-0x3ff;
slouken@11683
   209
	    j  = ix&0x000fffff;
slouken@11683
   210
	/* determine interval */
slouken@11683
   211
	    ix = j|0x3ff00000;		/* normalize ix */
slouken@11683
   212
	    if(j<=0x3988E) k=0;		/* |x|<sqrt(3/2) */
slouken@11683
   213
	    else if(j<0xBB67A) k=1;	/* |x|<sqrt(3)   */
slouken@11683
   214
	    else {k=0;n+=1;ix -= 0x00100000;}
slouken@11683
   215
	    SET_HIGH_WORD(ax,ix);
slouken@11683
   216
slouken@11683
   217
	/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
slouken@11683
   218
	    u = ax-bp[k];		/* bp[0]=1.0, bp[1]=1.5 */
slouken@11683
   219
	    v = one/(ax+bp[k]);
slouken@11683
   220
	    s = u*v;
slouken@11683
   221
	    s_h = s;
slouken@11683
   222
	    SET_LOW_WORD(s_h,0);
slouken@11683
   223
	/* t_h=ax+bp[k] High */
slouken@11683
   224
	    t_h = zero;
slouken@11683
   225
	    SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18));
slouken@11683
   226
	    t_l = ax - (t_h-bp[k]);
slouken@11683
   227
	    s_l = v*((u-s_h*t_h)-s_h*t_l);
slouken@11683
   228
	/* compute log(ax) */
slouken@11683
   229
	    s2 = s*s;
slouken@11683
   230
	    r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
slouken@11683
   231
	    r += s_l*(s_h+s);
slouken@11683
   232
	    s2  = s_h*s_h;
slouken@11683
   233
	    t_h = 3.0+s2+r;
slouken@11683
   234
	    SET_LOW_WORD(t_h,0);
slouken@11683
   235
	    t_l = r-((t_h-3.0)-s2);
slouken@11683
   236
	/* u+v = s*(1+...) */
slouken@11683
   237
	    u = s_h*t_h;
slouken@11683
   238
	    v = s_l*t_h+t_l*s;
slouken@11683
   239
	/* 2/(3log2)*(s+...) */
slouken@11683
   240
	    p_h = u+v;
slouken@11683
   241
	    SET_LOW_WORD(p_h,0);
slouken@11683
   242
	    p_l = v-(p_h-u);
slouken@11683
   243
	    z_h = cp_h*p_h;		/* cp_h+cp_l = 2/(3*log2) */
slouken@11683
   244
	    z_l = cp_l*p_h+p_l*cp+dp_l[k];
slouken@11683
   245
	/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
slouken@11683
   246
	    t = (double)n;
slouken@11683
   247
	    t1 = (((z_h+z_l)+dp_h[k])+t);
slouken@11683
   248
	    SET_LOW_WORD(t1,0);
slouken@11683
   249
	    t2 = z_l-(((t1-t)-dp_h[k])-z_h);
slouken@11683
   250
	}
slouken@11683
   251
slouken@11683
   252
	s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
slouken@11683
   253
	if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0)
slouken@11683
   254
	    s = -one;/* (-ve)**(odd int) */
slouken@11683
   255
slouken@11683
   256
    /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
slouken@11683
   257
	y1  = y;
slouken@11683
   258
	SET_LOW_WORD(y1,0);
slouken@11683
   259
	p_l = (y-y1)*t1+y*t2;
slouken@11683
   260
	p_h = y1*t1;
slouken@11683
   261
	z = p_l+p_h;
slouken@11683
   262
	EXTRACT_WORDS(j,i,z);
slouken@11683
   263
	if (j>=0x40900000) {				/* z >= 1024 */
slouken@11683
   264
	    if(((j-0x40900000)|i)!=0)			/* if z > 1024 */
slouken@11683
   265
		return s*huge*huge;			/* overflow */
slouken@11683
   266
	    else {
slouken@11683
   267
		if(p_l+ovt>z-p_h) return s*huge*huge;	/* overflow */
slouken@11683
   268
	    }
slouken@11683
   269
	} else if((j&0x7fffffff)>=0x4090cc00 ) {	/* z <= -1075 */
slouken@11683
   270
	    if(((j-0xc090cc00)|i)!=0) 		/* z < -1075 */
slouken@11683
   271
		return s*tiny*tiny;		/* underflow */
slouken@11683
   272
	    else {
slouken@11683
   273
		if(p_l<=z-p_h) return s*tiny*tiny;	/* underflow */
slouken@11683
   274
	    }
slouken@11683
   275
	}
slouken@11683
   276
    /*
slouken@11683
   277
     * compute 2**(p_h+p_l)
slouken@11683
   278
     */
slouken@11683
   279
	i = j&0x7fffffff;
slouken@11683
   280
	k = (i>>20)-0x3ff;
slouken@11683
   281
	n = 0;
slouken@11683
   282
	if(i>0x3fe00000) {		/* if |z| > 0.5, set n = [z+0.5] */
slouken@11683
   283
	    n = j+(0x00100000>>(k+1));
slouken@11683
   284
	    k = ((n&0x7fffffff)>>20)-0x3ff;	/* new k for n */
slouken@11683
   285
	    t = zero;
slouken@11683
   286
	    SET_HIGH_WORD(t,n&~(0x000fffff>>k));
slouken@11683
   287
	    n = ((n&0x000fffff)|0x00100000)>>(20-k);
slouken@11683
   288
	    if(j<0) n = -n;
slouken@11683
   289
	    p_h -= t;
slouken@11683
   290
	}
slouken@11683
   291
	t = p_l+p_h;
slouken@11683
   292
	SET_LOW_WORD(t,0);
slouken@11683
   293
	u = t*lg2_h;
slouken@11683
   294
	v = (p_l-(t-p_h))*lg2+t*lg2_l;
slouken@11683
   295
	z = u+v;
slouken@11683
   296
	w = v-(z-u);
slouken@11683
   297
	t  = z*z;
slouken@11683
   298
	t1  = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
slouken@11683
   299
	r  = (z*t1)/(t1-two)-(w+z*w);
slouken@11683
   300
	z  = one-(r-z);
slouken@11683
   301
	GET_HIGH_WORD(j,z);
slouken@11683
   302
	j += (n<<20);
slouken@11683
   303
	if((j>>20)<=0) z = scalbn(z,n);	/* subnormal output */
slouken@11683
   304
	else SET_HIGH_WORD(z,j);
slouken@11683
   305
	return s*z;
slouken@11683
   306
}
slouken@11683
   307
slouken@11683
   308
/*
slouken@11683
   309
 * wrapper pow(x,y) return x**y
slouken@11683
   310
 */
slouken@11683
   311
#ifndef _IEEE_LIBM
slouken@11683
   312
double pow(double x, double y)
slouken@11683
   313
{
slouken@11683
   314
	double z = __ieee754_pow(x, y);
slouken@11683
   315
	if (_LIB_VERSION == _IEEE_|| isnan(y))
slouken@11683
   316
		return z;
slouken@11683
   317
	if (isnan(x)) {
slouken@11683
   318
		if (y == 0.0)
slouken@11683
   319
			return __kernel_standard(x, y, 42); /* pow(NaN,0.0) */
slouken@11683
   320
		return z;
slouken@11683
   321
	}
slouken@11683
   322
	if (x == 0.0) {
slouken@11683
   323
		if (y == 0.0)
slouken@11683
   324
	    		return __kernel_standard(x, y, 20); /* pow(0.0,0.0) */
slouken@11683
   325
		if (isfinite(y) && y < 0.0)
slouken@11683
   326
			return __kernel_standard(x,y,23); /* pow(0.0,negative) */
slouken@11683
   327
		return z;
slouken@11683
   328
	}
slouken@11683
   329
	if (!isfinite(z)) {
slouken@11683
   330
		if (isfinite(x) && isfinite(y)) {
slouken@11683
   331
			if (isnan(z))
slouken@11683
   332
				return __kernel_standard(x, y, 24); /* pow neg**non-int */
slouken@11683
   333
			return __kernel_standard(x, y, 21); /* pow overflow */
slouken@11683
   334
		}
slouken@11683
   335
	}
slouken@11683
   336
	if (z == 0.0 && isfinite(x) && isfinite(y))
slouken@11683
   337
		return __kernel_standard(x, y, 22); /* pow underflow */
slouken@11683
   338
	return z;
slouken@11683
   339
}
slouken@2756
   340
#else
slouken@11683
   341
strong_alias(__ieee754_pow, pow)
slouken@2756
   342
#endif
slouken@11683
   343
libm_hidden_def(pow)