#include <float.h>
#ifdef __i386__
#include <ieeefp.h>
#endif
#include "fpmath.h"
#include "math.h"
#include "math_private.h"
#include "k_expl.h"
#if LDBL_MAX_EXP != 0x4000
#error "Unsupported long double format"
#endif
#define BIAS (LDBL_MAX_EXP - 1)
static const volatile long double huge = 0x1p10000L, tiny = 0x1p-10000L;
#if LDBL_MANT_DIG == 64
static const union IEEEl2bits
C4u = LD80C(0xaaaaaaaaaaaaac78, -5, 4.16666666666666682297e-2L);
#define C4 C4u.e
static const double
C2 = 0.5,
C6 = 1.3888888888888616e-3,
C8 = 2.4801587301767953e-5,
C10 = 2.7557319163300398e-7,
C12 = 2.0876768371393075e-9,
C14 = 1.1469537039374480e-11,
C16 = 4.8473490896852041e-14;
#elif LDBL_MANT_DIG == 113
static const long double
C4 = 4.16666666666666666666666666666666225e-2L,
C6 = 1.38888888888888888888888888889434831e-3L,
C8 = 2.48015873015873015873015871870962089e-5L,
C10 = 2.75573192239858906525574318600800201e-7L,
C12 = 2.08767569878680989791444691755468269e-9L,
C14= 1.14707455977297247387801189650495351e-11L,
C16 = 4.77947733238737883626416876486279985e-14L;
static const double
C2 = 0.5,
C18 = 1.5619206968597871e-16,
C20 = 4.1103176218528049e-19,
C22 = 8.8967926401641701e-22,
C24 = 1.6116681626523904e-24,
C26 = 2.5022374732804632e-27;
#else
#error "Unsupported long double format"
#endif
static const float
o_threshold = 1.13572168e4;
long double
coshl(long double x)
{
long double hi,lo,x2,x4;
#if LDBL_MANT_DIG == 113
double dx2;
#endif
uint16_t ix;
GET_LDBL_EXPSIGN(ix,x);
ix &= 0x7fff;
if(ix>=0x7fff) return x*x;
ENTERI();
if(ix<0x3fff) {
if (ix<BIAS-(LDBL_MANT_DIG+1)/2)
RETURNI(1+tiny);
x2 = x*x;
#if LDBL_MANT_DIG == 64
x4 = x2*x2;
RETURNI(((C16*x2 + C14)*x4 + (C12*x2 + C10))*(x4*x4*x2) +
((C8*x2 + C6)*x2 + C4)*x4 + C2*x2 + 1);
#elif LDBL_MANT_DIG == 113
dx2 = x2;
RETURNI((((((((((((C26*dx2 + C24)*dx2 + C22)*dx2 +
C20)*x2 + C18)*x2 +
C16)*x2 + C14)*x2 + C12)*x2 + C10)*x2 + C8)*x2 + C6)*x2 +
C4)*(x2*x2) + C2*x2 + 1);
#endif
}
if (ix < 0x4005) {
k_hexpl(fabsl(x), &hi, &lo);
RETURNI(lo + 0.25/(hi + lo) + hi);
}
if (fabsl(x) <= o_threshold)
RETURNI(hexpl(fabsl(x)));
RETURNI(huge*huge);
}