#include "libm.h"
static const float
pio2_hi = 1.5707962513e+00,
pio2_lo = 7.5497894159e-08,
pS0 = 1.66666672e-01,
pS1 = -5.11644611e-02,
pS2 = -1.21124933e-02,
pS3 = -3.58742251e-03,
qS1 = -7.56982703e-01;
static float R(float z)
{
float_t p, q;
p = z*(pS0+z*(pS1+z*(pS2+z*pS3)));
q = 1.0f+z*qS1;
return p/q;
}
float __cdecl acosf(float x)
{
float z,w,s,c,df;
uint32_t hx,ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix >= 0x3f800000) {
if (ix == 0x3f800000) {
if (hx >> 31)
return M_PI;
return 0;
}
if (isnan(x)) return x;
return math_error(_DOMAIN, "acosf", x, 0, 0 / (x - x));
}
if (ix < 0x3f000000) {
if (ix <= 0x32800000)
return M_PI_2;
return pio2_hi - (x - (pio2_lo-x*R(x*x)));
}
if (hx >> 31) {
z = (1+x)*0.5f;
s = sqrtf(z);
return 2*(pio2_hi - (s + (R(z)*s-pio2_lo)));
}
z = (1-x)*0.5f;
s = sqrtf(z);
GET_FLOAT_WORD(hx,s);
SET_FLOAT_WORD(df,hx&0xfffff000);
c = (z-df*df)/(s+df);
w = R(z)*s+c;
return 2*(df+w);
}