// Copyright (c) 2004 David Muse
// See the COPYING file for more information.

#ifndef RUDIMENTS_MATH_H
#define RUDIMENTS_MATH_H

#include <rudiments/private/mathincludes.h>

#ifdef RUDIMENTS_NAMESPACE
namespace rudiments {
#endif

class math {
        public:
                static int      absoluteValue(int j);
                static div_t    divide(int numer, int denom);

                static long     absoluteValue(long j);
                static ldiv_t   divide(long numer, long denom);

                static long long        absoluteValue(long long j);
                static lldiv_t          divide(long long numer,
                                                long long denom);

                static bool     isFinite(float x);
                static bool     isInfinite(float x);

                static bool     isNaN(float x);
                static bool     areNaN(float x, float y);

                static bool     isNormal(float x);
                static bool     isSubNormal(float x);

                static bool     isGreater(float x, float y);
                static bool     isGreaterOrEqual(float x, float y);
                static bool     isLess(float x, float y);
                static bool     isLessOrEqual(float x, float y);
                static bool     isLessOrGreater(float x, float y);

                static bool     isSignBitSet(float x);
                static float    copySignBit(float x, float y);

                static float    arcCosine(float x);
                static float    arcSine(float x);
                static float    arcTangent(float x);
                static float    arcTangent(float y, float x);

                static float    cosine(float x);
                static float    sine(float x);
                static float    tangent(float x);

                static float    hyperbolicArcCosine(float x);
                static float    hyperbolicArcSine(float x);
                static float    hyperbolicArcTangent(float x);

                static float    hyperbolicCosine(float x);
                static float    hyperbolicSine(float x);
                static float    hyperbolicTangent(float x);

                static float    naturalExponent(float x);
                static float    naturalLog(float x);
                static float    naturalExponentMinusOne(float x);
                static float    naturalLogOfPlusOne(float x);

                static float    normalize(float x, int *exp);

                static float    logBase10(float x);

                static float    exponentBase2(float x);
                static float    logBase2(float x);

                static float    power(float x, float y);

                static float    squareRoot(float x);
                static float    cubeRoot(float x);

                static float    hypotenuse(float x, float y);

                static float    computeExponent(float x);
                static int      integralExponent(float x);
                static float    loadExponent(float x, int exp);

                static float    ceiling(float x);
                static float    floor(float x);
                static float    absoluteValue(float x);

                static float    remainder(float x, float y);
                static float    remainder(float x, float y, int *quo);

                static float    truncate(float x);
                static float    nearbyInteger(float x);
                static float    round(float x);
                static float    roundInexact(float x);
                static long             roundToLong(float x);
                static long long        roundToLongLong(float x);
                static long             roundAwayFromZeroToLong(float x);
                static long long        roundAwayFromZeroToLongLong(float x);
                static float    nextAfter(float x, float y);
                static float    nextToward(float x, float y);

                static float    errorFunction(float x);
                static float    complementaryErrorFunction(float x);

                static float    trueGamma(float x);
                static float    naturalLogGamma(float x);

                static float    scaleByRadixToPower(float x, float n);
                static float    scaleByRadixToPower(float x, int n);
                static float    scaleByRadixToPower(float x, long n);

                static float    larger(float x, float y);
                static float    smaller(float x, float y);

                static float    multiplyAndAdd(float x, float y, float z);
                static float    positiveDifference(float x, float y);

                static float    argument(float complex z);
                static float    conjugate(float complex z);
                static float    project(float complex z);
                static float    imaginary(float complex z);
                static float    real(float complex z);




                // double methods
                static bool     isFinite(double x);
                static bool     isInfinite(double x);

                static bool     isNaN(double x);
                static bool     areNaN(double x, double y);

                static bool     isNormal(double x);
                static bool     isSubNormal(double x);

                static bool     isGreater(double x, double y);
                static bool     isGreaterOrEqual(double x, double y);
                static bool     isLess(double x, double y);
                static bool     isLessOrEqual(double x, double y);
                static bool     isLessOrGreater(double x, double y);

                static bool     isSignBitSet(double x);
                static double   copySignBit(double x, double y);

                static double   arcCosine(double x);
                static double   arcSine(double x);
                static double   arcTangent(double x);
                static double   arcTangent(double y, double x);

                static double   cosine(double x);
                static double   sine(double x);
                static double   tangent(double x);

                static double   hyperbolicArcCosine(double x);
                static double   hyperbolicArcSine(double x);
                static double   hyperbolicArcTangent(double x);

                static double   hyperbolicCosine(double x);
                static double   hyperbolicSine(double x);
                static double   hyperbolicTangent(double x);

                static double   naturalExponent(double x);
                static double   naturalLog(double x);
                static double   naturalExponentMinusOne(double x);
                static double   naturalLogOfPlusOne(double x);

                static double   normalize(double x, int *exp);

                static double   logBase10(double x);

                static double   exponentBase2(double x);
                static double   logBase2(double x);

                static double   power(double x, double y);

                static double   squareRoot(double x);
                static double   cubeRoot(double x);

                static double   hypotenuse(double x, double y);

                static double   computeExponent(double x);
                static int      integralExponent(double x);
                static double   loadExponent(double x, int exp);

