/*
 * |-----------------------------------------------------------|
 * | Copyright (c) 1991, 1990 MIPS Computer Systems, Inc.      |
 * | All Rights Reserved                                       |
 * |-----------------------------------------------------------|
 * |          Restricted Rights Legend                         |
 * | Use, duplication, or disclosure by the Government is      |
 * | subject to restrictions as set forth in                   |
 * | subparagraph (c)(1)(ii) of the Rights in Technical        |
 * | Data and Computer Software Clause of DFARS 252.227-7013.  |
 * |         MIPS Computer Systems, Inc.                       |
 * |         950 DeGuigne Avenue                               |
 * |         Sunnyvale, California 94088-3650, USA             |
 * |-----------------------------------------------------------|
 */
/* $Header: math.h,v 1.13.2.1 92/06/24 13:56:54 marker Exp $ */
/*
 *-------------------------------------------------------------
 *|         RESTRICTED RIGHTS LEGEND                          |
 *| Use, duplication, or disclosure by the Government is      |
 *| subject to restrictions as set forth in subparagraph      |
 *| (c)(1)(ii) of the Rights in Technical Data and Computer   |
 *| Software Clause at DFARS 252.227-7013.                    |
 *|         MIPS Computer Systems, Inc.                       |
 *|         928 Arques Avenue                                 |
 *|         Sunnyvale, CA 94086                               |
 *-------------------------------------------------------------
 */

/*
** ANSI convention for suffixing names, e.g. cosf, will eventually
** result in the corresponding prefixed names, e.g. fcos, being withdrawn.
*/

#ifndef	__MATH_H
#define	__MATH_H

#if  defined(__STDC__)
#ifndef _HUGE_VAL_
#define _HUGE_VAL_
#define  HUGE_VAL	(1.0/0.0)
#endif  /* _HUGE_VAL_ */
#endif  /* __STDC__ */

/* ANSI C, 4.5 Mathematics */


/* 4.5.2 Trigonometric functions */
extern double acos( double );	
extern double asin( double );
extern double atan( double );
extern double atan2( double , double );
extern double cos( double );
extern double sin( double );
extern double tan( double );

extern float acosf( float );	
extern float asinf( float );
extern float atanf( float );
extern float atan2f( float , float );
extern float cosf( float );
extern float sinf( float );
extern float tanf( float );

/* 4.5.3 Hyperbolic functions */
extern double cosh( double );
extern double sinh( double );
extern double tanh( double );

extern float coshf( float ); 
extern float sinhf( float ); 
extern float tanhf( float ); 

/* 4.5.4 Exponential and logarithmic functions */
extern double exp( double );
extern double frexp( double , int *);
extern double ldexp( double , int );
extern double log( double );
extern double log10( double );
extern double modf( double , double *);

extern float expf( float );
/* extern float frexpf( float , int *); */
/* extern float ldexpf( float , int ); */
extern float logf( float );
extern float log10f( float );
/* extern float modff( float , float* ); */

/* 4.5.5 Power functions */
extern double  pow( double , double );
extern double  sqrt( double );

extern float powf( float , float );
extern float sqrtf( float );

/* 4.5.6 Nearest integer, absolute value, and remainder functions */
extern double ceil( double );
extern double fabs( double );
extern double floor( double );
extern double fmod( double , double );

extern float ceilf( float );
/* extern float fabsf( float ); */
extern float floorf( float );
/* extern float fmodf( float , float ); */





#ifndef _POLY9
#if defined(__STDC__)
#if (__STDC__ == 0)
extern int errno, signgam;

struct exception {
	int type;
	char *name;
	double arg1;
	double arg2;
	double retval;
};
/* features from sys v */

extern double gamma(double);
extern int matherr(struct exception *);

/* features from 4.3 BSD */
extern double erf(double), erfc(double);
extern double expm1(double);
extern double log1p(double);
extern double  rint(double);
extern double trunc(double);
extern double lgamma(double);
extern double hypot(double, double), cabs(/*struct {double; double}*/);
extern double copysign(double, double), drem(double, double);
extern double logb(double), scalb(double, int);
extern int finite(double);
extern double j0(double), j1(double), jn(int, double);
extern double y0(double), y1(double), yn(int, double);
extern double cbrt(double);
extern double atof(const char *);

