// cmath0 internal header (from <cmath>)
#ifndef _CMATH0_
#define _CMATH0_
#include <yvals.h>

#if defined(__ghs) && _HAS_CPP17 && !defined(__NoFloat)
#include <limits>
#include <type_traits>
#endif /* defined(__ghs) && _HAS_CPP17 && !defined(__NoFloat) */

 #if defined(__ghs)
  #pragma ghs start_cxx_lib_header
  // Don't use '#pragma startdata' here, as we need to include more headers below
  #if defined(__ghs_max_pack_value)
   #pragma pack (push, __ghs_max_pack_value)
  #endif /* defined(__ghs_max_pack_value) */
 #endif /* defined(__ghs) */


/* ========================================================================= */
/* GHS uses their own version of this header.  See the corresponding #else for
   this #if. */
#if !defined(__ghs)
/* ========================================================================= */

#ifdef _STD_USING
 #undef _STD_USING
  #include <math.h>

 #if _HAS_CPP11
  #include <xtgmath.h>
 #endif /* _HAS_CPP11 */

 #define _STD_USING

 #if defined(__GNUC__)	/* 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>

 #if _HAS_CPP11
 #include <xtgmath.h>
 #endif /* _HAS_CPP11 */

 #if 3 <= __GNUC__ && defined(sparc)	/* compiler test */
inline double abs(double _Left)
	{	// return absolute value
	return (_CSTD fabs(_Left));
	}
 #endif /* 3 <= __GNUC__ etc. */

#endif /* _STD_USING */

 #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(__GLIBC__) || defined(__BORLANDC__)	/* compiler test */ \
	|| 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_C99
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 hypot3; 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 hypot3f; 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 hypot3l; 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;

using _CSTD fpclassify; using _CSTD signbit;
using _CSTD isfinite; using _CSTD isinf;
using _CSTD isnan; using _CSTD isnormal;
using _CSTD isgreater; using _CSTD isgreaterequal;
using _CSTD isless; using _CSTD islessequal;
using _CSTD islessgreater; using _CSTD isunordered;
 #endif /* _HAS_C99 */
_STD_END
 #endif /* _GLOBAL_USING */

/* ========================================================================= */
#else /* !defined(__ghs) */
/* ========================================================================= */

#ifdef __NoFloat

#if defined(__ghs)
#pragma ghs startdata
#endif

#else // __NoFloat

#if defined (__VXWORKS)
  extern "C" {
#endif
#include <math.h>
#if defined (__VXWORKS)
  } /* extern "C" */
#endif
#if _HAS_CPP11
# if !defined(__VXWORKS)
// These macros may be defined for C99, but they are functions in C++11
#undef fpclassify
#undef isfinite
#undef isgreater
#undef isgreaterequal
#undef isinf
#undef isless
#undef islessequal
#undef islessgreater
#undef isnan
#undef isnormal
#undef isunordered
#undef signbit
extern "C" {
int __fcompare(float,float) __attribute__((__const__));
int __dcompare(double,double) __attribute__((__const__));
int __lcompare(long double,long double) __attribute__((__const__));
}
# endif /* !defined(__VXWORKS) */
# include <xtgmath.h>
#endif /* _HAS_CPP11 */

#if defined(__ghs)
#pragma ghs startdata
#endif


// 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__)))
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)); }
#endif
#if (defined(__LINUX) && !(defined(__i386) || defined(__x86_64__))) || defined(__sun)
// 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(__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) && !(defined(__i386) || defined(__x86_64__)))
// 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
#if defined(__LINUX) && (defined(__i386) || defined(__x86_64__))
extern "C" {
#endif /* __LINUX && (__i386 || __x86_64__) */
// 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)); }
#if defined(__LINUX) && (defined(__i386) || defined(__x86_64__))
}
#endif /* __LINUX && (__i386 || __x86_64__) */
#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 double pow(int _X, int _Y) ___THROW
	{
	return pow((double)_X, _Y);
	}
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 tan(float _X) ___THROW
	{return (tanf(_X)); }
inline float tanh(float _X) ___THROW
	{return (tanhf(_X)); }
