// cmath standard header
#ifndef _CMATH_
#define _CMATH_

#if defined(__ghs) || defined(__SC3__)
#ifndef __NoFloat

#include <math.h>

// gcc math functions throw exceptions
#if defined(__LINUX)
# define ___THROW __THROW
#else
# define ___THROW
#endif	/* __LINUX */

// note that hypot was not part of C until C99, nor part of C++
// If hypot is missing on your environment, add to the #if here.
#if defined(_MC_EXEC)
inline double hypot(double _X, double _Y)
	{ double _Z = _X + _Y;
	if (_Z == _X || _Z == _Y) return (_Z >= 0.0) ? _Z : -_Z;
	return(sqrt(_X*_X+_Y*_Y)); }
#endif // defined(_MC_EXEC)

#if defined(__windows)
// note that hypot was not part of C until C99, nor part of C++
inline float hypotf(float _X, float _Y) ___THROW
	{return ((float)hypot((double)_X, (double)_Y)); }
// note that hypot was not part of C until C99, nor part of C++
inline long double hypotl(long double _X, long double _Y) ___THROW
	{return ((long double)hypot((double)_X, (double)_Y)); }
#endif
// these are the single precision functions which are not commonly available
#if (defined(__LINUX) && !(defined(__i386) || defined(__x86_64__))) || defined(__sun)
inline float ceilf(float _X) ___THROW
	{return ((float)ceil((double)_X)); }
inline float fabsf(float _X) ___THROW
	{return ((float)fabs((double)_X)); }
inline float floorf(float _X) ___THROW
	{return ((float)floor((double)_X)); }
inline float fmodf(float _X, float _Y) ___THROW
	{return ((float)fmod((double)_X, (double)_Y)); }
// note that hypot was not part of C until C99, nor part of C++
inline float hypotf(float _X, float _Y) ___THROW
	{return ((float)hypot((double)_X, (double)_Y)); }
#endif
#if (defined(__LINUX)&& !(defined(__i386) || defined(__x86_64__))) ||defined(__sun)||defined(__VXWORKS)
inline float modff(float _X, float *_Y) ___THROW
	{ double _Di, _Df = modf((double)_X, &_Di);
	*_Y = (float)_Di;
	return ((float)_Df); }
#endif
#if defined(__VXWORKS) || ((defined(__i386) || defined(__x86_64__)) && defined(__sun))
inline float frexpf (float _X, int *_P) ___THROW
	{return (float)frexp((double)_X, _P); }
inline float ldexpf (float _X, int _I) ___THROW
	{return (float)ldexp((double)_X, _I); }
#endif	//  !(defined(__VXWORKS) || (defined(__i386)&&defined(__sun)))

#if defined(__windows)
#define __Does_Not_Have_Arc_Hyperbolic_Trig
#endif

// if math.h does not declare the long double functions, fake it here
// these are now part of C99, so over time vendors will be providing these.
#if defined(__OSE) || defined(__sun) || defined(__VXWORKS) || defined(__LYNX) || defined(_MC_EXEC) || \
   defined(__LINUX) // Linux-x86 has these, but the long double is not compatible
// I assume that any environment which does not provide the long double versions
// of these functions also does not provide the arc-hyperbolic-trig functions.
// these were all added by ISO C99 and are related to support for complex numbers.
#define __Does_Not_Have_Arc_Hyperbolic_Trig
// long double functions just call double equivalents
inline long double acosl(long double _X) ___THROW
	{return (acos((double)_X)); }
inline long double asinl(long double _X) ___THROW
	{return (asin((double)_X)); }
inline long double atanl(long double _X) ___THROW
	{return (atan((double)_X)); }
inline long double atan2l(long double _X, long double _Y) ___THROW
	{return (atan2((double)_X, (double)_Y)); }
inline long double ceill(long double _X) ___THROW
	{return (ceil((double)_X)); }
inline long double cosl(long double _X) ___THROW
	{return (cos((double)_X)); }
inline long double coshl(long double _X) ___THROW
	{return (cosh((double)_X)); }
inline long double expl(long double _X) ___THROW
	{return (exp((double)_X)); }
inline long double fabsl(long double _X) ___THROW
	{return (fabs((double)_X)); }
inline long double floorl(long double _X) ___THROW
	{return (floor((double)_X)); }
inline long double fmodl(long double _X, long double _Y) ___THROW
	{return (fmod((double)_X, (double)_Y)); }
