#include "math.h"
#include "math_private.h"
#define _CC (0x1p12F + 1)
#define _ROOT sqrtf
volatile static const float tiny = 1.e-30;
static const float half = 0.5f, one = 1.f;
static const float
invpihi = 3.18309873e-01f,
invpilo = 1.28412765e-08f;
static inline float
__r(float xs)
{
static const float
R0 = 5.30516468e-02f,
R1 = -3.80413085e-02f,
R2 = 1.74116367e-03f,
S1 = -1.16706085e+00f,
S2 = 2.90115148e-01f;
float r, s;
r = R0 + (R1 + R2 * xs) * xs;
s = 1 + (S1 + S2 * xs) * xs;
return (xs * (r / s));
}
float
asinpif(float x)
{
float ax, hi, lo, xh, xl, y, zh, zl;
uint32_t hx, ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix > 0x3f800000)
return ((x - x) / (x - x));
SET_FLOAT_WORD(ax, ix);
if (ix <= 0x3f000000) {
if (ix < 0x39800000) {
if (ix < 0x03800000) {
if (ix == 0)
return (x);
ax *= 0x1p25f;
_XMUL(ax, 0, invpihi, invpilo, hi, lo);
y = (hi + lo) * 0x1p-25f;
} else {
_XMUL(ax, 0, invpihi, invpilo, hi, lo);
y = hi + lo;
}
} else {
y = __r(ax * ax);
_XADD(invpihi, invpilo, y, 0, xh, xl);
_XMUL(ax, 0, xh, xl, hi, lo);
y = hi + lo;
}
} else if (ix < 0x3f800000) {
y = 1 - ax;
x = __r(y / 2);
_XADD(invpihi, invpilo, x, 0, xh, xl);
_SQRT(2 * y, zh, zl);
_XMUL(xh, xl, zh, zl, hi, lo);
_XADD(half, 0, -hi, -lo, y, x);
} else
y = half;
return ((hx & 0x80000000) ? -y : y);
}
float
acospif(float x)
{
float ax, hi, lo, xh, xl, y, zh, zl;
uint32_t hx, ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix > 0x3f800000)
return ((x - x) / (x - x));
if (ix <= 0x3f000000) {
if (ix <= 0x3a800000) {
y = (ix == 0) ? half : ((ix < 0x33800000) ?
half - tiny : half - x * invpihi);
} else {
y = __r(x * x);
_XADD(invpihi, invpilo, y, 0, xh, xl);
_XMUL(x, 0, xh, xl, hi, lo);
_XADD(half, 0, -hi, -lo, y, ax);
}
} else if (ix < 0x3f800000) {
SET_FLOAT_WORD(ax, ix);
y = 1 - ax;
ax = __r(y / 2);
_XADD(invpihi, invpilo, ax, 0, xh, xl);
_SQRT(2 * y, zh, zl);
_XMUL(xh, xl, zh, zl, hi, lo);
if (hx & 0x80000000)
_XADD(one, 0, -hi, -lo, y, ax);
else
y = hi + lo;
} else
y = hx & 0x80000000 ? 1 : 0;
return (y);
}