#if _HAS_CPP11 && !defined(__VXWORKS)
inline float acosh(float _X) ___THROW
	{return (acoshf(_X)); }
inline float asinh(float _X) ___THROW
	{return (asinhf(_X)); }
inline float atanh(float _X) ___THROW
	{return (atanhf(_X)); }
inline float cbrt(float _X) ___THROW
	{return (cbrtf(_X)); }
inline float copysign(float _X, float _Y) ___THROW
	{return (copysignf(_X, _Y)); }
inline float erf(float _X) ___THROW
	{return (erff(_X)); }
inline float erfc(float _X) ___THROW
	{return (erfcf(_X)); }
inline float exp2(float _X) ___THROW
	{return (exp2f(_X)); }
inline float expm1(float _X) ___THROW
	{return (expm1f(_X)); }
inline float fdim(float _X, float _Y) ___THROW
	{return (fdimf(_X, _Y)); }
inline float fma(float _X, float _Y, float _Z) ___THROW
	{return (fmaf(_X, _Y, _Z)); }
inline float fmax(float _X, float _Y) ___THROW
	{return (fmaxf(_X, _Y)); }
inline float fmin(float _X, float _Y) ___THROW
	{return (fminf(_X, _Y)); }
inline float hypot(float _X, float _Y) ___THROW
	{return (hypotf(_X, _Y)); }
inline int ilogb(float _X) ___THROW
	{return (ilogbf(_X)); }
inline float lgamma(float _X) ___THROW
	{return (lgammaf(_X)); }
# if defined(_LONGLONG)
inline _LONGLONG llrint(float _X) ___THROW
	{return (llrintf(_X)); }
inline _LONGLONG llround(float _X) ___THROW
	{return (llroundf(_X)); }
# endif /* defined(_LONGLONG) */
inline float log1p(float _X) ___THROW
	{return (log1pf(_X)); }
inline float log2(float _X) ___THROW
	{return (log2f(_X)); }
inline float logb(float _X) ___THROW
	{return (logbf(_X)); }
inline long lrint(float _X) ___THROW
	{return (lrintf(_X)); }
inline long lround(float _X) ___THROW
	{return (lroundf(_X)); }
inline float nearbyint(float _X) ___THROW
	{return (nearbyintf(_X)); }
inline float nextafter(float _X, float _Y) ___THROW
	{return (nextafterf(_X, _Y)); }
inline float nexttoward(float _X, long double _Y) ___THROW
	{return (nexttowardf(_X, _Y)); }
inline float remainder(float _X, float _Y) ___THROW
	{return (remainderf(_X, _Y)); }
inline float remquo(float _X, float _Y, int *_Z) ___THROW
	{return (remquof(_X, _Y, _Z)); }
inline float rint(float _X) ___THROW
	{return (rintf(_X)); }
inline float round(float _X) ___THROW
	{return (roundf(_X)); }
inline float scalbn(float _X, int _Y) ___THROW
	{return (scalbnf(_X, _Y)); }
inline float scalbln(float _X, long _Y) ___THROW
	{return (scalblnf(_X, _Y)); }
inline float tgamma(float _X) ___THROW
	{return (tgammaf(_X)); }
inline float trunc(float _X) ___THROW
	{return (truncf(_X)); }
inline int fpclassify(float _X) ___THROW
	{return (__fpclassifyf(_X)); }
inline bool isfinite(float _X) ___THROW
#if defined(__GLIBC__)
	{return (__finitef(_X)); }
#else
	{return (__isfinitef(_X)); }
#endif
inline bool isgreater(float _X, float _Y) ___THROW
	{return (__fcompare(_Y, _X)==-1); }
inline bool isgreaterequal(float _X, float _Y) ___THROW
	{return (__fcompare(_Y, _X)<=0); }
inline bool isinf(float _X) ___THROW
	{return (__isinff(_X)); }
inline bool isless(float _X, float _Y) ___THROW
	{return (__fcompare(_X, _Y)==-1); }
inline bool islessequal(float _X, float _Y) ___THROW
	{return (__fcompare(_X, _Y)<=0); }
