#include "il2cpp-config.h" #include #include #include #include "icalls/mscorlib/System/Math.h" #include "vm/Exception.h" namespace il2cpp { namespace icalls { namespace mscorlib { namespace System { double Math::Acos(double val) { return acos(val); } double Math::Asin(double val) { return asin(val); } double Math::Atan(double val) { return atan(val); } double Math::Atan2(double y, double x) { return atan2(y, x); } double Math::Cos(double val) { return cos(val); } double Math::Cosh(double val) { return cosh(val); } double Math::Exp(double val) { return exp(val); } double Math::Floor(double x) { return floor(x); } double Math::Log(double x) { IL2CPP_NOT_IMPLEMENTED_ICALL_NO_ASSERT(Math::Log, "Determin what value of NAN to use"); if (x == 0) return -HUGE_VAL; else if (x < 0) return std::numeric_limits::signaling_NaN(); //return NAN; return log(x); } double Math::Log10(double val) { return log10(val); } static bool IsInteger(double value) { double unused; return std::modf(value, &unused) == 0.0; } double Math::Pow(double val, double exp) { if (std::isnan(val)) return val; if (std::isnan(exp)) return exp; if (val > -1 && val < 1 && exp == -std::numeric_limits::infinity()) return std::numeric_limits::infinity(); if (val > -1 && val < 1 && exp == std::numeric_limits::infinity()) return 0.0; if ((val < -1 || val > 1) && exp == -std::numeric_limits::infinity()) return 0.0; if ((val < -1 || val > 1) && exp == std::numeric_limits::infinity()) return std::numeric_limits::infinity(); if (val < 0) { if (!IsInteger(exp) || exp == std::numeric_limits::infinity() || exp == -std::numeric_limits::infinity()) return std::numeric_limits::quiet_NaN(); } double res = pow(val, exp); if (std::isnan(res)) return 1.0; if (res == -0.0) return 0.0; return res; } double Math::Round(double x) { double int_part, dec_part; int_part = floor(x); dec_part = x - int_part; if (((dec_part == 0.5) && ((2.0 * ((int_part / 2.0) - floor(int_part / 2.0))) != 0.0)) || (dec_part > 0.5)) { int_part++; } return int_part; } double Math::Sin(double val) { return sin(val); } double Math::Sinh(double val) { return sinh(val); } double Math::Sqrt(double val) { return sqrt(val); } double Math::Tan(double val) { return tan(val); } double Math::Tanh(double val) { return tanh(val); } double Math::Round2(double value, int32_t digits, bool away_from_zero) { double p; if (value == HUGE_VAL) return HUGE_VAL; if (value == -HUGE_VAL) return -HUGE_VAL; if (digits == 0 && !away_from_zero) return Round(value); p = pow(10.0, digits); // Note: Migrate to C++11 when possible #if 0 if (away_from_zero) return std::round(value * p) / p; else return std::rint(value * p) / p; #else if (away_from_zero) return (value >= 0.0) ? floor(value * p + 0.5) / p : ceil(value * p - 0.5) / p; else return (value >= 0.0) ? ceil(value * p - 0.5) / p : floor(value * p + 0.5) / p; #endif } double Math::Abs(double value) { return fabs(value); } double Math::Ceiling(double a) { return ceil(a); } double Math::SplitFractionDouble(double* value) { return modf(*value, value); } float Math::Abs(float value) { return fabsf(value); } } /* namespace System */ } /* namespace mscorlib */ } /* namespace icalls */ } /* namespace il2cpp */