inline long double frexpl(long double _X, int *_Y) ___THROW
	{return (frexp((double)_X, _Y)); }
// note that hypot was not part of C until C99, nor part of C++
inline long double hypotl(long double _X, long double _Y) ___THROW
	{return ((long double)hypot((double)_X, (double)_Y)); }
inline long double ldexpl(long double _X, int _Y) ___THROW
	{return (ldexp((double)_X, _Y)); }
inline long double logl(long double _X) ___THROW
	{return (log((double)_X)); }
inline long double log10l(long double _X) ___THROW
	{return (log10((double)_X)); }
inline long double modfl(long double _X, long double *_Y) ___THROW
	{double _Di, _Df = modf((double)_X, &_Di);
	*_Y = (long double)_Di;
	return (_Df); }
inline long double powl(long double _X, long double _Y) ___THROW
	{return (pow((double)_X, (double)_Y)); }
inline long double sinl(long double _X) ___THROW
	{return (sin((double)_X)); }
inline long double sinhl(long double _X) ___THROW
	{return (sinh((double)_X)); }
inline long double sqrtl(long double _X) ___THROW
	{return (sqrt((double)_X)); }
inline long double tanl(long double _X) ___THROW
	{return (tan((double)_X)); }
inline long double tanhl(long double _X) ___THROW
	{return (tanh((double)_X)); }
#endif

// overloads provided here for all environments because C++ added them to C.
// in C abs() was int(*)(int), but C++ has float, double, long double
// similarly in C++ pow() is allowed to have its second arg be an integer

inline double abs(double _X) ___THROW
	{return (fabs(_X)); }
inline double pow(double _X, int _Y) ___THROW
	{typedef double _Ty;
	unsigned int _N = _Y;
	if (_Y < 0)
		_N = -_N;
	for (_Ty _Z = _Ty(1); ; _X *= _X)
		{if ((_N & 1) != 0)
			_Z *= _X;
		if ((_N >>= 1) == 0)
			return (_Y < 0 ? _Ty(1) / _Z : _Z); }}
inline int pow(int _X, int _Y) ___THROW
	{typedef int _Ty;
	unsigned int _N = _Y;
	if (_Y < 0)
		_N = -_N;
	for (_Ty _Z = _Ty(1); ; _X *= _X)
		{if ((_N & 1) != 0)
			_Z *= _X;
		if ((_N >>= 1) == 0)
			return (_Y < 0 ? _Ty(1) / _Z : _Z); }}
inline float abs(float _X) ___THROW
	{return (fabsf(_X)); }
inline float acos(float _X) ___THROW
	{return (acosf(_X)); }
inline float asin(float _X) ___THROW
	{return (asinf(_X)); }
inline float atan(float _X) ___THROW
	{return (atanf(_X)); }
inline float atan2(float _Y, float _X) ___THROW
	{return (atan2f(_Y, _X)); }
inline float ceil(float _X) ___THROW
	{return (ceilf(_X)); }
inline float cos(float _X) ___THROW
	{return (cosf(_X)); }
inline float cosh(float _X) ___THROW
	{return (coshf(_X)); }
inline float exp(float _X) ___THROW
	{return (expf(_X)); }
inline float fabs(float _X) ___THROW
	{return (fabsf(_X)); }
inline float floor(float _X) ___THROW
	{return (floorf(_X)); }
inline float fmod(float _X, float _Y) ___THROW
	{return (fmodf(_X, _Y)); }
inline float frexp(float _X, int * _Y) ___THROW
	{return (frexpf(_X, _Y)); }
inline float ldexp(float _X, int _Y) ___THROW
	{return (ldexpf(_X, _Y)); }
inline float log(float _X) ___THROW
	{return (logf(_X)); }
inline float log10(float _X) ___THROW
	{return (log10f(_X)); }
inline float modf(float _X, float * _Y) ___THROW
	{return (modff(_X, _Y)); }
inline float pow(float _X, float _Y) ___THROW
	{return (powf(_X, _Y)); }
inline float pow(float _X, int _Y) ___THROW
	{typedef float _Ty;
	unsigned int _N = _Y;
	if (_Y < 0)
		_N = -_N;
	for (_Ty _Z = _Ty(1); ; _X *= _X)
		{if ((_N & 1) != 0)
			_Z *= _X;
		if ((_N >>= 1) == 0)
			return (_Y < 0 ? _Ty(1) / _Z : _Z); }}
inline float sin(float _X) ___THROW
	{return (sinf(_X)); }