inline bool islessgreater(float _X, float _Y) ___THROW
	{return ((__fcompare(_X, _Y)&1)!=0); }
inline bool isnan(float _X) ___THROW
	{return (__isnanf(_X)); }
inline bool isnormal(float _X) ___THROW
#if defined(__GLIBC__)
	{return (fpclassify(_X) == FP_NORMAL); }
#else
	{return (__isnormalf(_X)); }
#endif
inline bool isunordered(float _X, float _Y) ___THROW
	{return (isnan(_X) || isnan(_Y)); }
inline bool signbit(float _X) ___THROW
	{return (__signbitf(_X)); }
#if defined(__FloatSingle__)
inline int fpclassify(double _X) ___THROW
	{return (__fpclassifyf((float)_X)); }
inline bool isfinite(double _X) ___THROW
	{return (__isfinitef((float)_X)); }
inline bool isgreater(double _X, double _Y) ___THROW
	{return (__fcompare((float)_Y, (float)_X)==-1); }
inline bool isgreaterequal(double _X, double _Y) ___THROW
	{return (__fcompare((float)_Y, (float)_X)<=0); }
inline bool isinf(double _X) ___THROW
	{return (__isinff((float)_X)); }
inline bool isless(double _X, double _Y) ___THROW
	{return (__fcompare((float)_X, (float)_Y)==-1); }
inline bool islessequal(double _X, double _Y) ___THROW
	{return (__fcompare((float)_X, (float)_Y)<=0); }
inline bool islessgreater(double _X, double _Y) ___THROW
	{return ((__fcompare((float)_X, (float)_Y)&1)!=0); }
inline bool isnan(double _X) ___THROW
	{return (__isnanf((float)_X)); }
inline bool isnormal(double _X) ___THROW
	{return (__isnormalf((float)_X)); }
inline bool signbit(double _X) ___THROW
	{return (__signbitf((float)_X)); }
#else
inline int fpclassify(double _X) ___THROW
 #if defined(__GLIBC__)
	{return (__fpclassify(_X)); }
 #else
	{return (__fpclassifyd(_X)); }
 #endif /* __GLIBC__ */
inline bool isfinite(double _X) ___THROW
 #if defined(__GLIBC__)
	{return (__finite(_X)); }
 #else
	{return (__isfinited(_X)); }
 #endif /* __GLIBC__ */
inline bool isgreater(double _X, double _Y) ___THROW
	{return (__dcompare(_Y, _X)==-1); }
inline bool isgreaterequal(double _X, double _Y) ___THROW
	{return (__dcompare(_Y, _X)<=0); }
 #if defined(__GLIBC__)
inline int isinf(double _X) ___THROW
	{return (__isinf(_X)); }
 #else
inline bool isinf(double _X) ___THROW
	{return (__isinfd(_X)); }
 #endif /* __GLIBC__ */
inline bool isless(double _X, double _Y) ___THROW
	{return (__dcompare(_X, _Y)==-1); }
inline bool islessequal(double _X, double _Y) ___THROW
	{return (__dcompare(_X, _Y)<=0); }
inline bool islessgreater(double _X, double _Y) ___THROW
	{return ((__dcompare(_X, _Y)&1)!=0); }
 #if defined(__GLIBC__)
inline int isnan(double _X) ___THROW
	{return (__isnan(_X)); }
 #else
inline bool isnan(double _X) ___THROW
	{return (__isnand(_X)); }
 #endif /* __GLIBC__ */
inline bool isnormal(double _X) ___THROW
 #if defined(__GLIBC__)
	{return (fpclassify(_X) == FP_NORMAL); }
 #else
	{return (__isnormald(_X)); }
 #endif /* __GLIBC__ */
inline bool signbit(double _X) ___THROW
 #if defined(__GLIBC__)
	{return (__signbit(_X)); }
 #else
	{return (__signbitd(_X)); }
 #endif /* __GLIBC__ */
#endif /* __FloatSingle__ */
inline bool isunordered(double _X, double _Y) ___THROW
	{return (isnan(_X) || isnan(_Y)); }
#endif /* _HAS_CPP11 && !defined(__VXWORKS) */
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 tan(long double _X) ___THROW
	{return (tanl(_X)); }
