Unified · Split
| @@ -46,7 +46,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. · 45 unmodified lines | |||
| 46 | /* fpclassify */ | 46 | /* fpclassify */ |
| 47 | 47 | ||
| 48 | __CRT_INLINE int __cdecl __fpclassify (double x) { | 48 | __CRT_INLINE int __cdecl __fpclassify (double x) { |
| 49 | union {double f; uint64_t i;} u = {x}; | 49 | union {double f; uint64_t i;} u = {.f = x}; |
| 50 | int e = u.i>>52 & 0x7ff; | 50 | int e = u.i>>52 & 0x7ff; |
| 51 | if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; | 51 | if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; |
| 52 | if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE; | 52 | if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE; |
| @@ -54,7 +54,7 @@ __CRT_INLINE int __cdecl __fpclassify (double x) { · 1 unmodified line | |||
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | __CRT_INLINE int __cdecl __fpclassifyf (float x) { | 56 | __CRT_INLINE int __cdecl __fpclassifyf (float x) { |
| 57 | union {float f; uint32_t i;} u = {x}; | 57 | union {float f; uint32_t i;} u = {.f = x}; |
| 58 | int e = u.i>>23 & 0xff; | 58 | int e = u.i>>23 & 0xff; |
| 59 | if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; | 59 | if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; |
| 60 | if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE; | 60 | if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE; |
| @@ -69,13 +69,13 @@ __CRT_INLINE int __cdecl __fpclassifyl (long double x) { · 8 unmodified lines | |||
| 69 | /* signbit */ | 69 | /* signbit */ |
| 70 | 70 | ||
| 71 | __CRT_INLINE int __cdecl __signbit (double x) { | 71 | __CRT_INLINE int __cdecl __signbit (double x) { |
| 72 | union {double d; uint64_t i;} y = { x }; | 72 | union {double f; uint64_t i;} u = {.f = x}; |
| 73 | return y.i>>63; | 73 | return u.i>>63; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | __CRT_INLINE int __cdecl __signbitf (float x) { | 76 | __CRT_INLINE int __cdecl __signbitf (float x) { |
| 77 | union {float f; uint32_t i; } y = { x }; | 77 | union {float f; uint32_t i; } u = {.f = x}; |
| 78 | return y.i>>31; | 78 | return u.i>>31; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | __CRT_INLINE int __cdecl __signbitl (long double x) { | 81 | __CRT_INLINE int __cdecl __signbitl (long double x) { |
| @@ -128,7 +128,7 @@ __CRT_INLINE long double __cdecl fmaxl (long double x, long double y) { · 46 unmodified lines | |||
| 128 | } while(0) | 128 | } while(0) |
| 129 | 129 | ||
| 130 | __CRT_INLINE double __cdecl round (double x) { | 130 | __CRT_INLINE double __cdecl round (double x) { |
| 131 | union {double f; uint64_t i;} u = {x}; | 131 | union {double f; uint64_t i;} u = {.f = x}; |
| 132 | int e = u.i >> 52 & 0x7ff; | 132 | int e = u.i >> 52 & 0x7ff; |
| 133 | double y; | 133 | double y; |
| 134 | 134 | ||
| @@ -182,26 +182,26 @@ __CRT_INLINE long long __cdecl llroundl (long double x) { · 47 unmodified lines | |||
| 182 | /* MUSL asinh, acosh, atanh */ | 182 | /* MUSL asinh, acosh, atanh */ |
| 183 | 183 | ||
| 184 | __CRT_INLINE double __cdecl asinh(double x) { | 184 | __CRT_INLINE double __cdecl asinh(double x) { |
| 185 | union {double f; uint64_t i;} u = {x}; | 185 | union {double f; uint64_t i;} u = {.f = x}; |
| 186 | unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63; | 186 | unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63; |
| 187 | u.i &= -1ull / 2, x = u.f; | 187 | u.i &= -1ull / 2, x = u.f; |
| 188 | if (e >= 0x3ff + 26) x = log(x) + 0.69314718055994530941723212145818; | 188 | if (e >= 0x3ff + 26) x = log(x) + 0.693147180559945309; |
| 189 | else if (e >= 0x3ff + 1) x = log(2*x + 1 / (sqrt(x*x + 1) + x)); | 189 | else if (e >= 0x3ff + 1) x = log(2*x + 1 / (sqrt(x*x + 1) + x)); /* |x|>=2 */ |
| 190 | else if (e >= 0x3ff - 26) x = log1p(x + x*x / (sqrt(x*x + 1) + 1)); | 190 | else if (e >= 0x3ff - 26) x = log1p(x + x*x / (sqrt(x*x + 1) + 1)); |
| 191 | else TCCFP_FORCE_EVAL(x + 0x1p120f); | 191 | else TCCFP_FORCE_EVAL(x + 0x1p120f); |
| 192 | return s ? -x : x; | 192 | return s ? -x : x; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | __CRT_INLINE double __cdecl acosh(double x) { | 195 | __CRT_INLINE double __cdecl acosh(double x) { |
| 196 | union {double f; uint64_t i;} u = {x}; | 196 | union {double f; uint64_t i;} u = {.f = x}; |
| 197 | unsigned e = u.i >> 52 & 0x7ff; | 197 | unsigned e = u.i >> 52 & 0x7ff; |
| 198 | if (e < 0x3ff + 1) return log1p(x - 1 + sqrt((x - 1)*(x - 1) + 2*(x - 1))); | 198 | if (e < 0x3ff + 1) return --x, log1p(x + sqrt(x*x + 2*x)); /* |x|<2 */ |
| 199 | if (e < 0x3ff + 26) return log(2*x - 1 / (x + sqrt(x*x - 1))); | 199 | if (e < 0x3ff + 26) return log(2*x - 1 / (x + sqrt(x*x - 1))); |
| 200 | return log(x) + 0.69314718055994530941723212145818; | 200 | return log(x) + 0.693147180559945309; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | __CRT_INLINE double __cdecl atanh(double x) { | 203 | __CRT_INLINE double __cdecl atanh(double x) { |
| 204 | union {double f; uint64_t i;} u = {x}; | 204 | union {double f; uint64_t i;} u = {.f = x}; |
| 205 | unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63; | 205 | unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63; |
| 206 | u.i &= -1ull / 2, x = u.f; | 206 | u.i &= -1ull / 2, x = u.f; |
| 207 | if (e < 0x3ff - 1) { | 207 | if (e < 0x3ff - 1) { |
| @@ -232,6 +232,18 @@ __CRT_INLINE double __cdecl scalbn(double x, int n) { · 24 unmodified lines | |||
| 232 | return x * u.f; | 232 | return x * u.f; |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | /* MUSL nan */ | ||
| 236 | |||
| 237 | __CRT_INLINE double __cdecl nan(const char* s) { | ||
| 238 | return NAN; | ||
| 239 | } | ||
| 240 | __CRT_INLINE float __cdecl nanf(const char* s) { | ||
| 241 | return NAN; | ||
| 242 | } | ||
| 243 | __CRT_INLINE long double __cdecl nanl(const char* s) { | ||
| 244 | return NAN; | ||
| 245 | } | ||
| 246 | |||
| 235 | 247 | ||
| 236 | /******************************************************************************* | 248 | /******************************************************************************* |
| 237 | End of code based on MUSL | 249 | End of code based on MUSL |
| @@ -240,7 +252,7 @@ __CRT_INLINE double __cdecl scalbn(double x, int n) { · 2 unmodified lines | |||
| 240 | 252 | ||
| 241 | /* Following are math functions missing from msvcrt.dll, and not defined | 253 | /* Following are math functions missing from msvcrt.dll, and not defined |
| 242 | * in math.h or above. Functions still remaining: | 254 | * in math.h or above. Functions still remaining: |
| 243 | * remquo(), remainder(), fma(), nan(), erf(), erfc(), nearbyint(). | 255 | * remquo(), remainder(), fma(), erf(), erfc(), nearbyint(). |
| 244 | * In <stdlib.h>: lldiv(). | 256 | * In <stdlib.h>: lldiv(). |
| 245 | */ | 257 | */ |
| 246 | 258 | ||
| @@ -381,12 +393,12 @@ __CRT_INLINE long double __cdecl nexttowardl(long double x, long double to) { · 134 unmodified lines | |||
| 381 | 393 | ||
| 382 | 394 | ||
| 383 | __CRT_INLINE float __cdecl fabsf (float x) { | 395 | __CRT_INLINE float __cdecl fabsf (float x) { |
| 384 | union {float f; uint32_t i;} u = {x}; | 396 | union {float f; uint32_t i;} u = {.f = x}; |
| 385 | u.i &= 0x7fffffff; | 397 | u.i &= 0x7fffffff; return u.f; |
| 386 | return u.f; | ||
| 387 | } | 398 | } |
| 388 | __CRT_INLINE long double __cdecl fabsl (long double x) { | 399 | __CRT_INLINE long double __cdecl fabsl (long double x) { |
| 389 | return fabs(x); | 400 | union {double f; uint64_t i;} u = {.f = x}; |
| 401 | u.i &= 0x7fffffffffffffff; return u.f; | ||
| 390 | } | 402 | } |
| 391 | 403 | ||
| 392 | 404 | ||
| @@ -456,14 +468,12 @@ __CRT_INLINE long double __cdecl log1pl(long double x) { · 63 unmodified lines | |||
| 456 | 468 | ||
| 457 | 469 | ||
| 458 | __CRT_INLINE double __cdecl expm1(double x) { | 470 | __CRT_INLINE double __cdecl expm1(double x) { |
| 459 | if (fabs(x) > 0.0024) return exp(x) - 1.0; | 471 | if (x > 0.0024 || x < -0.0024) return exp(x) - 1.0; |
| 460 | double u, v = x*x, t = x + 0.5*v + 0.1666666666666666667*(u = v*x); | 472 | return x*(1.0 + 0.5*x*(1.0 + (1/3.0)*x*(1.0 + 0.25*x*(1.0 + 0.2*x)))); |
| 461 | return t + 0.04166666666666666667*u*x; | ||
| 462 | } | 473 | } |
| 463 | __CRT_INLINE float __cdecl expm1f(float x) { | 474 | __CRT_INLINE float __cdecl expm1f(float x) { |
| 464 | if (fabsf(x) > 0.085f) return expf(x) - 1.0f; | 475 | if (x > 0.085f || x < -0.085f) return expf(x) - 1.0f; |
| 465 | float u, v = x*x, t = x + 0.5f*v + 0.1666666666666666667f*(u = v*x); | 476 | return x*(1.0f + 0.5f*x*(1.0f + (1/3.0f)*x*(1.0f + 0.25f*x))); |
| 466 | return t + 0.04166666666666666667f*u*x; | ||
| 467 | } | 477 | } |
| 468 | __CRT_INLINE long double __cdecl expm1l(long double x) { | 478 | __CRT_INLINE long double __cdecl expm1l(long double x) { |
| 469 | return expm1(x); | 479 | return expm1(x); |
| @@ -471,35 +481,35 @@ __CRT_INLINE long double __cdecl expm1l(long double x) { · 1 unmodified line | |||
| 471 | 481 | ||
| 472 | 482 | ||
| 473 | __CRT_INLINE double __cdecl cbrt(double x) { | 483 | __CRT_INLINE double __cdecl cbrt(double x) { |
| 474 | return copysign(pow(fabs(x), 1/3.0), x); | 484 | return x < 0.0 ? -pow(-x, 1/3.0) : pow(x, 1/3.0); |
| 475 | } | 485 | } |
| 476 | __CRT_INLINE float __cdecl cbrtf(float x) { | 486 | __CRT_INLINE float __cdecl cbrtf(float x) { |
| 477 | return copysignf(pow(fabs(x), 1/3.0), x); | 487 | return x < 0.0f ? -pow(-x, 1/3.0) : pow(x, 1/3.0); |
| 478 | } | 488 | } |
| 479 | __CRT_INLINE long double __cdecl cbrtl(long double x) { | 489 | __CRT_INLINE long double __cdecl cbrtl(long double x) { |
| 480 | return copysign(pow(fabs(x), 1/3.0), x); | 490 | return cbrt(x); |
| 481 | } | 491 | } |
| 482 | 492 | ||
| 483 | 493 | ||
| 484 | __CRT_INLINE double __cdecl log2(double x) { | 494 | __CRT_INLINE double __cdecl log2(double x) { |
| 485 | return log(x) * 1.4426950408889634073599246810019; | 495 | return log(x) * 1.442695040888963407; |
| 486 | } | 496 | } |
| 487 | __CRT_INLINE float __cdecl log2f(float x) { | 497 | __CRT_INLINE float __cdecl log2f(float x) { |
| 488 | return log(x) * 1.4426950408889634073599246810019; | 498 | return log(x) * 1.442695040888963407; |
| 489 | } | 499 | } |
| 490 | __CRT_INLINE long double __cdecl log2l(long double x) { | 500 | __CRT_INLINE long double __cdecl log2l(long double x) { |
| 491 | return log(x) * 1.4426950408889634073599246810019; | 501 | return log(x) * 1.442695040888963407; |
| 492 | } | 502 | } |
| 493 | 503 | ||
| 494 | 504 | ||
| 495 | __CRT_INLINE double __cdecl exp2(double x) { | 505 | __CRT_INLINE double __cdecl exp2(double x) { |
| 496 | return exp(x * 0.69314718055994530941723212145818); | 506 | return exp(x * 0.693147180559945309); |
| 497 | } | 507 | } |
| 498 | __CRT_INLINE float __cdecl exp2f(float x) { | 508 | __CRT_INLINE float __cdecl exp2f(float x) { |
| 499 | return exp(x * 0.69314718055994530941723212145818); | 509 | return exp(x * 0.693147180559945309); |
| 500 | } | 510 | } |
| 501 | __CRT_INLINE long double __cdecl exp2l(long double x) { | 511 | __CRT_INLINE long double __cdecl exp2l(long double x) { |
| 502 | return exp(x * 0.69314718055994530941723212145818); | 512 | return exp(x * 0.693147180559945309); |
| 503 | } | 513 | } |
| 504 | 514 | ||
| 505 | 515 | ||
| @@ -535,11 +545,10 @@ __CRT_INLINE long double __cdecl fdiml(long double x, long double y) { · 29 unmodified lines | |||
| 535 | 545 | ||
| 536 | __CRT_INLINE double __cdecl tgamma(double x) { | 546 | __CRT_INLINE double __cdecl tgamma(double x) { |
| 537 | double m = 1.0, t = 3.14159265358979323; | 547 | double m = 1.0, t = 3.14159265358979323; |
| 538 | if (x > 172.0) | ||
| 539 | return INFINITY; | ||
| 540 | if (x == floor(x)) { | 548 | if (x == floor(x)) { |
| 541 | for (int k = 2; k < x; ++k) m *= k; | 549 | if (x == 0) return INFINITY; |
| 542 | return x > 0.0 ? m : (x == 0.0 ? INFINITY : NAN); | 550 | if (x < 0) return NAN; |
| 551 | if (x < 26) { for (double k = 2; k < x; ++k) m *= k; return m; } | ||
| 543 | } | 552 | } |
| 544 | if (x < 0.5) | 553 | if (x < 0.5) |
| 545 | return t / (sin(t*x)*tgamma(1.0 - x)); | 554 | return t / (sin(t*x)*tgamma(1.0 - x)); |
| @@ -557,9 +566,11 @@ __CRT_INLINE double __cdecl tgamma(double x) { · 11 unmodified lines | |||
| 557 | 566 | ||
| 558 | 567 | ||
| 559 | __CRT_INLINE double __cdecl lgamma(double x) { | 568 | __CRT_INLINE double __cdecl lgamma(double x) { |
| 560 | if (x < 12.0) | 569 | if (x < 12.0) { |
| 561 | return x > 0.0 || x != floor(x) ? log(fabs(tgamma(x))) : INFINITY; | 570 | if (x <= 0.0 && x == floor(x)) return INFINITY; |
| 562 | 571 | x = tgamma(x); | |
| 572 | return log(x < 0.0 ? -x : x); | ||
| 573 | } | ||
| 563 | static const double c[7] = {1.0/12.0, -1.0/360.0, 1.0/1260.0, -1.0/1680.0, | 574 | static const double c[7] = {1.0/12.0, -1.0/360.0, 1.0/1260.0, -1.0/1680.0, |
| 564 | 1.0/1188.0, -691.0/360360.0, 1.0/156.0}; | 575 | 1.0/1188.0, -691.0/360360.0, 1.0/156.0}; |
| 565 | double m = -3617.0/122400.0, t = 1.0 / (x*x); | 576 | double m = -3617.0/122400.0, t = 1.0 / (x*x); |