/*
** MIPS single-precision forms. 
*/

/*extern float ferf(float), ferfc(float);*/
extern double asinh(double), acosh(double), atanh(double);
extern float fexp(float), fexpm1(float), expm1f(float);
extern float flog(float), flog10(float), flog1p(float), fpow(float, float);
extern float log1pf(float);
extern float /*ffabs(float),*/ ffloor(float), fceil(float)/*, frint(float)*/;
extern float ftrunc(float), truncf(float);
/*extern float flgamma(float);*/
extern float fhypot(float, float), fcabs(/*struct {float; float}*/);
extern float hypotf(float, float), cabsf(/*struct {float; float}*/);
/*extern float fcopysign(float, float), fdrem(float, float);*/
/*extern float flogb(float), fscalb(float, int);*/
/*extern int ffinite(float);*/
/*extern float fj0(float), fj1(float), fjn(int, float);*/
/*extern float fy0(float), fy1(float), fyn(int, float);*/
extern float fsin(float), fcos(float), ftan(float);
extern float fasin(float), facos(float), fatan(float), fatan2(float, float);
extern float fsinh(float), fcosh(float), ftanh(float);
extern float /*fcbrt(float),*/ fsqrt(float);
/*extern float fmodf(float, float *);*/
/*extern float fldexp(float, int), ffrexp(float, int *);*/
/*extern float fatof(char *);*/

/* some useful constants */
#define M_E	2.7182818284590452354
#define M_LOG2E	1.4426950408889634074
#define M_LOG10E	0.43429448190325182765
#define M_LN2	0.69314718055994530942
#define M_LN10	2.30258509299404568402
#define M_PI	3.14159265358979323846
#define M_PI_2	1.57079632679489661923
#define M_PI_4	0.78539816339744830962
#define M_1_PI	0.31830988618379067154
#define M_2_PI	0.63661977236758134308
#define M_2_SQRTPI	1.12837916709551257390
#define M_SQRT2	1.41421356237309504880
#define M_SQRT1_2	0.70710678118654752440
#define MAXFLOAT	((float)1.701411733192644299e+38)
#define HUGE	MAXFLOAT

#define _ABS(x)	((x) < 0 ? -(x) : (x))
#define _REDUCE(TYPE, X, XN, C1, C2)	{ \
	double x1 = (double)(TYPE)X, x2 = X - x1; \
	X = x1 - (XN) * (C1); X += x2; X -= (XN) * (C2); }
#define _POLY1(x, c)	((c)[0] * (x) + (c)[1])
#define _POLY2(x, c)	(_POLY1((x), (c)) * (x) + (c)[2])
#define _POLY3(x, c)	(_POLY2((x), (c)) * (x) + (c)[3])
#define _POLY4(x, c)	(_POLY3((x), (c)) * (x) + (c)[4])
#define _POLY5(x, c)	(_POLY4((x), (c)) * (x) + (c)[5])
#define _POLY6(x, c)	(_POLY5((x), (c)) * (x) + (c)[6])
#define _POLY7(x, c)	(_POLY6((x), (c)) * (x) + (c)[7])
#define _POLY8(x, c)	(_POLY7((x), (c)) * (x) + (c)[8])
#define _POLY9(x, c)	(_POLY8((x), (c)) * (x) + (c)[9])


#define DOMAIN		1
#define	SING		2
#define	OVERFLOW	3
#define	UNDERFLOW	4
#define	TLOSS		5
#define	PLOSS		6
#endif /*__STDC__ == 0 */

#else / defined(__STDC__) */
extern int errno, signgam;
struct exception {
	int type;
	char *name;
	double arg1;
	double arg2;
	double retval;
};

/* features from sys v */

extern double gamma(double);
extern int matherr(struct exception *);

