#ifndef WTF_MathExtras_h
#define WTF_MathExtras_h
#include <math.h>
#include <time.h>
#if COMPILER(MSVC)
#include "kjs/operations.h"
#include "kjs/value.h"
#include <xmath.h>
#include <limits>
#if HAVE(FLOAT_H)
#include <float.h>
#endif
#endif
#ifndef M_PI
const double piDouble = 3.14159265358979323846;
const float piFloat = 3.14159265358979323846f;
#else
const double piDouble = M_PI;
const float piFloat = static_cast<float>(M_PI);
#endif
#ifndef M_PI_4
const double piOverFourDouble = 0.785398163397448309616;
const float piOverFourFloat = 0.785398163397448309616f;
#else
const double piOverFourDouble = M_PI_4;
const float piOverFourFloat = static_cast<float>(M_PI_4);
#endif
#if COMPILER(MSVC)
inline bool isinf(double num) { return !_finite(num) && !_isnan(num); }
inline bool isnan(double num) { return !!_isnan(num); }
inline long lround(double num) { return static_cast<long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); }
inline long lroundf(float num) { return static_cast<long>(num > 0 ? num + 0.5f : ceilf(num - 0.5f)); }
inline double round(double num) { return num > 0 ? floor(num + 0.5) : ceil(num - 0.5); }
inline float roundf(float num) { return num > 0 ? floorf(num + 0.5f) : ceilf(num - 0.5f); }
inline bool signbit(double num) { return _copysign(1.0, num) < 0; }
inline double nextafter(double x, double y) { return _nextafter(x, y); }
inline float nextafterf(float x, float y) { return x > y ? x - FLT_EPSILON : x + FLT_EPSILON; }
inline double copysign(double x, double y) { return _copysign(x, y); }
inline int isfinite(double x) { return _finite(x); }
inline double wtf_atan2(double x, double y)
{
static double posInf = std::numeric_limits<double>::infinity();
static double negInf = -std::numeric_limits<double>::infinity();
double result = KJS::NaN;
if (x == posInf && y == posInf)
result = piOverFourDouble;
else if (x == posInf && y == negInf)
result = 3 * piOverFourDouble;
else if (x == negInf && y == posInf)
result = -piOverFourDouble;
else if (x == negInf && y == negInf)
result = -3 * piOverFourDouble;
else
result = ::atan2(x, y);
return result;
}
inline double wtf_fmod(double x, double y) { return (!isinf(x) && isinf(y)) ? x : fmod(x, y); }
#define fmod(x, y) wtf_fmod(x, y)
#define atan2(x, y) wtf_atan2(x, y)
#if defined(_CRT_RAND_S)
inline void wtf_random_init()
{
}
inline double wtf_random()
{
unsigned u;
rand_s(&u);
return static_cast<double>(u) / (static_cast<double>(UINT_MAX) + 1.0);
}
#endif // _CRT_RAND_S
#else
inline void wtf_random_init()
{
srand(static_cast<unsigned>(time(0)));
}
inline double wtf_random()
{
return static_cast<double>(rand()) / (static_cast<double>(RAND_MAX) + 1.0);
}
#endif // #if COMPILER(MSVC)
#endif // #ifndef WTF_MathExtras_h