#include "math.h"
#include "math_private.h"
static const volatile float vzero = 0;
static const float
zero= 0,
half= 0.5,
one = 1,
pi = 3.1415927410e+00,
a0 = 7.72156641e-02,
a1 = 3.22467119e-01,
a2 = 6.73484802e-02,
a3 = 2.06395667e-02,
a4 = 6.98275631e-03,
a5 = 4.11768444e-03,
tc = 1.46163213e+00,
tf = -1.21486291e-01,
t0 = -2.94064460e-11,
t1 = -2.35939837e-08,
t2 = 4.83836412e-01,
t3 = -1.47586212e-01,
t4 = 6.46013096e-02,
t5 = -3.28450352e-02,
t6 = 1.86483748e-02,
t7 = -9.89206228e-03,
u0 = -7.72156641e-02,
u1 = 7.36789703e-01,
u2 = 4.95649040e-01,
v1 = 1.10958421e+00,
v2 = 2.10598111e-01,
v3 = -1.02995494e-02,
s0 = -7.72156641e-02,
s1 = 2.69987404e-01,
s2 = 1.42851010e-01,
s3 = 1.19389519e-02,
r1 = 6.79650068e-01,
r2 = 1.16058730e-01,
r3 = 3.75673687e-03,
w0 = 4.18938547e-01,
w1 = 8.33332464e-02,
w2 = -2.76129087e-03;
static float
sin_pif(float x)
{
volatile float vz;
float y,z;
int n;
y = -x;
vz = y+0x1p23F;
z = vz-0x1p23F;
if (z == y)
return zero;
vz = y+0x1p21F;
GET_FLOAT_WORD(n,vz);
z = vz-0x1p21F;
if (z > y) {
z -= 0.25F;
n--;
}
n &= 7;
y = y - z + n * 0.25F;
switch (n) {
case 0: y = __kernel_sindf(pi*y); break;
case 1:
case 2: y = __kernel_cosdf(pi*((float)0.5-y)); break;
case 3:
case 4: y = __kernel_sindf(pi*(one-y)); break;
case 5:
case 6: y = -__kernel_cosdf(pi*(y-(float)1.5)); break;
default: y = __kernel_sindf(pi*(y-(float)2.0)); break;
}
return -y;
}
float
lgammaf_r(float x, int *signgamp)
{
float nadj,p,p1,p2,q,r,t,w,y,z;
int32_t hx;
int i,ix;
GET_FLOAT_WORD(hx,x);
*signgamp = 1;
ix = hx&0x7fffffff;
if(ix>=0x7f800000) return x*x;
*signgamp = 1-2*((uint32_t)hx>>31);
if(ix<0x32000000) {
if(ix==0)
return one/vzero;
return -logf(fabsf(x));
}
if(hx<0) {
*signgamp = 1;
if(ix>=0x4b000000)
return one/vzero;
t = sin_pif(x);
if(t==zero) return one/vzero;
nadj = logf(pi/fabsf(t*x));
if(t<zero) *signgamp = -1;
x = -x;
}
if (ix==0x3f800000||ix==0x40000000) r = 0;
else if(ix<0x40000000) {
if(ix<=0x3f666666) {
r = -logf(x);
if(ix>=0x3f3b4a20) {y = one-x; i= 0;}
else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;}
else {y = x; i=2;}
} else {
r = zero;
if(ix>=0x3fdda618) {y=2-x;i=0;}
else if(ix>=0x3F9da620) {y=x-tc;i=1;}
else {y=x-one;i=2;}
}
switch(i) {
case 0:
z = y*y;
p1 = a0+z*(a2+z*a4);
p2 = z*(a1+z*(a3+z*a5));
p = y*p1+p2;
r += p-y/2; break;
case 1:
p = t0+y*t1+y*y*(t2+y*(t3+y*(t4+y*(t5+y*(t6+y*t7)))));
r += tf + p; break;
case 2:
p1 = y*(u0+y*(u1+y*u2));
p2 = one+y*(v1+y*(v2+y*v3));
r += p1/p2-y/2;
}
}
else if(ix<0x41000000) {
i = x;
y = x-i;
p = y*(s0+y*(s1+y*(s2+y*s3)));
q = one+y*(r1+y*(r2+y*r3));
r = y/2+p/q;
z = one;
switch(i) {
case 7: z *= (y+6);
case 6: z *= (y+5);
case 5: z *= (y+4);
case 4: z *= (y+3);
case 3: z *= (y+2);
r += logf(z); break;
}
} else if (ix < 0x4d000000) {
t = logf(x);
z = one/x;
y = z*z;
w = w0+z*(w1+y*w2);
r = (x-half)*(t-one)+w;
} else
r = x*(logf(x)-one);
if(hx<0) r = nadj - r;
return r;
}