inline long double tanh(long double _X) ___THROW
	{return (tanhl(_X)); }
#if _HAS_CPP11 && !defined(__VXWORKS)
inline long double acosh(long double _X) ___THROW
	{return (acoshl(_X)); }
inline long double asinh(long double _X) ___THROW
	{return (asinhl(_X)); }
inline long double atanh(long double _X) ___THROW
	{return (atanhl(_X)); }
inline long double cbrt(long double _X) ___THROW
	{return (cbrtl(_X)); }
inline long double copysign(long double _X, long double _Y) ___THROW
	{return (copysignl(_X, _Y)); }
inline long double erf(long double _X) ___THROW
	{return (erfl(_X)); }
inline long double erfc(long double _X) ___THROW
	{return (erfcl(_X)); }
inline long double exp2(long double _X) ___THROW
	{return (exp2l(_X)); }
inline long double expm1(long double _X) ___THROW
	{return (expm1l(_X)); }
inline long double fdim(long double _X, long double _Y) ___THROW
	{return (fdiml(_X, _Y)); }
inline long double fma(long double _X, long double _Y, long double _Z) ___THROW
	{return (fmal(_X, _Y, _Z)); }
inline long double fmax(long double _X, long double _Y) ___THROW
	{return (fmaxl(_X, _Y)); }
inline long double fmin(long double _X, long double _Y) ___THROW
	{return (fminl(_X, _Y)); }
inline long double hypot(long double _X, long double _Y) ___THROW
	{return (hypotl(_X, _Y)); }
inline int ilogb(long double _X) ___THROW
	{return (ilogbl(_X)); }
inline long double lgamma(long double _X) ___THROW
	{return (lgammal(_X)); }
# if defined(_LONGLONG)
inline _LONGLONG llrint(long double _X) ___THROW
	{return (llrintl(_X)); }
inline _LONGLONG llround(long double _X) ___THROW
	{return (llroundl(_X)); }
# endif /* defined(_LONGLONG) */
inline long double log1p(long double _X) ___THROW
	{return (log1pl(_X)); }
inline long double log2(long double _X) ___THROW
	{return (log2l(_X)); }
inline long double logb(long double _X) ___THROW
	{return (logbl(_X)); }
inline long lrint(long double _X) ___THROW
	{return (lrintl(_X)); }
inline long lround(long double _X) ___THROW
	{return (lroundl(_X)); }
inline long double nearbyint(long double _X) ___THROW
	{return (nearbyintl(_X)); }
inline long double nextafter(long double _X, long double _Y) ___THROW
	{return (nextafterl(_X, _Y)); }
inline long double nexttoward(long double _X, long double _Y) ___THROW
	{return (nexttowardl(_X, _Y)); }
inline long double remainder(long double _X, long double _Y) ___THROW
	{return (remainderl(_X, _Y)); }
inline long double remquo(long double _X, long double _Y, int *_Z) ___THROW
	{return (remquol(_X, _Y, _Z)); }
inline long double rint(long double _X) ___THROW
	{return (rintl(_X)); }
inline long double round(long double _X) ___THROW
	{return (roundl(_X)); }
inline long double scalbn(long double _X, int _Y) ___THROW
	{return (scalbnl(_X, _Y)); }
inline long double scalbln(long double _X, long _Y) ___THROW
	{return (scalblnl(_X, _Y)); }
inline long double tgamma(long double _X) ___THROW
	{return (tgammal(_X)); }
inline long double trunc(long double _X) ___THROW
	{return (truncl(_X)); }
#if defined(__FloatSingle__)
inline int fpclassify(long double _X) ___THROW
	{return (__fpclassifyf((float)_X)); }
inline bool isfinite(long double _X) ___THROW
	{return (__isfinitef((float)_X)); }
inline bool isgreater(long double _X, long double _Y) ___THROW
	{return (__fcompare((float)_Y, (float)_X)==-1); }
inline bool isgreaterequal(long double _X, long double _Y) ___THROW
	{return (__fcompare((float)_Y, (float)_X)<=0); }