inline float sinh(float _X) ___THROW
	{return (sinhf(_X)); }
inline float sqrt(float _X) ___THROW
	{return (sqrtf(_X)); }
inline float tan(float _X) ___THROW
	{return (tanf(_X)); }
inline float tanh(float _X) ___THROW
	{return (tanhf(_X)); }
inline long double abs(long double _X) ___THROW
	{return (fabsl(_X)); }
inline long double acos(long double _X) ___THROW
	{return (acosl(_X)); }
inline long double asin(long double _X) ___THROW
	{return (asinl(_X)); }
inline long double atan(long double _X) ___THROW
	{return (atanl(_X)); }
inline long double atan2(long double _Y, long double _X) ___THROW
	{return (atan2l(_Y, _X)); }
inline long double ceil(long double _X) ___THROW
	{return (ceill(_X)); }
inline long double cos(long double _X) ___THROW
	{return (cosl(_X)); }
inline long double cosh(long double _X) ___THROW
	{return (coshl(_X)); }
inline long double exp(long double _X) ___THROW
	{return (expl(_X)); }
inline long double fabs(long double _X) ___THROW
	{return (fabsl(_X)); }
inline long double floor(long double _X) ___THROW
	{return (floorl(_X)); }
inline long double fmod(long double _X, long double _Y) ___THROW
	{return (fmodl(_X, _Y)); }
inline long double frexp(long double _X, int * _Y) ___THROW
	{return (frexpl(_X, _Y)); }
inline long double ldexp(long double _X, int _Y) ___THROW
	{return (ldexpl(_X, _Y)); }
inline long double log(long double _X) ___THROW
	{return (logl(_X)); }
inline long double log10(long double _X) ___THROW
	{return (log10l(_X)); }
inline long double modf(long double _X, long double * _Y) ___THROW
	{return (modfl(_X, _Y)); }
inline long double pow(long double _X, long double _Y) ___THROW
	{return (powl(_X, _Y)); }
inline long double pow(long double _X, int _Y) ___THROW
	{typedef long double _Ty;
	unsigned int _N = _Y;
	if (_Y < 0)
		_N = -_N;
	for (_Ty _Z = _Ty(1); ; _X *= _X)
		{if ((_N & 1) != 0)
			_Z *= _X;
		if ((_N >>= 1) == 0)
			return (_Y < 0 ? _Ty(1) / _Z : _Z); }}
inline long double sin(long double _X) ___THROW
	{return (sinl(_X)); }
inline long double sinh(long double _X) ___THROW
	{return (sinhl(_X)); }
inline long double sqrt(long double _X) ___THROW
	{return (sqrtl(_X)); }
inline long double tan(long double _X) ___THROW
	{return (tanl(_X)); }
inline long double tanh(long double _X) ___THROW
	{return (tanhl(_X)); }

#if defined(__NAMESPACES) && !defined(__EMBEDDED_CXX_HEADERS)
namespace std {
/*
	// From the original ANSI C standard for math.h:
	abs
	acos
	asin
	atan
	atan2
	ceil
	cos
	cosh
	exp
	fabs
	floor
	fmod
	frexp
	ldexp
	log
	log10
	modf
	pow
	sin
	sinh
	sqrt
	tan
	tanh
*/

    using ::abs;

// Single precision versions
    using ::acosf;
    using ::asinf;
    using ::atanf;
    using ::atan2f;
    using ::ceilf;
    using ::cosf;
    using ::coshf;
    using ::expf;
    using ::fabsf;
    using ::floorf;
    using ::fmodf; 
    using ::frexpf;
// note that hypot was not part of C until C99, nor part of C++
    using ::hypotf;
    using ::ldexpf;
    using ::logf;
    using ::log10f;
    using ::modff; 
    using ::powf;
    using ::sinf;
    using ::sinhf;
    using ::sqrtf;
    using ::tanf;
    using ::tanhf;

// old fashioned double precision routines available everywhere
    using ::acos;
    using ::asin;
    using ::atan;
    using ::atan2;

    using ::cos;
    using ::sin;
    using ::tan;
    using ::cosh;
    using ::sinh;
    using ::tanh;

    using ::exp;
    using ::frexp;
    using ::ldexp;
    using ::modf;
    using ::log;
    using ::log10;
    using ::pow;
    using ::sqrt;