/* features from 4.3 BSD */
extern double erf(double), erfc(double);
extern double expm1(double);
extern double log1p(double);
extern double  rint(double);
extern double trunc(double);
extern double lgamma(double);
extern double hypot(double, double), cabs(/*struct {double; double}*/);
extern double copysign(double, double), drem(double, double);
extern double logb(double), scalb(double, int);
extern int finite(double);
extern double j0(double), j1(double), jn(int, double);
extern double y0(double), y1(double), yn(int, double);
extern double cbrt(double);
extern double atof(const char *);

/*
** MIPS single-precision forms. 
*/

/*extern float ferf(float), ferfc(float);*/
extern double asinh(double), acosh(double), atanh(double);
extern float fexp(float), fexpm1(float), expm1f(float);
extern float flog(float), flog10(float), flog1p(float), fpow(float, float);
extern float log1pf(float);
extern float /*ffabs(float),*/ ffloor(float), fceil(float)/*, frint(float)*/;
extern float ftrunc(float), truncf(float);
/*extern float flgamma(float);*/
extern float fhypot(float, float), fcabs(/*struct {float; float}*/);
extern float hypotf(float, float), cabsf(/*struct {float; float}*/);
/*extern float fcopysign(float, float), fdrem(float, float);*/
/*extern float flogb(float), fscalb(float, int);*/
/*extern int ffinite(float);*/
/*extern float fj0(float), fj1(float), fjn(int, float);*/
/*extern float fy0(float), fy1(float), fyn(int, float);*/
extern float fsin(float), fcos(float), ftan(float);
extern float fasin(float), facos(float), fatan(float), fatan2(float, float);
extern float fsinh(float), fcosh(float), ftanh(float);
extern float /*fcbrt(float),*/ fsqrt(float);
/*extern float fmodf(float, float *);*/
/*extern float fldexp(float, int), ffrexp(float, int *);*/
/*extern float fatof(char *);*/

/* some useful constants */
#define M_E	2.7182818284590452354
#define M_LOG2E	1.4426950408889634074
#define M_LOG10E	0.43429448190325182765
#define M_LN2	0.69314718055994530942
#define M_LN10	2.30258509299404568402
#define M_PI	3.14159265358979323846
#define M_PI_2	1.57079632679489661923
#define M_PI_4	0.78539816339744830962
#define M_1_PI	0.31830988618379067154
#define M_2_PI	0.63661977236758134308
#define M_2_SQRTPI	1.12837916709551257390
#define M_SQRT2	1.41421356237309504880
#define M_SQRT1_2	0.70710678118654752440
#define MAXFLOAT	((float)1.701411733192644299e+38)
#define HUGE	MAXFLOAT

#define _ABS(x)	((x) < 0 ? -(x) : (x))
#define _REDUCE(TYPE, X, XN, C1, C2)	{ \
	double x1 = (double)(TYPE)X, x2 = X - x1; \
	X = x1 - (XN) * (C1); X += x2; X -= (XN) * (C2); }
#define _POLY1(x, c)	((c)[0] * (x) + (c)[1])
#define _POLY2(x, c)	(_POLY1((x), (c)) * (x) + (c)[2])
#define _POLY3(x, c)	(_POLY2((x), (c)) * (x) + (c)[3])
#define _POLY4(x, c)	(_POLY3((x), (c)) * (x) + (c)[4])
#define _POLY5(x, c)	(_POLY4((x), (c)) * (x) + (c)[5])
#define _POLY6(x, c)	(_POLY5((x), (c)) * (x) + (c)[6])
#define _POLY7(x, c)	(_POLY6((x), (c)) * (x) + (c)[7])
#define _POLY8(x, c)	(_POLY7((x), (c)) * (x) + (c)[8])
#define _POLY9(x, c)	(_POLY8((x), (c)) * (x) + (c)[9])


#define DOMAIN		1
#define	SING		2
#define	OVERFLOW	3
#define	UNDERFLOW	4
#define	TLOSS		5
#define	PLOSS		6
#endif  /* __STDC__ */

#endif

#endif
