/* This file is part of Fennix C Library. Fennix C Library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix C Library. If not, see . */ #include #include #include #include #include #include #include export int signgam; export double acos(double x) { if (x < -1.0 || x > 1.0) { errno = EDOM; return NAN; } return atan2(sqrt(1.0 - x * x), x); } export float acosf(float x) { if (x < -1.0f || x > 1.0f) { errno = EDOM; return NAN; } return atan2f(sqrtf(1.0f - x * x), x); } export double acosh(double x) { if (x < 1.0) { errno = EDOM; return NAN; } return log(x + sqrt(x * x - 1.0)); } export float acoshf(float x) { if (x < 1.0f) { errno = EDOM; return NAN; } return logf(x + sqrtf(x * x - 1.0f)); } export long double acoshl(long double x) { if (x < 1.0L) { errno = EDOM; return NAN; } return logl(x + sqrtl(x * x - 1.0L)); } export long double acosl(long double x) { if (x < -1.0L || x > 1.0L) { errno = EDOM; return NAN; } return atan2l(sqrtl(1.0L - x * x), x); } export double asin(double x) { if (x < -1.0 || x > 1.0) { errno = EDOM; return NAN; } return atan2(x, sqrt(1.0 - x * x)); } export float asinf(float x) { if (x < -1.0f || x > 1.0f) { errno = EDOM; return NAN; } return atan2f(x, sqrtf(1.0f - x * x)); } export double asinh(double x) { return log(x + sqrt(x * x + 1.0)); } export float asinhf(float x) { return logf(x + sqrtf(x * x + 1.0f)); } export long double asinhl(long double x) { return logl(x + sqrtl(x * x + 1.0L)); } export long double asinl(long double x) { if (x < -1.0L || x > 1.0L) { errno = EDOM; return NAN; } return atan2l(x, sqrtl(1.0L - x * x)); } export double atan(double x) { return atan2(x, 1.0); } export double atan2(double y, double x) { if (x > 0.0) { return atan(y / x); } else if (x < 0.0 && y >= 0.0) { return atan(y / x) + M_PI; } else if (x < 0.0 && y < 0.0) { return atan(y / x) - M_PI; } else if (x == 0.0 && y > 0.0) { return M_PI_2; } else if (x == 0.0 && y < 0.0) { return -M_PI_2; } else { errno = EDOM; return NAN; } } export float atan2f(float y, float x) { if (x > 0.0f) { return atanf(y / x); } else if (x < 0.0f && y >= 0.0f) { return atanf(y / x) + (float)M_PI; } else if (x < 0.0f && y < 0.0f) { return atanf(y / x) - (float)M_PI; } else if (x == 0.0f && y > 0.0f) { return (float)M_PI_2; } else if (x == 0.0f && y < 0.0f) { return -(float)M_PI_2; } else { errno = EDOM; return NAN; } } export long double atan2l(long double y, long double x) { if (x > 0.0L) { return atanl(y / x); } else if (x < 0.0L && y >= 0.0L) { return atanl(y / x) + M_PIl; } else if (x < 0.0L && y < 0.0L) { return atanl(y / x) - M_PIl; } else if (x == 0.0L && y > 0.0L) { return M_PI_2l; } else if (x == 0.0L && y < 0.0L) { return -M_PI_2l; } else { errno = EDOM; return NAN; } } export float atanf(float x) { return atan2f(x, 1.0f); } export double atanh(double x) { if (x <= -1.0 || x >= 1.0) { errno = EDOM; return NAN; } return 0.5 * log((1.0 + x) / (1.0 - x)); } export float atanhf(float x) { if (x <= -1.0f || x >= 1.0f) { errno = EDOM; return NAN; } return 0.5f * logf((1.0f + x) / (1.0f - x)); } export long double atanhl(long double x) { if (x <= -1.0L || x >= 1.0L) { errno = EDOM; return NAN; } return 0.5L * logl((1.0L + x) / (1.0L - x)); } export long double atanl(long double x) { return atan2l(x, 1.0L); } export double cbrt(double x) { return pow(x, 1.0 / 3.0); } export float cbrtf(float x) { return powf(x, 1.0f / 3.0f); } export long double cbrtl(long double x) { return powl(x, 1.0L / 3.0L); } export double ceil(double x) { if (x == (double)((long)x)) { return x; } return (x > 0.0) ? (double)((long)x + 1) : (double)((long)x); } export float ceilf(float x) { if (x == (float)((long)x)) { return x; } return (x > 0.0f) ? (float)((long)x + 1) : (float)((long)x); } export long double ceill(long double x) { if (x == (long double)((long)x)) { return x; } return (x > 0.0L) ? (long double)((long)x + 1) : (long double)((long)x); } export double copysign(double x, double y) { return (y < 0.0) ? -fabs(x) : fabs(x); } export float copysignf(float x, float y) { return (y < 0.0f) ? -fabsf(x) : fabsf(x); } export long double copysignl(long double x, long double y) { return (y < 0.0L) ? -fabsl(x) : fabsl(x); } export double cos(double x) { return sin(x + M_PI_2); } export float cosf(float x) { return sinf(x + (float)M_PI_2); } export double cosh(double x) { return (exp(x) + exp(-x)) / 2.0; } export float coshf(float x) { return (expf(x) + expf(-x)) / 2.0f; } export long double coshl(long double x) { return (expl(x) + expl(-x)) / 2.0L; } export long double cosl(long double x) { return sinl(x + M_PI_2l); } export double erf(double x) { double t = 1.0 / (1.0 + 0.5 * fabs(x)); double tau = t * exp(-x * x - 1.26551223 + t * (1.00002368 + t * (0.37409196 + t * (0.09678418 + t * (-0.18628806 + t * (0.27886807 + t * (-1.13520398 + t * (1.48851587 + t * (-0.82215223 + t * 0.17087277))))))))); return (x >= 0.0) ? 1.0 - tau : tau - 1.0; } export double erfc(double x) { return 1.0 - erf(x); } export float erfcf(float x) { return 1.0f - erff(x); } export long double erfcl(long double x) { return 1.0L - erfl(x); } export float erff(float x) { float t = 1.0f / (1.0f + 0.5f * fabsf(x)); float tau = t * expf(-x * x - 1.26551223f + t * (1.00002368f + t * (0.37409196f + t * (0.09678418f + t * (-0.18628806f + t * (0.27886807f + t * (-1.13520398f + t * (1.48851587f + t * (-0.82215223f + t * 0.17087277f))))))))); return (x >= 0.0f) ? 1.0f - tau : tau - 1.0f; } export long double erfl(long double x) { long double t = 1.0L / (1.0L + 0.5L * fabsl(x)); long double tau = t * expl(-x * x - 1.26551223L + t * (1.00002368L + t * (0.37409196L + t * (0.09678418L + t * (-0.18628806L + t * (0.27886807L + t * (-1.13520398L + t * (1.48851587L + t * (-0.82215223L + t * 0.17087277L))))))))); return (x >= 0.0L) ? 1.0L - tau : tau - 1.0L; } export double exp(double x) { if (x == 0.0) { return 1.0; } if (x < 0.0) { return 1.0 / exp(-x); } double result = 1.0; double term = 1.0; for (int i = 1; term > DBL_EPSILON || term < -DBL_EPSILON; i++) { term *= x / i; result += term; } return result; } export double exp2(double x) { if (x == 0.0) { return 1.0; } if (x < 0.0) { return 1.0 / exp2(-x); } double result = 1.0; double term = 1.0; for (int i = 1; term > DBL_EPSILON || term < -DBL_EPSILON; i++) { term *= x * log(2.0) / i; result += term; } return result; } export float exp2f(float x) { if (x == 0.0f) { return 1.0f; } if (x < 0.0f) { return 1.0f / exp2f(-x); } float result = 1.0f; float term = 1.0f; for (int i = 1; term > FLT_EPSILON || term < -FLT_EPSILON; i++) { term *= x * logf(2.0f) / i; result += term; } return result; } export long double exp2l(long double x) { return powl(2.0L, x); } export float expf(float x) { return powf(M_E, x); } export long double expl(long double x) { return powl(M_E, x); } export double expm1(double x) { return exp(x) - 1.0; } export float expm1f(float x) { return expf(x) - 1.0f; } export long double expm1l(long double x) { return expl(x) - 1.0L; } export double fabs(double x) { return (x < 0.0) ? -x : x; } export float fabsf(float x) { return (x < 0.0f) ? -x : x; } export long double fabsl(long double x) { return (x < 0.0L) ? -x : x; } export double fdim(double x, double y) { return (x > y) ? x - y : 0.0; } export float fdimf(float x, float y) { return (x > y) ? x - y : 0.0f; } export long double fdiml(long double x, long double y) { return (x > y) ? x - y : 0.0L; } export double floor(double x) { if (x == (double)((long)x)) { return x; } return (x > 0.0) ? (double)((long)x) : (double)((long)x - 1); } export float floorf(float x) { if (x == (float)((long)x)) { return x; } return (x > 0.0f) ? (float)((long)x) : (float)((long)x - 1); } export long double floorl(long double x) { if (x == (long double)((long)x)) { return x; } return (x > 0.0L) ? (long double)((long)x) : (long double)((long)x - 1); } export double fma(double x, double y, double z) { return x * y + z; } export float fmaf(float x, float y, float z) { return x * y + z; } export long double fmal(long double x, long double y, long double z) { return x * y + z; } export double fmax(double x, double y) { return (x > y) ? x : y; } export float fmaxf(float x, float y) { return (x > y) ? x : y; } export long double fmaxl(long double x, long double y) { return (x > y) ? x : y; } export double fmin(double x, double y) { return (x < y) ? x : y; } export float fminf(float x, float y) { return (x < y) ? x : y; } export long double fminl(long double x, long double y) { return (x < y) ? x : y; } export double fmod(double x, double y) { if (y == 0.0) { errno = EDOM; return NAN; } return x - y * floor(x / y); } export float fmodf(float x, float y) { if (y == 0.0f) { errno = EDOM; return NAN; } return x - y * floorf(x / y); } export long double fmodl(long double x, long double y) { if (y == 0.0L) { errno = EDOM; return NAN; } return x - y * floorl(x / y); } export double frexp(double num, int *exp) { if (num == 0.0) { *exp = 0; return 0.0; } double abs_num = fabs(num); *exp = (int)log2(abs_num) + 1; double mantissa = abs_num / pow(2.0, *exp); if (num < 0.0) { mantissa = -mantissa; } return mantissa; } export float frexpf(float num, int *exp) { if (num == 0.0f) { *exp = 0; return 0.0f; } float abs_num = fabsf(num); *exp = (int)log2f(abs_num) + 1; float mantissa = abs_num / powf(2.0f, *exp); if (num < 0.0f) { mantissa = -mantissa; } return mantissa; } export long double frexpl(long double num, int *exp) { if (num == 0.0L) { *exp = 0; return 0.0L; } long double abs_num = fabsl(num); *exp = (int)log2l(abs_num) + 1; long double mantissa = abs_num / powl(2.0L, *exp); if (num < 0.0L) { mantissa = -mantissa; } return mantissa; } export double hypot(double x, double y) { return sqrt(x * x + y * y); } export float hypotf(float x, float y) { return sqrtf(x * x + y * y); } export long double hypotl(long double x, long double y) { return sqrtl(x * x + y * y); } export int ilogb(double x) { if (x == 0.0) { errno = EDOM; return FP_ILOGB0; } if (isnan(x)) { errno = EDOM; return FP_ILOGBNAN; } return (int)log2(fabs(x)); } export int ilogbf(float x) { if (x == 0.0f) { errno = EDOM; return FP_ILOGB0; } if (isnan(x)) { errno = EDOM; return FP_ILOGBNAN; } return (int)log2f(fabsf(x)); } export int ilogbl(long double x) { if (x == 0.0L) { errno = EDOM; return FP_ILOGB0; } if (isnan(x)) { errno = EDOM; return FP_ILOGBNAN; } return (int)log2l(fabsl(x)); } export double j0(double x) { double ax = fabs(x); if (ax < 8.0) { double y = x * x; double ans1 = 57568490574.0 + y * (-13362590354.0 + y * (651619640.7 + y * (-11214424.18 + y * (77392.33017 + y * (-184.9052456))))); double ans2 = 57568490411.0 + y * (1029532985.0 + y * (9494680.718 + y * (59272.64853 + y * (267.8532712 + y * 1.0)))); return ans1 / ans2; } else { double z = 8.0 / ax; double y = z * z; double xx = ax - 0.785398164; double ans1 = 1.0 + y * (-0.1098628627e-2 + y * (0.2734510407e-4 + y * (-0.2073370639e-5 + y * 0.2093887211e-6))); double ans2 = -0.1562499995e-1 + y * (0.1430488765e-3 + y * (-0.6911147651e-5 + y * (0.7621095161e-6 - y * 0.934935152e-7))); return sqrt(0.636619772 / ax) * (cos(xx) * ans1 - z * sin(xx) * ans2); } } export double j1(double x) { double ax = fabs(x); if (ax < 8.0) { double y = x * x; double ans1 = x * (72362614232.0 + y * (-7895059235.0 + y * (242396853.1 + y * (-2972611.439 + y * (15704.48260 + y * (-30.16036606)))))); double ans2 = 144725228442.0 + y * (2300535178.0 + y * (18583304.74 + y * (99447.43394 + y * (376.9991397 + y * 1.0)))); return ans1 / ans2; } else { double z = 8.0 / ax; double y = z * z; double xx = ax - 2.356194491; double ans1 = 1.0 + y * (0.183105e-2 + y * (-0.3516396496e-4 + y * (0.2457520174e-5 + y * (-0.240337019e-6)))); double ans2 = 0.04687499995 + y * (-0.2002690873e-3 + y * (0.8449199096e-5 + y * (-0.88228987e-6 + y * 0.105787412e-6))); double ans = sqrt(0.636619772 / ax) * (cos(xx) * ans1 - z * sin(xx) * ans2); if (x < 0.0) ans = -ans; return ans; } } #define BIGNO 1.0e10 #define BIGNI 1.0e-10 export double jn(int n, double x) { if (n == 0) return j0(x); if (n == 1) return j1(x); if (x == 0.0) return 0.0; double ax = fabs(x); double tox = 2.0 / ax; double bj, bjm, bjp, sum; int j, m; if (ax > (double)n) { bjm = j0(ax); bj = j1(ax); for (j = 1; j < n; j++) { bjp = j * tox * bj - bjm; bjm = bj; bj = bjp; } sum = bj; } else { #define ACC 40 m = 2 * ((n + (int)sqrt(ACC * n)) / 2); bjp = sum = 0.0; bj = 1.0; for (j = m; j > 0; j--) { bjm = j * tox * bj - bjp; bjp = bj; bj = bjm; if (fabs(bj) > BIGNO) { bj *= BIGNI; bjp *= BIGNI; sum *= BIGNI; } if (j == n) sum = bjp; } sum *= j0(ax) / bj; } return (x < 0.0 && (n & 1)) ? -sum : sum; } export double ldexp(double x, int exp) { return x * pow(2.0, exp); } export float ldexpf(float x, int exp) { return x * powf(2.0f, exp); } export long double ldexpl(long double x, int exp) { return x * powl(2.0L, exp); } export double lgamma(double x) { if (x <= 0.0 && floor(x) == x) { errno = EDOM; return NAN; } double result = 0.0; if (x < 0.5) { result = log(M_PI) - log(sin(M_PI * x)) - lgamma(1.0 - x); } else { x -= 1.0; double a = 0.99999999999980993; double coefficients[] = { 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7}; for (int i = 0; i < 8; i++) { a += coefficients[i] / (x + i + 1); } double t = x + 7.5; result = log(2.5066282746310007 * a) - t + log(t) * (x + 0.5); } return result; } export float lgammaf(float x) { return (float)lgamma((double)x); } export long double lgammal(long double x) { return (long double)lgamma((double)x); } export long long llrint(double x) { return (long long)round(x); } export long long llrintf(float x) { return (long long)roundf(x); } export long long llrintl(long double x) { return (long long)roundl(x); } export long long llround(double x) { return (long long)round(x); } export long long llroundf(float x) { return (long long)roundf(x); } export long long llroundl(long double x) { return (long long)roundl(x); } export double log(double x) { if (x <= 0.0) { errno = EDOM; return NAN; } double result = 0.0; double y = (x - 1) / (x + 1); double y2 = y * y; double term = y; for (int i = 1; term > DBL_EPSILON || term < -DBL_EPSILON; i += 2) { result += term / i; term *= y2; } return 2 * result; } export double log10(double x) { return log(x) / log(10.0); } export float log10f(float x) { return (float)log10((double)x); } export long double log10l(long double x) { return (long double)log10((double)x); } export double log1p(double x) { if (x <= -1.0) { errno = EDOM; return NAN; } double result = 0.0; double term = x; for (int i = 1; term > DBL_EPSILON || term < -DBL_EPSILON; i++) { result += term / i; term *= -x; } return result; } export float log1pf(float x) { return (float)log1p((double)x); } export long double log1pl(long double x) { return (long double)log1p((double)x); } export double log2(double x) { return log(x) / log(2.0); } export float log2f(float x) { return (float)log2((double)x); } export long double log2l(long double x) { return (long double)log2((double)x); } export double logb(double x) { if (x == 0.0) { errno = ERANGE; return -HUGE_VAL; } if (isnan(x)) { errno = EDOM; return NAN; } if (isinf(x)) { return HUGE_VAL; } int exp; frexp(x, &exp); return (double)(exp - 1); } export float logbf(float x) { return (float)logb((double)x); } export long double logbl(long double x) { return (long double)logb((double)x); } export float logf(float x) { return (float)log((double)x); } export long double logl(long double x) { return (long double)log((double)x); } export long lrint(double x) { if (isnan(x) || isinf(x)) { errno = EDOM; return 0; } return (long)rint(x); } export long lrintf(float x) { if (isnan(x) || isinf(x)) { errno = EDOM; return 0; } return (long)rintf(x); } export long lrintl(long double x) { if (isnan(x) || isinf(x)) { errno = EDOM; return 0; } return (long)rintl(x); } export long lround(double x) { return (long)round(x); } export long lroundf(float x) { return (long)roundf(x); } export long lroundl(long double x) { return (long)roundl(x); } export double modf(double x, double *iptr) { *iptr = floor(x); return x - *iptr; } export float modff(float value, float *iptr) { *iptr = floorf(value); return value - *iptr; } export long double modfl(long double x, long double *iptr) { *iptr = floorl(x); return x - *iptr; } export double nan(const char *tagp) { return NAN; } export float nanf(const char *tagp) { return NAN; } export long double nanl(const char *tagp) { return NAN; } export double nearbyint(double x) { return round(x); } export float nearbyintf(float x) { return roundf(x); } export long double nearbyintl(long double x) { return roundl(x); } export double nextafter(double x, double y) { if (isnan(x) || isnan(y)) { return NAN; } if (x == y) { return y; } if (x == 0.0) { return (y > 0.0) ? DBL_MIN : -DBL_MIN; } union { double d; uint64_t u; } ux = {x}; if ((x > 0.0) == (y > x)) { ux.u++; } else { ux.u--; } return ux.d; } export float nextafterf(float x, float y) { if (isnan(x) || isnan(y)) { return NAN; } if (x == y) { return y; } if (x == 0.0f) { return (y > 0.0f) ? FLT_MIN : -FLT_MIN; } union { float f; uint32_t u; } ux = {x}; if ((x > 0.0f) == (y > x)) { ux.u++; } else { ux.u--; } return ux.f; } export long double nextafterl(long double x, long double y) { if (isnan(x) || isnan(y)) { return NAN; } if (x == y) { return y; } if (x == 0.0L) { return (y > 0.0L) ? LDBL_MIN : -LDBL_MIN; } union { long double ld; uint64_t u[2]; } ux = {x}; if ((x > 0.0L) == (y > x)) { ux.u[0]++; if (ux.u[0] == 0) { ux.u[1]++; } } else { if (ux.u[0] == 0) { ux.u[1]--; } ux.u[0]--; } return ux.ld; } export double nexttoward(double x, long double y) { return nextafterl(x, y); } export float nexttowardf(float x, long double y) { return nextafterl(x, y); } export long double nexttowardl(long double x, long double y) { return nextafterl(x, y); } export double pow(double x, double y) { if (x == 0.0 && y == 0.0) { errno = EDOM; return NAN; } return exp(y * log(x)); } export float powf(float x, float y) { return (float)pow((double)x, (double)y); } export long double powl(long double x, long double y) { return (long double)pow((double)x, (double)y); } export double remainder(double x, double y) { if (y == 0.0) { errno = EDOM; return NAN; } return x - y * round(x / y); } export float remainderf(float x, float y) { return (float)remainder((double)x, (double)y); } export long double remainderl(long double x, long double y) { return (long double)remainder((double)x, (double)y); } export double remquo(double x, double y, int *quo) { if (y == 0.0) { errno = EDOM; return NAN; } double result = remainder(x, y); *quo = (int)((x - result) / y); return result; } export float remquof(float x, float y, int *quo) { return (float)remquo((double)x, (double)y, quo); } export long double remquol(long double x, long double y, int *quo) { return (long double)remquo((double)x, (double)y, quo); } export double rint(double x) { int current_rounding_mode = fegetround(); double result; switch (current_rounding_mode) { case FE_TONEAREST: result = nearbyint(x); break; case FE_DOWNWARD: result = floor(x); break; case FE_UPWARD: result = ceil(x); break; case FE_TOWARDZERO: result = trunc(x); break; default: result = nearbyint(x); break; } if (result != x) { feraiseexcept(FE_INEXACT); } return result; } export float rintf(float x) { int current_rounding_mode = fegetround(); float result; switch (current_rounding_mode) { case FE_TONEAREST: result = nearbyintf(x); break; case FE_DOWNWARD: result = floorf(x); break; case FE_UPWARD: result = ceilf(x); break; case FE_TOWARDZERO: result = truncf(x); break; default: result = nearbyintf(x); break; } if (result != x) { feraiseexcept(FE_INEXACT); } return result; } export long double rintl(long double x) { int current_rounding_mode = fegetround(); long double result; switch (current_rounding_mode) { case FE_TONEAREST: result = nearbyintl(x); break; case FE_DOWNWARD: result = floorl(x); break; case FE_UPWARD: result = ceill(x); break; case FE_TOWARDZERO: result = truncl(x); break; default: result = nearbyintl(x); break; } if (result != x) { feraiseexcept(FE_INEXACT); } return result; } export double round(double x) { return (x < 0.0) ? ceil(x - 0.5) : floor(x + 0.5); } export float roundf(float x) { return (x < 0.0f) ? ceilf(x - 0.5f) : floorf(x + 0.5f); } export long double roundl(long double x) { return (x < 0.0L) ? ceill(x - 0.5L) : floorl(x + 0.5L); } export double scalb(double x, double n) { if (isnan(x) || isnan(n)) { return NAN; } if (n == 0.0) { return x; } if (isinf(x) && !isinf(n)) { return x; } if (x == 0.0 && !isinf(n)) { return x; } if (x == 0.0 && isinf(n)) { errno = EDOM; return NAN; } if (isinf(x) && isinf(n)) { errno = EDOM; return NAN; } if (isinf(n)) { return (n > 0.0) ? HUGE_VAL : 0.0; } if (isinf(-n)) { return (n < 0.0) ? -HUGE_VAL : 0.0; } int exp = (int)n; double result = x; if (exp > 0) { while (exp > 0) { result *= 2.0; exp--; } } else { while (exp < 0) { result /= 2.0; exp++; } } return result; } export double scalbln(double x, long n) { return x * pow(2.0, (double)n); } export float scalblnf(float x, long n) { return x * powf(2.0f, (float)n); } export long double scalblnl(long double x, long n) { return x * powl(2.0L, (long double)n); } export double scalbn(double x, int n) { return x * pow(2.0, (double)n); } export float scalbnf(float x, int n) { return x * powf(2.0f, (float)n); } export long double scalbnl(long double x, int n) { return x * powl(2.0L, (long double)n); } export double sin(double x) { double result = 0.0; double term = x; double x2 = x * x; for (int i = 1; term > DBL_EPSILON || term < -DBL_EPSILON; i += 2) { result += term; term *= -x2 / ((i + 1) * (i + 2)); } return result; } export float sinf(float x) { return (float)sin((double)x); } export double sinh(double x) { return (exp(x) - exp(-x)) / 2.0; } export float sinhf(float x) { return (float)sinh((double)x); } export long double sinhl(long double x) { return (long double)sinh((double)x); } export long double sinl(long double x) { return (long double)sin((double)x); } export double sqrt(double x) { if (x < 0.0) { errno = EDOM; return NAN; } double result = x; double last_result; do { last_result = result; result = (result + x / result) / 2.0; } while (fabs(result - last_result) > DBL_EPSILON); return result; } export float sqrtf(float x) { return (float)sqrt((double)x); } export long double sqrtl(long double x) { return (long double)sqrt((double)x); } export double tan(double x) { return sin(x) / cos(x); } export float tanf(float x) { return (float)tan((double)x); } export double tanh(double x) { return (exp(x) - exp(-x)) / (exp(x) + exp(-x)); } export float tanhf(float x) { return (float)tanh((double)x); } export long double tanhl(long double x) { return (long double)tanh((double)x); } export long double tanl(long double x) { return (long double)tan((double)x); } export double tgamma(double x) { if (x <= 0.0 && floor(x) == x) { errno = EDOM; return NAN; } double result = 1.0; if (x < 0.5) { return M_PI / (sin(M_PI * x) * tgamma(1.0 - x)); } x -= 1.0; double coefficients[] = { 1.000000000190015, 76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.001208650973866179, -0.000005395239384953}; double y = x + 5.5; y -= (x + 0.5) * log(y); for (int i = 0; i < 7; i++) { result += coefficients[i] / (x + i + 1); } return sqrt(2.0 * M_PI) * pow(x + 5.5, x + 0.5) * exp(-y) * result; } export float tgammaf(float x) { return (float)tgamma((double)x); } export long double tgammal(long double x) { return (long double)tgamma((double)x); } export double trunc(double x) { return (x < 0.0) ? ceil(x) : floor(x); } export float truncf(float x) { return (x < 0.0f) ? ceilf(x) : floorf(x); } export long double truncl(long double x) { return (x < 0.0L) ? ceill(x) : floorl(x); } export double y0(double x) { if (x < 8.0) { double y = x * x; double ans1 = -2957821389.0 + y * (7062834065.0 + y * (-512359803.6 + y * (10879881.29 + y * (-86327.92757 + y * 228.4622733)))); double ans2 = 40076544269.0 + y * (745249964.8 + y * (7189466.438 + y * (47447.26470 + y * (226.1030244 + y * 1.0)))); return (ans1 / ans2) + 0.636619772 * j0(x) * log(x); } else { double z = 8.0 / x; double y = z * z; double xx = x - 0.785398164; double ans1 = 1.0 + y * (-0.1098628627e-2 + y * (0.2734510407e-4 + y * (-0.2073370639e-5 + y * 0.2093887211e-6))); double ans2 = -0.1562499995e-1 + y * (0.1430488765e-3 + y * (-0.6911147651e-5 + y * (0.7621095161e-6 - y * 0.934935152e-7))); return sqrt(0.636619772 / x) * (sin(xx) * ans1 + z * cos(xx) * ans2); } } export double y1(double x) { if (x < 8.0) { double y = x * x; double ans1 = x * (-0.4900604943e13 + y * (0.1275274390e13 + y * (-0.5153438139e11 + y * (0.7349264551e9 + y * (-0.4237922726e7 + y * 0.8511937935e4))))); double ans2 = 0.2499580570e14 + y * (0.4244419664e12 + y * (0.3733650367e10 + y * (0.2245904002e8 + y * (0.1020426050e6 + y * (0.3549632885e3 + y))))); return (ans1 / ans2) + 0.636619772 * (j1(x) * log(x) - 1.0 / x); } else { double z = 8.0 / x; double y = z * z; double xx = x - 2.356194491; double ans1 = 1.0 + y * (0.183105e-2 + y * (-0.3516396496e-4 + y * (0.2457520174e-5 + y * (-0.240337019e-6)))); double ans2 = 0.04687499995 + y * (-0.2002690873e-3 + y * (0.8449199096e-5 + y * (-0.88228987e-6 + y * 0.105787412e-6))); return sqrt(0.636619772 / x) * (sin(xx) * ans1 + z * cos(xx) * ans2); } } export double yn(int n, double x) { if (n == 0) return y0(x); if (n == 1) return y1(x); if (x == 0.0) return -HUGE_VAL; if (x < 0.0) return NAN; double tox = 2.0 / x; double by, bym, byp; int j; bym = y0(x); by = y1(x); for (j = 1; j < n; j++) { byp = j * tox * by - bym; bym = by; by = byp; } return by; } void sincos(double x, double *s, double *c) { *s = sin(x); *c = cos(x); } void sincosf(float x, float *s, float *c) { *s = sinf(x); *c = cosf(x); } void sincosl(long double x, long double *s, long double *c) { *s = sinl(x); *c = cosl(x); }