                static double   ceiling(double x);
                static double   floor(double x);
                static double   absoluteValue(double x);

                static double   remainder(double x, double y);
                static double   remainder(double x, double y, int *quo);

                static double   truncate(double x);
                static double   nearbyInteger(double x);
                static double   round(double x);
                static double   roundInexact(double x);
                static long             roundToLong(double x);
                static long long        roundToLongLong(double x);
                static long             roundAwayFromZeroToLong(double x);
                static long long        roundAwayFromZeroToLongLong(double x);
                static double   nextAfter(double x, double y);
                static double   nextToward(double x, double y);

                static double   errorFunction(double x);
                static double   complementaryErrorFunction(double x);

                static double   trueGamma(double x);
                static double   naturalLogGamma(double x);

                static double   scaleByRadixToPower(double x, double n);
                static double   scaleByRadixToPower(double x, int n);
                static double   scaleByRadixToPower(double x, long n);

                static double   larger(double x, double y);
                static double   smaller(double x, double y);

                static double   multiplyAndAdd(double x, double y, double z);
                static double   positiveDifference(double x, double y);

                static double   argument(double complex z);
                static double   conjugate(double complex z);
                static double   project(double complex z);
                static double   imaginary(double complex z);
                static double   real(double complex z);


                // long double methods
                static bool     isFinite(long double x);
                static bool     isInfinite(long double x);

                static bool     isNaN(long double x);
                static bool     areNaN(long double x, long double y);

                static bool     isNormal(long double x);
                static bool     isSubNormal(long double x);

                static bool     isGreater(long double x, long double y);
                static bool     isGreaterOrEqual(long double x, long double y);
                static bool     isLess(long double x, long double y);
                static bool     isLessOrEqual(long double x, long double y);
                static bool     isLessOrGreater(long double x, long double y);

                static bool             isSignBitSet(long double x);
                static long double      copySignBit(long double x,
                                                        long double y);

                static long double      arcCosine(long double x);
                static long double      arcSine(long double x);
                static long double      arcTangent(long double x);
                static long double      arcTangent(long double y,
                                                        long double x);

                static long double      cosine(long double x);
                static long double      sine(long double x);
                static long double      tangent(long double x);

                static long double      hyperbolicArcCosine(long double x);
                static long double      hyperbolicArcSine(long double x);
                static long double      hyperbolicArcTangent(long double x);

                static long double      hyperbolicCosine(long double x);
                static long double      hyperbolicSine(long double x);
                static long double      hyperbolicTangent(long double x);

                static long double      naturalExponent(long double x);
                static long double      naturalLog(long double x);
                static long double      naturalExponentMinusOne(long double x);
                static long double      naturalLogOfPlusOne(long double x);

                static long double      normalize(long double x, int *exp);

                static long double      logBase10(long double x);

                static long double      exponentBase2(long double x);
                static long double      logBase2(long double x);

                static long double      power(long double x, long double y);

                static long double      squareRoot(long double x);
                static long double      cubeRoot(long double x);

                static long double      hypotenuse(long double x,
                                                        long double y);

                static long double      computeExponent(long double x);
                static int              integralExponent(long double x);
                static long double      loadExponent(long double x, int exp);

                static long double      ceiling(long double x);
                static long double      floor(long double x);
                static long double      absoluteValue(long double x);

                static long double      remainder(long double x,
                                                        long double y);
                static long double      remainder(long double x,
                                                        long double y,
                                                        int *quo);

                static long double      truncate(long double x);
                static long double      nearbyInteger(long double x);
                static long double      round(long double x);
                static long double      roundInexact(long double x);
                static long             roundToLong(long double x);
                static long long        roundToLongLong(long double x);
                static long             roundAwayFromZeroToLong(long double x);
                static long long        roundAwayFromZeroToLongLong(
                                                                long double x);
                static long double      nextAfter(long double x,
                                                        long double y);
                static long double      nextToward(long double x,
                                                        long double y);

                static long double      errorFunction(long double x);
                static long double      complementaryErrorFunction(
                                                                long double x);

                static long double      trueGamma(long double x);
                static long double      naturalLogGamma(long double x);


                static long double      scaleByRadixToPower(long double x,
                                                                long double n);
                static long double      scaleByRadixToPower(long double x,
                                                                int n);
                static long double      scaleByRadixToPower(long double x,
                                                                long n);

                static long double      larger(long double x, long double y);
                static long double      smaller(long double x, long double y);

                static long double      multiplyAndAdd(long double x,
                                                                long double y,
                                                                long double z);
                static long double      positiveDifference(long double x,
                                                                long double y);

                static long double      argument(long double complex z);
                static long double      conjugate(long double complex z);
                static long double      project(long double complex z);
                static long double      imaginary(long double complex z);
                static long double      real(long double complex z);


//      may not be in solaris - 
//              inttypes.h - some integer math functions
//                      imaxabs(),imaxdiv()
//                      strtoimax(),strtoumax(),wcstoimax(),wcstoumax()
//      not in solaris - 
//              sys/param.h - howmany(),roundup(),powerof2(),MIN(),MAX()

};

#ifdef RUDIMENTS_NAMESPACE
}
#endif

#ifdef ENABLE_RUDIMENTS_INLINES
        #include <rudiments/private/mathinlines.h>
#endif

#endif