#ifndef __math_h
   #if __IBMC__ || __IBMCPP__
      #pragma info(none)
      #ifndef __CHKHDR__
         #pragma info(none)
      #endif
      #pragma info(restore)
   #endif

   #define __math_h

   #if __cplusplus
      extern "C" {
   #endif

   #ifndef _LNK_CONV
      #if __IBMC__ || __IBMCPP__ || defined _OPTLINK_SUPPORTED
         #define _LNK_CONV _Optlink
      #else
         #define _LNK_CONV
      #endif
   #endif

   #ifndef _IMPORT
      #if __IMPORTLIB__
         #define _IMPORT _Import
      #else
         #define _IMPORT
      #endif
   #endif

   /********************************************************************/
   /*  <math.h> header file                                            */
   /*  IBM C and C++ Compilers for OS/2, AIX and for Windows NT,       */
   /*  Version 3.6                                                     */
   /*  Licensed Material - Property of IBM                             */
   /*  (C) Copyright IBM Corp. 1991, 1997. All rights reserved         */
   /*                                                                  */
   /********************************************************************/

   #if !defined __COMPATMATH__ && (__IBMCPP__ < 400)
      #define __COMPATMATH__ 1
   #endif

   extern const double _IMPORT _infinity;
   #define HUGE_VAL    _infinity

   /* function prototypes */

   #if __IBMC__ || __IBMCPP__
      #if __cplusplus
         extern "builtin" double __fabs(double);
         inline double fabs(double __x) { return __fabs(__x); }
      #else
         double _Builtin __fabs(double);
         extern double _IMPORT _LNK_CONV fabs(double);
         #define fabs(__x)  __fabs(__x)
      #endif
      #pragma isolated_call(__fabs)
   #else
      extern double _IMPORT _LNK_CONV fabs(double);
   #endif

   extern float _IMPORT _LNK_CONV acosf(float);
   extern float _IMPORT _LNK_CONV asinf(float);
   extern float _IMPORT _LNK_CONV atanf(float);
   extern float _IMPORT _LNK_CONV atan2f(float, float);
   extern float _IMPORT _LNK_CONV ceilf(float);
   extern float _IMPORT _LNK_CONV cosf(float);
   extern float _IMPORT _LNK_CONV coshf(float);
   extern float _IMPORT _LNK_CONV expf(float);
   extern float _IMPORT _LNK_CONV fabsf(float);
   extern float _IMPORT _LNK_CONV floorf(float);
   extern float _IMPORT _LNK_CONV fmodf(float, float);
   extern float _IMPORT _LNK_CONV frexpf(float, int *);
   extern float _IMPORT _LNK_CONV ldexpf(float, int);
   extern float _IMPORT _LNK_CONV logf(float);
   extern float _IMPORT _LNK_CONV log10f(float);
   extern float _IMPORT _LNK_CONV modff(float, float *);
   extern float _IMPORT _LNK_CONV powf(float, float);
   extern float _IMPORT _LNK_CONV sinf(float);
   extern float _IMPORT _LNK_CONV sinhf(float);
   extern float _IMPORT _LNK_CONV sqrtf(float);
   extern float _IMPORT _LNK_CONV tanf(float);
   extern float _IMPORT _LNK_CONV tanhf(float);

   extern double _IMPORT _LNK_CONV ceil(double);
   extern double _IMPORT _LNK_CONV cosh(double);
   extern double _IMPORT _LNK_CONV floor(double);
   extern double _IMPORT _LNK_CONV fmod(double, double);
   extern double _IMPORT _LNK_CONV frexp(double, int *);
   extern double _IMPORT _LNK_CONV ldexp(double, int);
   extern double _IMPORT _LNK_CONV modf(double, double *);
   extern double _IMPORT _LNK_CONV pow(double, double);
   extern double _IMPORT _LNK_CONV sinh(double);
   extern double _IMPORT _LNK_CONV tanh(double);

   extern long double _IMPORT _LNK_CONV acosl(long double);
   extern long double _IMPORT _LNK_CONV asinl(long double);
   extern long double _IMPORT _LNK_CONV atanl(long double);
   extern long double _IMPORT _LNK_CONV atan2l(long double, long double);
   extern long double _IMPORT _LNK_CONV ceill(long double);
   extern long double _IMPORT _LNK_CONV cosl(long double);
   extern long double _IMPORT _LNK_CONV coshl(long double);
   extern long double _IMPORT _LNK_CONV expl(long double);
   extern long double _IMPORT _LNK_CONV fabsl(long double);
   extern long double _IMPORT _LNK_CONV floorl(long double);
   extern long double _IMPORT _LNK_CONV fmodl(long double, long double);
   extern long double _IMPORT _LNK_CONV frexpl(long double, int *);
   extern long double _IMPORT _LNK_CONV ldexpl(long double, int);
   extern long double _IMPORT _LNK_CONV logl(long double);
   extern long double _IMPORT _LNK_CONV log10l(long double);
   extern long double _IMPORT _LNK_CONV modfl(long double, long double *);
   extern long double _IMPORT _LNK_CONV powl(long double, long double);
   extern long double _IMPORT _LNK_CONV sinl(long double);
   extern long double _IMPORT _LNK_CONV sinhl(long double);
   extern long double _IMPORT _LNK_CONV sqrtl(long double);
   extern long double _IMPORT _LNK_CONV tanl(long double);
   extern long double _IMPORT _LNK_CONV tanhl(long double);

   extern float _IMPORT _LNK_CONV __powif(float, int);
   extern double _IMPORT _LNK_CONV __powi(double, int);
   extern long double _IMPORT _LNK_CONV __powil(long double, int);

   #if __THW_INTEL__
      #if __IBMCPP__ && defined(_FP_INLINE)
         extern "builtin" double __fsin(double);
         extern "builtin" double __fcos(double);
         extern "builtin" double __fptan(double);
         extern "builtin" double __fpatan(double);
         extern "builtin" double __facos(double);
         extern "builtin" double __fasin(double);
         extern "builtin" double __fsqrt(double);

         inline double _LNK_CONV sin(double __x) { return __fsin(__x); }
         inline double _LNK_CONV cos(double __x) { return __fcos(__x); }
         inline double _LNK_CONV tan(double __x) { return __fptan(__x); }
         inline double _LNK_CONV atan(double __x) { return __fpatan(__x); }
         inline double _LNK_CONV acos(double __x) { return __facos(__x); }
         inline double _LNK_CONV asin(double __x) { return __fasin(__x); }
         inline double _LNK_CONV sqrt(double __x) { return __fsqrt(__x); }
      #elif __IBMC__ && defined(_FP_INLINE)
         extern double _Builtin __fsin(double);
         extern double _Builtin __fcos(double);
         extern double _Builtin __fptan(double);
         extern double _Builtin __fpatan(double);
         extern double _Builtin __facos(double);
         extern double _Builtin __fasin(double);
         extern double _Builtin __fsqrt(double);

         #define sin(x)  __fsin(x)
         #define cos(x)  __fcos(x)
         #define tan(x)  __fptan(x)
         #define atan(x)  __fpatan(x)
         #define acos(x)  __facos(x)
         #define asin(x)  __fasin(x)
         #define sqrt(x)  __fsqrt(x)
      #else
         extern double _IMPORT _LNK_CONV sin(double);
         extern double _IMPORT _LNK_CONV cos(double);
         extern double _IMPORT _LNK_CONV tan(double);
         extern double _IMPORT _LNK_CONV acos(double);
         extern double _IMPORT _LNK_CONV asin(double);
         extern double _IMPORT _LNK_CONV atan(double);
         extern double _IMPORT _LNK_CONV sqrt(double);
      #endif
      extern double _IMPORT _LNK_CONV atan2(double, double);
      extern double _IMPORT _LNK_CONV exp(double);
      extern double _IMPORT _LNK_CONV log(double);
      extern double _IMPORT _LNK_CONV log10(double);
   #elif __THW_PPC__
      #if __IBMCPP__ && __MATH__
         extern "builtin" double __sin(double);
         extern "builtin" double __cos(double);
         extern "builtin" double __tan(double);
         extern "builtin" double __atan(double);
         extern "builtin" double __acos(double);
         extern "builtin" double __asin(double);
         extern "builtin" double __sqrt(double);
         extern "builtin" double __exp(double);
         extern "builtin" double __log(double);
         extern "builtin" double __log10(double);
         extern "builtin" double __atan2(double, double);

         inline double acos(double __x) {return __acos(__x);}
         inline double asin(double __x) {return __asin(__x);}
         inline double atan(double __x) {return __atan(__x);}
         inline double atan2(double __x, double __x) {return __atan2(__x, __x);}
         inline double cos(double __x) {return __cos(__x);}
         inline double exp(double __x) {return __exp(__x);}
         inline double log(double __x) {return __log(__x);}
         inline double log10(double __x) {return __log10(__x);}
         inline double sin(double __x) {return __sin(__x);}
         inline double sqrt(double __x) {return __sqrt(__x);}
         inline double tan(double __x) {return __tan(__x);}
      #elif __IBMC__ && __MATH__
         extern double _Builtin __sin(double);
         extern double _Builtin __cos(double);
         extern double _Builtin __tan(double);
         extern double _Builtin __atan(double);
         extern double _Builtin __acos(double);
         extern double _Builtin __asin(double);
         extern double _Builtin __sqrt(double);
         extern double _Builtin __exp(double);
         extern double _Builtin __log(double);
         extern double _Builtin __log10(double);
         extern double _Builtin __atan2(double, double);

         #define acos(x)      __acos(x)
         #define asin(x)      __asin(x)
         #define atan(x)      __atan(x)
         #define atan2(x, y)  __atan2(x, y)
         #define cos(x)       __cos(x)
         #define exp(x)       __exp(x)
         #define log(x)       __log(x)
         #define log10(x)     __log10(x)
         #define sin(x)       __sin(x)
         #define sqrt(x)      __sqrt(x)
         #define tan(x)       __tan(x)
      #else
         extern double _IMPORT _LNK_CONV log(double);
         extern double _IMPORT _LNK_CONV log10(double);
         extern double _IMPORT _LNK_CONV exp(double);
         extern double _IMPORT _LNK_CONV atan2(double, double);
         extern double _IMPORT _LNK_CONV sin(double);
         extern double _IMPORT _LNK_CONV cos(double);
         extern double _IMPORT _LNK_CONV tan(double);
         extern double _IMPORT _LNK_CONV acos(double);
         extern double _IMPORT _LNK_CONV asin(double);
         extern double _IMPORT _LNK_CONV atan(double);
         extern double _IMPORT _LNK_CONV sqrt(double);
      #endif
   #endif

   #if (__IBMC__ || __IBMCPP__) && __LIBANSI__
      #if defined _FP_INLINE
         #pragma isolated_call(__sin)
         #pragma isolated_call(__cos)
         #pragma isolated_call(__tan)
         #pragma isolated_call(__atan)
         #pragma isolated_call(__acos)
         #pragma isolated_call(__asin)
         #pragma isolated_call(__sqrt)
         #pragma isolated_call(__exp)
         #pragma isolated_call(__log)
         #pragma isolated_call(__log10)
         #pragma isolated_call(__atan2)
      #endif

      #pragma isolated_call(atan)
      #pragma isolated_call(ceil)
      #pragma isolated_call(fabs)
      #pragma isolated_call(floor)
      #pragma isolated_call(atanf)
      #pragma isolated_call(ceilf)
      #pragma isolated_call(fabsf)
      #pragma isolated_call(floorf)
      #pragma isolated_call(atanl)
      #pragma isolated_call(ceill)
      #pragma isolated_call(fabsl)
      #pragma isolated_call(floorl)
      #pragma isolated_call(abs)

      #if __IGNERRNO__
         #pragma isolated_call(acosf)
         #pragma isolated_call(asinf)
         #pragma isolated_call(atan2f)
         #pragma isolated_call(cosf)
         #pragma isolated_call(coshf)
         #pragma isolated_call(expf)
         #pragma isolated_call(fmodf)
         #pragma isolated_call(frexpf)
         #pragma isolated_call(ldexpf)
         #pragma isolated_call(logf)
         #pragma isolated_call(log10f)
         #pragma isolated_call(modff)
         #pragma isolated_call(powf)
         #pragma isolated_call(sinf)
         #pragma isolated_call(sinhf)
         #pragma isolated_call(sqrtf)
         #pragma isolated_call(tanf)
         #pragma isolated_call(tanhf)

         #pragma isolated_call(acos)
         #pragma isolated_call(asin)
         #pragma isolated_call(atan2)
         #pragma isolated_call(cos)
         #pragma isolated_call(cosh)
         #pragma isolated_call(exp)
         #pragma isolated_call(fmod)
         #pragma isolated_call(frexp)
         #pragma isolated_call(ldexp)
         #pragma isolated_call(log)
         #pragma isolated_call(log10)
         #pragma isolated_call(modf)
         #pragma isolated_call(pow)
         #pragma isolated_call(sin)
         #pragma isolated_call(sinh)
         #pragma isolated_call(sqrt)
         #pragma isolated_call(tan)
         #pragma isolated_call(tanh)

         #pragma isolated_call(acosl)
         #pragma isolated_call(asinl)
         #pragma isolated_call(atan2l)
         #pragma isolated_call(cosl)
         #pragma isolated_call(coshl)
         #pragma isolated_call(expl)
         #pragma isolated_call(fmodl)
         #pragma isolated_call(frexpl)
         #pragma isolated_call(ldexpl)
         #pragma isolated_call(logl)
         #pragma isolated_call(log10l)
         #pragma isolated_call(modfl)
         #pragma isolated_call(powl)
         #pragma isolated_call(sinl)
         #pragma isolated_call(sinhl)
         #pragma isolated_call(sqrtl)
         #pragma isolated_call(tanl)
         #pragma isolated_call(tanhl)

         #pragma isolated_call(__powif)
         #pragma isolated_call(__powi)
         #pragma isolated_call(__powil)
      #endif
   #endif

   #if !__ANSI__
      extern double _IMPORT _LNK_CONV _erf(double);
      extern double _IMPORT _LNK_CONV _erfc(double);
      extern double _IMPORT _LNK_CONV _gamma(double);
      extern double _IMPORT _LNK_CONV _hypot(double, double);
      extern double _IMPORT _LNK_CONV _j0(double);
      extern double _IMPORT _LNK_CONV _j1(double);
      extern double _IMPORT _LNK_CONV _jn(int, double);
      extern double _IMPORT _LNK_CONV _y0(double);
      extern double _IMPORT _LNK_CONV _y1(double);
      extern double _IMPORT _LNK_CONV _yn(int, double);
      extern double _IMPORT _LNK_CONV erf(double);
      extern double _IMPORT _LNK_CONV erfc(double);
      extern double _IMPORT _LNK_CONV gamma(double);
      extern double _IMPORT _LNK_CONV hypot(double, double);
      extern double _IMPORT _LNK_CONV j0(double);
      extern double _IMPORT _LNK_CONV j1(double);
      extern double _IMPORT _LNK_CONV jn(int, double);
      extern double _IMPORT _LNK_CONV y0(double);
      extern double _IMPORT _LNK_CONV y1(double);
      extern double _IMPORT _LNK_CONV yn(int, double);

      #if (__IBMC__ || IBMCPP__) && __LIBANSI__ && __IGNERRNO__
         #pragma isolated_call(_erf)
         #pragma isolated_call(_erfc)
         #pragma isolated_call(_gama)
         #pragma isolated_call(_hypot)
         #pragma isolated_call(_j0)
         #pragma isolated_call(_j1)
         #pragma isolated_call(_jn)
         #pragma isolated_call(_y0)
         #pragma isolated_call(_y1)
         #pragma isolated_call(_yn)
         #pragma isolated_call(erf)
         #pragma isolated_call(erfc)
         #pragma isolated_call(gama)
         #pragma isolated_call(hypot)
         #pragma isolated_call(j0)
         #pragma isolated_call(j1)
         #pragma isolated_call(jn)
         #pragma isolated_call(y0)
         #pragma isolated_call(y1)
         #pragma isolated_call(yn)
      #endif

      #if __THW_PPC__
         extern int _ExtendedtoLD(__unaligned long double*);
         extern int _LDtoExtended(__unaligned long double*);
      #endif

      #if __IBMC__ || __IBMCPP__
         #if __WINDOWS__ && __THW_INTEL__
            #pragma map(erf, "?_erf")
            #pragma map(erfc, "?_erfc")
            #pragma map(gamma, "?_gamma")
            #pragma map(hypot, "?_hypot")
            #pragma map(j0, "?_j0")
            #pragma map(j1, "?_j1")
            #pragma map(jn, "?_jn")
            #pragma map(y0, "?_y0")
            #pragma map(y1, "?_y1")
            #pragma map(yn, "?_yn")
         #else
            #pragma map(erf, "_erf")
            #pragma map(erfc, "_erfc")
            #pragma map(gamma, "_gamma")
            #pragma map(hypot, "_hypot")
            #pragma map(j0, "_j0")
            #pragma map(j1, "_j1")
            #pragma map(jn, "_jn")
            #pragma map(y0, "_y0")
            #pragma map(y1, "_y1")
            #pragma map(yn, "_yn")
         #endif
      #else
         #define erf _erf
         #define erfc _erfc
         #define gamma _gamma
         #define hypot _hypot
         #define j0 _j0
         #define j1 _j1
         #define jn _jn
         #define y0 _y0
         #define y1 _y1
         #define yn _yn
      #endif

      #ifndef __SAA_L2__
         extern const long double _IMPORT _LHUGE_VAL;
         #define _LHUGE _LHUGE_VAL
      #endif

      #if __EXTENDED__

         #define HUGE   HUGE_VAL

         #define DOMAIN           1       /* argument domain error */
         #define SING             2       /* argument singularity */
         #define OVERFLOW         3       /* overflow range error */
         #define UNDERFLOW        4       /* underflow range error */
         #define TLOSS            5       /* total loss of precision */
         #define PLOSS            6       /* partial loss of precision */
         #define UNKNOWN          7       /* unknown error probably caused by */
                                          /* changing the 80387 control word */

         #if !__cplusplus || defined __C_complex
            struct complex {
               double x, y;             /* real and imaginary parts */
               };

            double _IMPORT _LNK_CONV _cabs(struct complex);
         #endif

         #define _cabs(z) _hypot((z).x, (z).y)
         #define cabs(a) _cabs(a)

         struct _exception {
            int type;               /* exception type - see below */
            char *name;             /* name of function where error occured */
            double arg1;            /* first argument to function */
            double arg2;            /* second argument (if any) to function */
            double retval;          /* value to be returned by function */
            };

         /* _matherr is defined by the user */

         int _matherr(struct _exception*);
         int  matherr(struct _exception*);

         #if __IBMC__ || __IBMCPP__
            #if __WINDOWS__ && __THW_INTEL__
               #pragma map(matherr, "?_matherr")
            #else
               #pragma map(matherr, "_matherr")
            #endif
         #else
            #define matherr _matherr
         #endif
      #endif
   #endif

   #if __cplusplus
      }
      #if !__COMPATMATH__
         inline float abs(float __x) { return fabsf(__x); }
         inline float acos(float __x) { return acosf(__x); }
         inline float asin(float __x) { return asinf(__x); }
         inline float atan(float __x) { return atanf(__x); }
         inline float atan2(float __y, float __x) { return atan2f(__y, __x); }
         inline float ceil(float __x) { return ceilf(__x); }
         inline float cos(float __x) { return cosf(__x); }
         inline float cosh(float __x) { return coshf(__x); }
         inline float exp(float __x) { return expf(__x); }
         inline float fabs(float __x) { return fabsf(__x); }
         inline float floor(float __x) { return floorf(__x); }
         inline float fmod(float __x, float __y) { return fmodf(__x, __y); }
         inline float frexp(float __x, int *__exp) { return frexpf(__x, __exp); }
         inline float ldexp(float __x, int __exp) { return ldexpf(__x, __exp); }
         inline float log(float __x) { return logf(__x); }
         inline float log10(float __x) { return log10f(__x); }
         inline float modf(float __x, float *__iptr) { return modff(__x, __iptr); }
         inline float pow(float __x, float __y) { return powf(__x, __y); }
         inline float pow(float __x, int __y) { return __powif(__x, __y); }
         inline float sin(float __x) { return sinf(__x); }
         inline float sinh(float __x) { return sinhf(__x); }
         inline float sqrt(float __x) { return sqrtf(__x); }
         inline float tan(float __x) { return tanf(__x); }
         inline float tanh(float __x) { return tanhf(__x); }

         inline double pow(double __x, int __y) { return __powi(__x, __y); }
         inline double abs(double __x) { return fabs(__x); }

         inline long double abs(long double __x) { return fabsl(__x); }
         inline long double acos(long double __x) { return acosl(__x); }
         inline long double asin(long double __x) { return asinl(__x); }
         inline long double atan(long double __x) { return atanl(__x); }
         inline long double atan2(long double __y, long double __x) { return atan2l(__y, __x); }
         inline long double ceil(long double __x) { return ceill(__x); }
         inline long double cos(long double __x) { return cosl(__x); }
         inline long double cosh(long double __x) { return coshl(__x); }
         inline long double exp(long double __x) { return expl(__x); }
         inline long double fabs(long double __x) { return fabsl(__x); }
         inline long double floor(long double __x) { return floorl(__x); }
         inline long double fmod(long double __x, long double __y) { return fmodl(__x, __y); }
         inline long double frexp(long double __x, int *__exp) { return frexpl(__x, __exp); }
         inline long double ldexp(long double __x, int __exp) { return ldexpl(__x, __exp); }
         inline long double log(long double __x) { return logl(__x); }
         inline long double log10(long double __x) { return log10l(__x); }
         inline long double modf(long double __x, long double *__iptr) { return modfl(__x, __iptr); }
         inline long double pow(long double __x, long double __y) { return powl(__x, __y); }
         inline long double pow(long double __x, int __y) { return __powil(__x, __y); }
         inline long double sin(long double __x) { return sinl(__x); }
         inline long double sinh(long double __x) { return sinhl(__x); }
         inline long double sqrt(long double __x) { return sqrtl(__x); }
         inline long double tan(long double __x) { return tanl(__x); }
         inline long double tanh(long double __x) { return tanhl(__x); }
      #endif
   #endif

   #if __IBMC__ || __IBMCPP__
      #pragma info(none)
      #ifndef __CHKHDR__
         #pragma info(restore)
      #endif
      #pragma info(restore)
   #endif
#endif