    using ::ceil;
    using ::fabs;
    using ::floor;
    using ::fmod;
// note that hypot was not part of C until C99, nor part of C++
    using ::hypot;

// Long double routines are often missing.  Declare an inline version above.
    using ::acosl;
    using ::asinl;
    using ::atanl;
    using ::atan2l;
    using ::ceill;
    using ::cosl;
    using ::coshl;
    using ::expl;
    using ::fabsl;
    using ::floorl;
    using ::fmodl;
    using ::frexpl;
// note that hypot was not part of C until C99, nor part of C++
    using ::hypotl;
    using ::ldexpl;
    using ::logl;
    using ::log10l;
    using ::modfl;
    using ::powl;
    using ::sqrtl;
    using ::sinl;
    using ::sinhl;
    using ::tanl;
    using ::tanhl;

#ifndef __Does_Not_Have_Arc_Hyperbolic_Trig
// Arc hyperbolic trig functions finally recognized by ISO C99
    using ::acoshf;
    using ::asinhf;
    using ::atanhf;

    using ::acosh;
    using ::asinh;
    using ::atanh;

    using ::acosl;
    using ::asinl;
    using ::atanl;
#endif

}
#endif  // __NAMESPACES

#endif	// __NoFloat

#else /* !__ghs */

#include <yvals.h>


 #if defined(__SUNPRO_CC)	/* compiler test */
 #define exception	_Math_exception	/* KLUDGE to avoid ambiguity */
 #endif /* defined(__SUNPRO_CC) */

#ifdef _STD_USING
 #undef _STD_USING
  #include <math.h>
 #define _STD_USING

 #if defined(__GLIBC__)	/* compiler test */
_STD_BEGIN
inline double abs(double _Left)
	{	// return absolute value
	return (_CSTD fabs(_Left));
	}
_STD_END
 #endif /* defined(__GNUC__) */

#else /* _STD_USING */
 #include <math.h>


 #ifdef _GLOBAL_USING

 #if defined(__BORLANDC__)	/* compiler test */
_C_STD_BEGIN
_C_LIB_DECL
float (atan2f)(float, float);
float (cosf)(float);
float (expf)(float);
float (ldexpf)(float, int);
float (logf)(float);
float (powf)(float, float);
float (sinf)(float);
float (sqrtf)(float);
float (tanf)(float);
_END_C_LIB_DECL
_C_STD_END
 #endif /* defined(__BORLANDC__) */

 #if defined(__MINGW32__) || defined(__SUNPRO_CC)	/* compiler test */ \
	|| defined(__APPLE__) || defined(__GLIBC__)
_C_STD_BEGIN
_C_LIB_DECL
float (atan2f)(float, float);
float (cosf)(float);
float (expf)(float);
float (ldexpf)(float, int);
float (logf)(float);
float (powf)(float, float);
float (sinf)(float);
float (sqrtf)(float);
float (tanf)(float);

long double (atan2l)(long double, long double);
long double (cosl)(long double);
long double (expl)(long double);
long double (ldexpl)(long double, int);
long double (logl)(long double);
long double (powl)(long double, long double);
long double (sinl)(long double);
long double (sqrtl)(long double);
long double (tanl)(long double);
_END_C_LIB_DECL
_C_STD_END
#endif /* defined(__MINGW32__) etc. */

_STD_BEGIN

 #if defined(__SUNPRO_CC) || defined(__GLIBC__)	/* compiler test */ \
	 || defined(__BORLANDC__) || defined(__MINGW32__) || defined(__APPLE__)
		/* double OVERLOADS */
inline double abs(double _Left)
	{	// return absolute value
	return (_CSTD fabs(_Left));
	}

 #else /* defined(__SUNPRO_CC) etc. */
using _CSTD acosf; using _CSTD asinf;
using _CSTD atanf; using _CSTD atan2f; using _CSTD ceilf;
using _CSTD cosf; using _CSTD coshf; using _CSTD expf;
using _CSTD fabsf; using _CSTD floorf; using _CSTD fmodf;
using _CSTD frexpf; using _CSTD ldexpf; using _CSTD logf;
using _CSTD log10f; using _CSTD modff; using _CSTD powf;
using _CSTD sinf; using _CSTD sinhf; using _CSTD sqrtf;
using _CSTD tanf; using _CSTD tanhf;