inline bool isinf(long double _X) ___THROW
	{return (__isinff((float)_X)); }
inline bool isless(long double _X, long double _Y) ___THROW
	{return (__fcompare((float)_X, (float)_Y)==-1); }
inline bool islessequal(long double _X, long double _Y) ___THROW
	{return (__fcompare((float)_X, (float)_Y)<=0); }
inline bool islessgreater(long double _X, long double _Y) ___THROW
	{return ((__fcompare((float)_X, (float)_Y)&1)!=0); }
inline bool isnan(long double _X) ___THROW
	{return (__isnanf((float)_X)); }
inline bool isnormal(long double _X) ___THROW
	{return (__isnormalf((float)_X)); }
inline bool signbit(long double _X) ___THROW
	{return (__signbitf((float)_X)); }
#else
inline int fpclassify(long double _X) ___THROW
	{return (__fpclassifyl(_X)); }
inline bool isfinite(long double _X) ___THROW
 #if defined(__GLIBC__)
	{return (__finitel(_X)); }
 #else
	{return (__isfinitel(_X)); }
 #endif /* __GLIBC__ */
inline bool isgreater(long double _X, long double _Y) ___THROW
	{return (__lcompare(_Y, _X)==-1); }
inline bool isgreaterequal(long double _X, long double _Y) ___THROW
	{return (__lcompare(_Y, _X)<=0); }
inline bool isinf(long double _X) ___THROW
	{return (__isinfl(_X)); }
inline bool isless(long double _X, long double _Y) ___THROW
	{return (__lcompare(_X, _Y)==-1); }
inline bool islessequal(long double _X, long double _Y) ___THROW
	{return (__lcompare(_X, _Y)<=0); }
inline bool islessgreater(long double _X, long double _Y) ___THROW
	{return ((__lcompare(_X, _Y)&1)!=0); }
inline bool isnan(long double _X) ___THROW
	{return (__isnanl(_X)); }
inline bool isnormal(long double _X) ___THROW
 #if defined(__GLIBC__)
	{return (fpclassify(_X) == FP_NORMAL); }
 #else
	{return (__isnormall(_X)); }
 #endif /* __GLIBC__ */
inline bool signbit(long double _X) ___THROW
	{return (__signbitl(_X)); }
#endif /* __FloatSingle__ */
inline bool isunordered(long double _X, long double _Y) ___THROW
	{return (isnan(_X) || isnan(_Y)); }
#endif /* _HAS_CPP11 && !defined(__VXWORKS) */

#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

	// New in C++11:
	acosh
	asinh
	atanh
	cbrt
	copysign
	erfc
	erf
	exp2
	expm1
	fdim
	fma
	fmax
	fmin
	hypot
	ilogb
	lgamma
	llrint
	llround
	log1p
	log2
	logb
	lrint
	lround
	nan
	nearbyint
	nextafter
	nexttoward
	remainder
	remquo
	rint
	round
	scalbln
	scalbn
	tgamma
	trunc

	fpclassify
	isfinite
	isgreater
	isgreaterequal
	isinf
	isless
	islessequal
	islessgreater
	isnan
	isnormal
	isunordered
	signbit

	float_t
	double_t
*/

    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;

#if _HAS_CPP11 && !defined(__VXWORKS)
    using ::acoshf;
    using ::asinhf;
    using ::atanhf;
    using ::cbrtf;
    using ::copysignf;
    using ::erfcf;
    using ::erff;
    using ::exp2f;
    using ::expm1f;
    using ::fdimf;
    using ::fmaf;
    using ::fmaxf;
    using ::fminf;
    using ::ilogbf;
    using ::lgammaf;
# if defined(_LONGLONG)
    using ::llrintf;
    using ::llroundf;
# endif /* defined(_LONGLONG) */
    using ::log1pf;
    using ::log2f;
    using ::logbf;
    using ::lrintf;
    using ::lroundf;
    using ::nanf;
    using ::nearbyintf;
    using ::nextafterf;
    using ::nexttowardf;
    using ::remainderf;
    using ::remquof;
    using ::rintf;
    using ::roundf;
    using ::scalblnf;
    using ::scalbnf;
    using ::tgammaf;
    using ::truncf;
