#include "math.h"
#include "fenv.h"
#include "fp_private.h"
#include "fenv_private.h"
float acosf( float x ) { return (float)acos((double)( x )); }
float asinf( float x ) { return (float)asin((double)( x )); }
float atanf( float x ) { return (float)atan( (double)x ); }
float atan2f( float y, float x) { return (float)atan2( (double)y, (double)x ); }
float cosf( float x ) { return (float)cos((double)( x )); }
float sinf( float x) { return (float)sin( (double)x ); }
float tanf( float x ) { return (float)tan( (double)x ); }
float acoshf( float x ) { return (float)acosh( (double)x ); }
float asinhf( float x ) { return (float)asinh( (double)x ); }
float atanhf( float x ) { return (float)atanh( (double)x ); }
float coshf( float x) { return (float)cosh( (double)x ); }
float sinhf( float x) { return (float)sinh( (double)x ); }
float tanhf( float x) { return (float)tanh( (double)x ); }
float expf( float x) { return (float)exp( (double)x ); }
float exp2f( float x) { return (float)exp2( (double)x ); }
float expm1f( float x ) { return (float)expm1( (double)x ); }
float logf ( float x ) { return (float)log( (double)x ); }
float log10f ( float x ){ return (float)log10( (double)x ); }
float log2f ( float x ) { return (float)log2( x ); }
float log1pf ( float x ){ return (float)log1p( (double)x ); }
float cbrtf( float x ) { return (float)cbrt((double)( x )); }
float powf ( float x, float y ) { return (float)pow ( (double)x, (double)y ); }
float erff( float x ) { return (float)erf((double)( x )); }
float erfcf( float x ) { return (float)erfc((double)( x )); }
float lgammaf( float x ){ return (float)lgamma((double)( x )); }
float tgammaf( float x ){ return (float)tgamma((double)( x )); }
#ifdef notdef
#undef upHalfOfAnULP
#define upHalfOfAnULP 0.50000006 // 0x1.000002p-1
#define twoTo64 0.1844674407370955e20 // 2**64
#define twoToMinus32 0.2328306436538696e-9 // 2**-32
float sqrtf ( float x )
{
register int index;
hexdouble OldEnvironment;
hexsingle xInHex, yInHex, gInHex;
register float g, y, y2, d, e;
register unsigned long int xhead, ghead, yhead;
xInHex.fval = x;
xhead = xInHex.lval; FEGETENVD( OldEnvironment.d ); FESETENVD( 0.0 );
if ( xhead < 0x7f800000 )
{
if ( xhead > 0x1a000000ul )
{
ghead = ( ( xhead + 0x3f800000 ) >> 1 ) & 0x7f800000;
index = ( xhead >> 16 ) & 0xffUL; yhead = 0x7e000000UL - ghead;
gInHex.lval = ghead + ( ( 0xff00UL & SqrtTable[index] ) << 7 );
yInHex.lval = yhead + ( ( 0xffUL & SqrtTable[index] ) << 15 );
g = gInHex.fval;
y = yInHex.fval;
d = x - g * g;
y2 = y + y;
g = g + y * d; e = upHalfOfAnULP - y * g;
d = x - g * g;
y = y + e * y2; g = g + y * d; y2 = y + y;
e = upHalfOfAnULP - y * g;
d = x - g * g;
y = y + e * y2; FESETENVD( OldEnvironment.d ); return ( g + y * d ); }
if ( xhead != 0UL )
{
xInHex.fval = x * twoTo64; xhead = xInHex.lval;
ghead = ( ( xhead + 0x3f800000 ) >> 1 ) & 0x7f800000;
index = ( xhead >> 16 ) & 0xffUL; yhead = 0x7e000000UL - ghead;
gInHex.lval = ghead + ( ( 0xff00UL & SqrtTable[index] ) << 7 );
yInHex.lval = yhead + ( ( 0xffUL & SqrtTable[index] ) << 15 );
x = xInHex.fval;
g = gInHex.fval;
y = yInHex.fval;
d = x - g * g;
y2 = y + y;
g = g + y * d; e = upHalfOfAnULP - y * g;
d = x - g * g;
y = y + e * y2; g = g + y * d; y2 = y + y;
e = upHalfOfAnULP - y * g;
d = x - g * g;
y = y + e * y2; g *= twoToMinus32; d *= twoToMinus32;
FESETENVD( OldEnvironment.d ); return ( g + y * d ); }
else
{ FESETENVD( OldEnvironment.d ); return ( x );
}
}
FESETENVD( OldEnvironment.d );
if ( xhead < 0x80000000 ) return ( x );
if ( ( x == 0.0 ) || ( x != x ) ) return x;
else {
x = nan ( SQRT_NAN );
OldEnvironment.i.lo |= SET_INVALID;
FESETENVD( OldEnvironment.d ); return ( x ); }
}
#else
float sqrtf ( float x ) { return (float) sqrt((double) x); }
#endif
static const hexsingle HugeF = { 0x7F800000 };
static const hexsingle NegHugeF = { 0xFF800000 };
float hypotf ( float x, float y )
{
register float temp;
hexdouble OldEnvironment, CurrentEnvironment;
register float FPR_z, FPR_one, FPR_inf, FPR_Minf, FPR_absx, FPR_absy, FPR_big, FPR_small;
register double FPR_env;
FPR_z = 0.0; FPR_one = 1.0;
FPR_inf = HugeF.fval; FPR_Minf = NegHugeF.fval;
FPR_absx = __FABSF( x ); FPR_absy = __FABSF( y );
if ( ( x == FPR_inf ) || ( y == FPR_inf ) || ( x == FPR_Minf ) || ( y == FPR_Minf ) )
return FPR_inf;
if ( ( x != x ) || ( y != y ) )
{
x = __FABSF ( x + y );
return x;
}
if ( FPR_absx > FPR_absy )
{
FPR_big = FPR_absx;
FPR_small = FPR_absy;
}
else
{
FPR_big = FPR_absy;
FPR_small = FPR_absx;
}
if ( FPR_small == FPR_z )
return FPR_big;
FEGETENVD( FPR_env ); FESETENVD( FPR_z );
temp = FPR_small / FPR_big; OldEnvironment.d = FPR_env;
temp = sqrtf ( FPR_one + temp * temp );
FEGETENVD( CurrentEnvironment.d );
CurrentEnvironment.i.lo &= ~FE_UNDERFLOW; FESETENVD( CurrentEnvironment.d );
temp = FPR_big * temp;
FEGETENVD( CurrentEnvironment.d );
OldEnvironment.i.lo |= CurrentEnvironment.i.lo; FESETENVD( OldEnvironment.d );
return temp;
}