#include <math.h>
float tanhf( float x )
{
static const float overflow = 183.2222702f/2.0; float fabsx = __builtin_fabsf( x );
if( x != x ) return x + x;
if( fabsx > 0x1.0p-12f ) {
if( fabsx < overflow )
{
fabsx = expm1f( -2.0L * fabsx );
fabsx = -fabsx / (2.0L + fabsx );
}
else
fabsx = 1.0f;
}
else
{
if( x == 0.0 )
return x;
fabsx *= 0x1.0p25;
fabsx -= 0x1.0p-126f;
fabsx *= 0x1.0p-25;
}
if( x < 0 )
fabsx = -fabsx;
return fabsx;
}
double tanh( double x )
{
static const double overflow = 1.477319723e+03L/2.0; double fabsx = __builtin_fabs( x );
if( x != x ) return x + x;
if( fabsx > 0x1.0p-27 ) {
if( fabsx < overflow )
{
fabsx = expm1( -2.0 * fabsx );
fabsx = -fabsx / (2.0 + fabsx );
}
else
fabsx = 1.0;
}
else
{
if( x == 0.0 )
return x;
fabsx *= 0x1.0p55;
fabsx -= 0x1.0p-1022;
fabsx *= 0x1.0p-55;
}
if( x < 0 )
fabsx = -fabsx;
return fabsx;
}
long double tanhl( long double x )
{
static const long double overflow = 1.13565234062941445534588410310297337926799095235775e+04L / 2.0L; long double fabsx = __builtin_fabsl( x );
if( x != x ) return x + x;
if( fabsx > 0x1.0p-32 ) {
if( fabsx < overflow )
{
fabsx = expm1l( -2.0L * fabsx );
fabsx = -fabsx / (2.0L + fabsx );
}
else
fabsx = 1.0L;
}
else
{
if( x == 0.0 )
return x;
fabsx *= 0x1.0p65;
fabsx -= 0x1.0p-16382L;
fabsx *= 0x1.0p-65;
}
if( x < 0 )
fabsx = -fabsx;
return fabsx;
}