#endif /* _HAS_CPP11 && !defined(__VXWORKS) */

// 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;

#if _HAS_CPP11 && !defined(__VXWORKS)
    using ::acosh;
    using ::asinh;
    using ::atanh;
    using ::cbrt;
    using ::copysign;
    using ::erf;
    using ::erfc;
    using ::exp2;
    using ::expm1;
    using ::fdim;
    using ::fma;
    using ::fmax;
    using ::fmin;
    using ::ilogb;
    using ::lgamma;
# if defined(_LONGLONG)
    using ::llrint;
    using ::llround;
# endif /* defined(_LONGLONG) */
    using ::log1p;
    using ::log2;
    using ::logb;
    using ::lrint;
    using ::lround;
    using ::nan;
    using ::nearbyint;
    using ::nextafter;
    using ::nexttoward;
    using ::remainder;
    using ::remquo;
    using ::rint;
    using ::round;
    using ::scalbn;
    using ::scalbln;
    using ::tgamma;
    using ::trunc;
#endif /* _HAS_CPP11 && !defined(__VXWORKS) */

// 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;

#if _HAS_CPP11 && !defined(__VXWORKS)
    using ::acoshl;
    using ::asinhl;
    using ::atanhl;
    using ::cbrtl;
    using ::copysignl;
    using ::erfcl;
    using ::erfl;
    using ::exp2l;
    using ::expm1l;
    using ::fdiml;
    using ::fmal;
    using ::fmaxl;
    using ::fminl;
    using ::ilogbl;
    using ::lgammal;
# if defined(_LONGLONG)
    using ::llrintl;
    using ::llroundl;
# endif /* defined(_LONGLONG) */
    using ::log1pl;
    using ::log2l;
    using ::logbl;
    using ::lrintl;
    using ::lroundl;
    using ::nanl;
    using ::nearbyintl;
    using ::nextafterl;
    using ::nexttowardl;
    using ::remainderl;
    using ::remquol;
    using ::rintl;
    using ::roundl;
    using ::scalblnl;
    using ::scalbnl;
    using ::tgammal;
    using ::truncl;
#endif /* _HAS_CPP11 && !defined(__VXWORKS) */

#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

#if _HAS_CPP11 && !defined(__VXWORKS)
    using ::fpclassify;
    using ::isfinite;
    using ::isgreater;
    using ::isgreaterequal;
    using ::isinf;
    using ::isless;
    using ::islessequal;
    using ::islessgreater;
    using ::isnan;
    using ::isnormal;
    using ::isunordered;
    using ::signbit;

    using ::float_t;
    using ::double_t;
#endif /* _HAS_CPP11 && !defined(__VXWORKS) */


#if _HAS_CPP17
//three argument hypot is specified by the C++17 standard, but not the C11/C18 standard

template<class _Ty> class numeric_limits;
	
template <class _Ty>
static void _Find_max_and_swap(_Ty &_XX, _Ty &_YY)
{
    _Ty _Tmp;
    if(abs(_XX) < abs(_YY))
    {
        _Tmp = _XX;
        _XX = _YY;
        _YY = _Tmp;
    }
}

#if defined(__ghs)
// doesn't have overloaded sqrt here.
template <class _Ty> inline _Ty __sqrt(_Ty __in)        { return sqrt (__in); }
template <> inline float       __sqrt(float __in)       { return sqrtf(__in); }
template <> inline double      __sqrt(double __in)      { return sqrt (__in); }
template <> inline long double __sqrt(long double __in) { return sqrtl(__in); }
#endif

