#ifdef __APPLE_CC__
#if __APPLE_CC__ > 930
#include "math.h"
#include "fenv_private.h"
#include "fp_private.h"
static const double rintFactor = 6.7553994410557440000e+15;
static const double oneOverLn2 = 1.4426950408889633000e+00;
static const double ln2Head = 6.9314718055994530000e-01;
static const double ln2Tail = 2.3190468138462996000e-17;
static const double maxExp = 7.0978271289338397000e+02;
static const double minExp = -7.4513321910194122000e+02;
static const double maxExp2 = 1024.0;
static const double minNormExp2 = -1022.0;
static const double minExp2 = -1075.0;
static const double denormal = 2.9387358770557188000e-39;
static const double oneOverDenorm = 3.402823669209384635e+38;
static const hexdouble infinity = HEXDOUBLE(0x7ff00000, 0x00000000);
static const double cm1 = 8.3333336309523691e-03;
static const double c0 = 4.1666668402777808000e-02;
static const double c1 = 1.6666666666666655000e-01;
static const double c2 = 4.9999999999999955000e-01;
static const double cc4 = 0.5000000000000000000;
static const double cc3 = 0.16666666666663809522820;
static const double cc2 = 0.04166666666666111110939;
static const double cc1 = 0.008333338095239329810170;
static const double cc0 = 0.001388889583333492938381;
extern const unsigned long int expTable[];
struct expTableEntry
{
double x;
double f;
};
#if !defined(BUILDING_FOR_CARBONCORE_LEGACY)
double exp ( double x )
{
hexdouble scale, xInHex, yInHex, OldEnvironment;
register double d, y, yTail, z, zTail, z2, temp1, temp2, power, result;
register long int i;
struct expTableEntry *tablePointer = ( struct expTableEntry * ) expTable + 177;
xInHex.d = x;
if ( ( xInHex.i.hi & 0x7ff00000 ) < 0x40800000ul )
{ if ( ( ( xInHex.i.hi & 0x7fffffff ) | xInHex.i.lo ) == 0x0ul )
return 1.0;
scale.d = 0.0;
fegetenvd ( OldEnvironment.d ); fesetenvd ( 0.0 );
yInHex.d = x * oneOverLn2 + rintFactor;
scale.i.hi = ( yInHex.i.lo + 1023 ) << 20;
yInHex.d -= rintFactor;
y = x - ln2Head * yInHex.d;
yTail = ln2Tail * yInHex.d;
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cm1 * z2 + c1;
temp2 = c0 * z2 + c2;
OldEnvironment.i.lo |= FE_INEXACT; temp1 = temp1 * z + temp2;
temp2 = temp1 * z2 + z;
result = scale.d * tablePointer[i].f;
temp1 = result * ( temp2 + ( zTail + zTail * temp2 ) );
result += temp1;
fesetenvd ( OldEnvironment.d );
return result;
}
if ( ( x <= maxExp ) && ( x > minExp ) )
{
scale.d = 0.0;
fegetenvd ( OldEnvironment.d ); fesetenvd ( 0.0 );
yInHex.d = x * oneOverLn2 + rintFactor;
if ( x >= 512.0 )
{
power = 2.0;
scale.i.hi = ( yInHex.i.lo + 1022 ) << 20;
}
else
{
power = denormal;
scale.i.hi = ( yInHex.i.lo + 1023+128 ) << 20;
}
yInHex.d -= rintFactor;
y = x - ln2Head * yInHex.d;
yTail = ln2Tail * yInHex.d;
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cm1 * z2 + c1;
temp2 = c0 * z2 + c2;
OldEnvironment.i.lo |= FE_INEXACT; temp1 = temp1 * z + temp2;
temp2 = temp1 * z2 + z;
result = scale.d * tablePointer[i].f;
temp1 = result * ( temp2 + ( zTail + zTail * temp2 ) );
result = ( result + temp1 ) * power;
fesetenvd ( OldEnvironment.d );
return result;
}
else if ( x != x )
return x;
else if ( x == infinity.d )
return infinity.d;
else if ( x == -infinity.d )
return +0.0;
else if ( x > maxExp )
{
fegetenvd ( OldEnvironment.d ); result = infinity.d;
OldEnvironment.i.lo |= FE_INEXACT | FE_OVERFLOW;
fesetenvd ( OldEnvironment.d );
return result;
}
else
{
fegetenvd ( OldEnvironment.d ); result = +0.0;
OldEnvironment.i.lo |= FE_INEXACT | FE_UNDERFLOW;
fesetenvd ( OldEnvironment.d );
return result;
}
}
#ifdef notdef
float expf( float x)
{
return (float)exp( x );
}
#endif
double expm1 ( double x )
{
hexdouble scale, invScale, xInHex, yInHex, OldEnvironment;
register double d, y, yTail, z, zTail, z2, temp1, temp2, power, result, f;
register long int i;
unsigned long int xpower;
struct expTableEntry *tablePointer = ( struct expTableEntry * ) expTable + 177;
xInHex.d = x;
xpower = xInHex.i.hi & 0x7ff00000;
if ( xpower < 0x40800000ul )
{ scale.d = 0.0;
invScale.d = 0.0;
fegetenvd ( OldEnvironment.d ); fesetenvd ( 0.0 );
if ( xpower < 0x3c800000ul )
{ if ( x == 0.0 )
{
}
else
{
if ( xpower == 0x0ul )
OldEnvironment.i.lo |= FE_INEXACT + FE_UNDERFLOW; else
OldEnvironment.i.lo |= FE_INEXACT; }
fesetenvd ( OldEnvironment.d );
return x;
}
yInHex.d = x * oneOverLn2 + rintFactor;
scale.i.hi = ( yInHex.i.lo + 1023 ) << 20;
yInHex.d -= rintFactor;
y = x - ln2Head * yInHex.d;
invScale.i.hi = 0x7fe00000 - scale.i.hi;
yTail = ln2Tail * yInHex.d;
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cc0 * z2 + cc2;
temp2 = cc1 * z2 + cc3;
#if 0
if ( yInHex.d != x ) OldEnvironment.i.lo |= FE_INEXACT; #else
OldEnvironment.i.lo |= FE_INEXACT; #endif
temp1 = temp1 * z2 + cc4;
temp2 = temp1 + temp2 * z;
temp1 = temp2 * z2 + z;
d = tablePointer[i].f - invScale.d;
temp2 = temp1 + ( zTail + zTail * temp1 );
result = ( d + tablePointer[i].f * temp2 ) * scale.d;
fesetenvd ( OldEnvironment.d );
return result;
}
if ( ( x <= maxExp ) && ( x > minExp ) )
{
scale.d = 0.0;
invScale.d = 0.0;
fegetenvd ( OldEnvironment.d ); fesetenvd ( 0.0 );
yInHex.d = x * oneOverLn2 + rintFactor;
if ( x >= 512.0 )
{
power = 2.0;
f = 0.5;
scale.i.hi = ( yInHex.i.lo + 1022 ) << 20;
}
else
{
power = denormal;
f = oneOverDenorm;
scale.i.hi = ( yInHex.i.lo + 1023+128 ) << 20;
if ( scale.i.hi < ( 168<<20 ) )
{
OldEnvironment.i.lo |= FE_INEXACT; fesetenvd ( OldEnvironment.d );
return -1.0;
}
}
invScale.i.hi = 0x7fe00000 - scale.i.hi;
yInHex.d -= rintFactor;
y = x - ln2Head * yInHex.d;
yTail = ln2Tail * yInHex.d;
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cc0 * z2 + cc2;
temp2 = cc1 * z2 + cc3;
#if 0
if ( yInHex.d != x )
OldEnvironment.i.lo |= FE_INEXACT; #else
OldEnvironment.i.lo |= FE_INEXACT; #endif
temp1 = temp1 * z2 + cc4;
temp2 = temp1 + temp2 * z;
temp1 = temp2 * z2 + z;
d = tablePointer[i].f - f * invScale.d;
temp2 = temp1 + ( zTail + zTail * temp1 );
result = ( ( d + tablePointer[i].f * temp2 ) * scale.d ) * power;
fesetenvd ( OldEnvironment.d );
return result;
}
else if ( x != x )
return x;
else if ( x == infinity.d )
return infinity.d;
else if ( x == -infinity.d )
return -1.0;
else if ( x > maxExp )
{
fegetenvd ( OldEnvironment.d ); result = infinity.d;
OldEnvironment.i.lo |= FE_INEXACT | FE_OVERFLOW;
fesetenvd ( OldEnvironment.d );
return result;
}
else
{
fegetenvd ( OldEnvironment.d ); result = -1.0;
#if 0
OldEnvironment.i.lo |= FE_INEXACT | FE_UNDERFLOW;
#else
OldEnvironment.i.lo |= FE_INEXACT;
#endif
fesetenvd ( OldEnvironment.d );
return result;
}
}
#ifdef notdef
float expm1f( float x )
{
return (float)expm1( x );
}
#endif
#else
double exp2 ( double x )
{
hexdouble scale, xInHex, yInHex, OldEnvironment;
register double d, y, yTail, z, zTail, z2, temp1, temp2, power, result;
register long int i;
struct expTableEntry *tablePointer = ( struct expTableEntry * ) expTable + 177;
xInHex.d = x;
if ( ( xInHex.i.hi & 0x7ff00000 ) < 0x40800000ul )
{ if ( ( ( xInHex.i.hi & 0x7fffffff ) | xInHex.i.lo ) == 0x0ul )
return 1.0;
scale.d = 0.0;
fegetenvd ( OldEnvironment.d ); fesetenvd ( 0.0 );
yInHex.d = x + rintFactor;
scale.i.hi = ( yInHex.i.lo + 1023 ) << 20;
yInHex.d -= rintFactor;
y = ln2Head * ( x - yInHex.d );
yTail = ln2Tail * ( x - yInHex.d );
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cm1 * z2 + c1;
temp2 = c0 * z2 + c2;
if ( yInHex.d != x ) OldEnvironment.i.lo |= FE_INEXACT; temp1 = temp1 * z + temp2;
temp2 = temp1 * z2 + z;
result = scale.d * tablePointer[i].f;
temp1 = result * ( temp2 + ( zTail + zTail * temp2 ) );
result += temp1;
fesetenvd ( OldEnvironment.d );
return result;
}
if ( ( x < maxExp2 ) && ( x > minExp2 ) )
{
scale.d = 0.0;
fegetenvd ( OldEnvironment.d ); fesetenvd ( 0.0 );
if (x < minNormExp2)
OldEnvironment.i.lo |= FE_UNDERFLOW; yInHex.d = x + rintFactor;
if ( x >= 512.0 )
{
power = 2.0;
scale.i.hi = ( yInHex.i.lo + 1022 ) << 20;
}
else
{
power = denormal;
scale.i.hi = ( yInHex.i.lo + 1023+128 ) << 20;
}
yInHex.d -= rintFactor;
y = ln2Head * ( x - yInHex.d );
yTail = ln2Tail * ( x - yInHex.d );
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cm1 * z2 + c1;
temp2 = c0 * z2 + c2;
if ( yInHex.d != x ) OldEnvironment.i.lo |= FE_INEXACT; temp1 = temp1 * z + temp2;
temp2 = temp1 * z2 + z;
result = scale.d * tablePointer[i].f;
temp1 = result * ( temp2 + ( zTail + zTail * temp2 ) );
result = ( result + temp1 ) * power;
fesetenvd ( OldEnvironment.d );
return result;
}
else if ( x != x )
return x;
else if ( x == infinity.d )
return infinity.d;
else if ( x == -infinity.d )
return +0.0;
else if ( x > maxExp )
{
fegetenvd ( OldEnvironment.d ); result = infinity.d;
OldEnvironment.i.lo |= FE_INEXACT | FE_OVERFLOW;
fesetenvd ( OldEnvironment.d );
return result;
}
else
{
fegetenvd ( OldEnvironment.d ); result = +0.0;
OldEnvironment.i.lo |= FE_INEXACT | FE_UNDERFLOW;
fesetenvd ( OldEnvironment.d );
return result;
}
}
#ifdef notdef
float exp2f( float x)
{
return (float)exp2( x );
}
#endif
#endif
#else
#warning A higher version than gcc-932 is required.
#endif
#endif