#ifndef __AMSMATHUTIL25_MATHFNS1_HPP__
#define __AMSMATHUTIL25_MATHFNS1_HPP__

namespace ams
{

bool isnan(double d);
bool isinf(double d);
bool isinfnan(double d);
bool isnan(float f);
bool isinf(float f);
bool isinfnan(float f);

double arg(double x, double y);
float arg(float x, float y);

double sgn(double d);
float sgn(float f);


//It has come to my attention that the behavior of Cs
//fmod is odd: Negative numbers have negative moduli
//I need to fix this with a proper modular function, whose values are in [0,N)
double mod(double a, double b);
float mod(float a, float b);
int32_t mod(int32_t a, int32_t b);
int64_t mod(int64_t a, int64_t b);

int32_t truediv(int32_t x, int32_t y);
int64_t truediv(int64_t x, int64_t y);

double abs(double a);
float abs(float a);
int32_t abs(int32_t a);
int64_t abs(int64_t a);

template<typename T> T max(T a, T b);
template<typename T> T min(T a, T b);
template<typename T> T max(T a, T b, T c);
template<typename T> T min(T a, T b, T c);

//generic implementations
template<typename T> T max(T a, T b)
{
    T ret = (a>b)? a : b;
    return ret;
}

template<typename T> T min(T a, T b)
{
    T ret = (a<b)? a : b;
    return ret;
}

template<typename T> T max(T a, T b, T c)
{
    T ret = a;
    ret = (ret<b) ? b : ret;
    ret = (ret<c) ? c : ret;
    return ret;
    
}

template<typename T> T min(T a, T b, T c)
{
    T ret = a;
    ret = (ret>b) ? b : ret;
    ret = (ret>c) ? c : ret;
    return ret;
}


}; //end namespace ams

#endif