template <class _Ty>
static _Ty _Hypot_three_args(_Ty _XX, _Ty _YY, _Ty _ZZ)
{
    constexpr _Ty _Constant_one = 1.0;
    constexpr _Ty _Constant_zero = 0.0;    
    _Ty _Tmp;
    bool _Scale_flag = false;
    int _Scale_val = 0;
    
    const int _XX_category = fpclassify(_XX);
    const int _YY_category = fpclassify(_YY);
    const int _ZZ_category = fpclassify(_ZZ);    

    if(_XX_category == FP_INFINITE || _YY_category == FP_INFINITE || _ZZ_category == FP_INFINITE)
    {
        return numeric_limits<_Ty>::infinity();
    }
    if(_XX_category == FP_NAN || _YY_category == FP_NAN || _ZZ_category == FP_NAN)
    {
        return numeric_limits<_Ty>::quiet_NaN();
    }
    if(_XX_category == FP_ZERO && _YY_category == FP_ZERO && _ZZ_category == FP_ZERO)
    {
	return _Constant_zero;
    }
    //Scale the input values out of the subnormal range if all inputs are either subnormal or zero
    //to avoid strange behaviors with subnormal on certain CPUs
    if( (_XX_category == FP_SUBNORMAL || _XX_category == FP_ZERO) &&
	(_YY_category == FP_SUBNORMAL || _YY_category == FP_ZERO) &&
	(_ZZ_category == FP_SUBNORMAL || _ZZ_category == FP_ZERO) )
    {
	_Scale_flag = true;
	_Scale_val = numeric_limits<_Ty>::digits;
	_XX = scalbn(_XX, _Scale_val);
	_YY = scalbn(_YY, _Scale_val);
	_ZZ = scalbn(_ZZ, _Scale_val);	
    }
    _Find_max_and_swap(_XX, _YY);
    _Find_max_and_swap(_XX, _ZZ);
    _Find_max_and_swap(_YY, _ZZ);

    //x has the largest absolute value
    _Tmp = (_YY / _XX) * (_YY / _XX) + (_ZZ / _XX) * (_ZZ / _XX); //add these first
#if defined(__ghs)
    // use overloaded __sqrt
    _Tmp = abs(_XX) * __sqrt<_Ty>(_Constant_one + _Tmp);
#else
    _Tmp = abs(_XX) * sqrt(_Constant_one + _Tmp);
#endif
    if(_Scale_flag == true)
    {
	_Tmp = scalbn(_Tmp, -_Scale_val);
    }
    return _Tmp;
}

inline long double hypot(long double _XX, long double _YY, long double _ZZ)
{
    return _Hypot_three_args<long double>(_XX, _YY, _ZZ);
}

inline double hypot(double _XX, double _YY, double _ZZ)
{
    return _Hypot_three_args<double>(_XX, _YY, _ZZ);
}

inline float hypot(float _XX, float _YY, float _ZZ)
{
    return _Hypot_three_args<float>(_XX, _YY, _ZZ);    
}

template <class _T1, class _T2, class _T3, class = enable_if_t<is_arithmetic_v<_T1> && is_arithmetic_v<_T2> && is_arithmetic_v<_T3> > >
inline decltype(auto) hypot(_T1 _XX, _T2 _YY, _T3 _ZZ)
{
    auto _Lambda = [] (auto _S)
        {
	    if constexpr(is_integral_v<decltype(_S)>)
	    {
	        return static_cast<double>(_S);
	    }
	    else
	    {
	        return _S;
	    }
        };
    if constexpr(is_same_v<_T1, long double> == true || is_same_v<_T2, long double> == true || is_same_v<_T3, long double> == true)
    {
        long double _X1 = _Lambda(_XX);
        long double _Y1 = _Lambda(_YY);
        long double _Z1 = _Lambda(_ZZ);
        return hypot(_X1, _Y1, _Z1);
    }
    else
    {
        double _X1 = _Lambda(_XX);
        double _Y1 = _Lambda(_YY);
        double _Z1 = _Lambda(_ZZ);       
        return hypot(_X1, _Y1, _Z1);	
    }
}

#endif //_HAS_CPP17

}
#endif  // __NAMESPACES
#endif	// __NoFloat

/* ========================================================================= */
#endif /* !__ghs */
/* ========================================================================= */

 #if defined(__ghs)
  #if defined(__ghs_max_pack_value)
   #pragma pack(pop)
  #endif /* defined(__ghs_max_pack_value) */
  #pragma ghs enddata
  #pragma ghs end_cxx_lib_header
 #endif /* defined(__ghs) */

#endif /* _CMATH0_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V8.03b/17:0063 */