using _CSTD acosl; using _CSTD asinl;
using _CSTD atanl; using _CSTD atan2l; using _CSTD ceill;
using _CSTD cosl; using _CSTD coshl; using _CSTD expl;
using _CSTD fabsl; using _CSTD floorl; using _CSTD fmodl;
using _CSTD frexpl; using _CSTD ldexpl; using _CSTD logl;
using _CSTD log10l; using _CSTD modfl; using _CSTD powl;
using _CSTD sinl; using _CSTD sinhl; using _CSTD sqrtl;
using _CSTD tanl; using _CSTD tanhl;

using _CSTD abs;
 #endif /* defined(__SUNPRO_CC) etc. */

using _CSTD acos; using _CSTD asin;
using _CSTD atan; using _CSTD atan2; using _CSTD ceil;
using _CSTD cos; using _CSTD cosh; using _CSTD exp;
using _CSTD fabs; using _CSTD floor; using _CSTD fmod;
using _CSTD frexp; using _CSTD ldexp; using _CSTD log;
using _CSTD log10; using _CSTD modf; using _CSTD pow;
using _CSTD sin; using _CSTD sinh; using _CSTD sqrt;
using _CSTD tan; using _CSTD tanh;

 #if _HAS_C9X
using _CSTD float_t; using _CSTD double_t;

using _CSTD acosh; using _CSTD asinh; using _CSTD atanh;
using _CSTD cbrt; using _CSTD erf; using _CSTD erfc;
using _CSTD expm1; using _CSTD exp2;
using _CSTD hypot; using _CSTD ilogb; using _CSTD lgamma;
using _CSTD log1p; using _CSTD log2; using _CSTD logb;
using _CSTD llrint; using _CSTD lrint; using _CSTD nearbyint;
using _CSTD rint; using _CSTD llround; using _CSTD lround;
using _CSTD fdim; using _CSTD fma; using _CSTD fmax; using _CSTD fmin;
using _CSTD round; using _CSTD trunc;
using _CSTD remainder; using _CSTD remquo;
using _CSTD copysign; using _CSTD nan; using _CSTD nextafter;
using _CSTD scalbn; using _CSTD scalbln;
using _CSTD nexttoward; using _CSTD tgamma;

using _CSTD acoshf; using _CSTD asinhf; using _CSTD atanhf;
using _CSTD cbrtf; using _CSTD erff; using _CSTD erfcf;
using _CSTD expm1f; using _CSTD exp2f;
using _CSTD hypotf; using _CSTD ilogbf; using _CSTD lgammaf;
using _CSTD log1pf; using _CSTD log2f; using _CSTD logbf;
using _CSTD llrintf; using _CSTD lrintf; using _CSTD nearbyintf;
using _CSTD rintf; using _CSTD llroundf; using _CSTD lroundf;
using _CSTD fdimf; using _CSTD fmaf; using _CSTD fmaxf; using _CSTD fminf;
using _CSTD roundf; using _CSTD truncf;
using _CSTD remainderf; using _CSTD remquof;
using _CSTD copysignf; using _CSTD nanf;
using _CSTD nextafterf; using _CSTD scalbnf; using _CSTD scalblnf;
using _CSTD nexttowardf; using _CSTD tgammaf;

using _CSTD acoshl; using _CSTD asinhl; using _CSTD atanhl;
using _CSTD cbrtl; using _CSTD erfl; using _CSTD erfcl;
using _CSTD expm1l; using _CSTD exp2l;
using _CSTD hypotl; using _CSTD ilogbl; using _CSTD lgammal;
using _CSTD log1pl; using _CSTD log2l; using _CSTD logbl;
using _CSTD llrintl; using _CSTD lrintl; using _CSTD nearbyintl;
using _CSTD rintl; using _CSTD llroundl; using _CSTD lroundl;
using _CSTD fdiml; using _CSTD fmal; using _CSTD fmaxl; using _CSTD fminl;
using _CSTD roundl; using _CSTD truncl;
using _CSTD remainderl; using _CSTD remquol;
using _CSTD copysignl; using _CSTD nanl;
using _CSTD nextafterl; using _CSTD scalbnl; using _CSTD scalblnl;
using _CSTD nexttowardl; using _CSTD tgammal;
 #endif /* _HAS_C9X */

_STD_END
 #endif /* _GLOBAL_USING */

#endif /* _STD_USING */

 #if defined(__SUNPRO_CC)	/* compiler test */
 #undef exception
 #endif /* defined(__SUNPRO_CC) */

#endif /* !__ghs */

#endif /* _CMATH_ */

/*
 * Copyright (c) 1992-2003 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
V4.02:0324 */
