From 98525b04bc1de4c136d4fb0d70bdecaf0641f0e8 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Wed, 19 May 2021 15:26:29 +0200 Subject: [PATCH] msvcrt: Import erff implementation from musl. Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- configure | 1 - configure.ac | 1 - dlls/msvcrt/math.c | 42 +++++++++++++++++++++++++++++++++++++++++- dlls/msvcrt/unixlib.c | 13 ------------- dlls/msvcrt/unixlib.h | 1 - include/config.h.in | 3 --- 6 files changed, 41 insertions(+), 20 deletions(-) diff --git a/configure b/configure index 00c8378b4c6..9eb6cb7fd61 100755 --- a/configure +++ b/configure @@ -19624,7 +19624,6 @@ for ac_func in \ atanhf \ erf \ erfc \ - erff \ exp2 \ exp2f \ expm1 \ diff --git a/configure.ac b/configure.ac index e8b3d175fc9..d21882c7813 100644 --- a/configure.ac +++ b/configure.ac @@ -2664,7 +2664,6 @@ AC_CHECK_FUNCS(\ atanhf \ erf \ erfc \ - erff \ exp2 \ exp2f \ expm1 \ diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index bd4df691e58..e0c28e25638 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -5306,10 +5306,50 @@ static float erfc2f(UINT32 ix, float x) /********************************************************************* * erff (MSVCR120.@) + * + * Copied from musl: src/math/erff.c */ float CDECL erff(float x) { - return unix_funcs->erff( x ); + static const float efx8 = 1.0270333290e+00, + pp0 = 1.2837916613e-01, + pp1 = -3.2504209876e-01, + pp2 = -2.8481749818e-02, + pp3 = -5.7702702470e-03, + pp4 = -2.3763017452e-05, + qq1 = 3.9791721106e-01, + qq2 = 6.5022252500e-02, + qq3 = 5.0813062117e-03, + qq4 = 1.3249473704e-04, + qq5 = -3.9602282413e-06; + + float r, s, z, y; + UINT32 ix; + int sign; + + ix = *(UINT32*)&x; + sign = ix >> 31; + ix &= 0x7fffffff; + if (ix >= 0x7f800000) { + /* erf(nan)=nan, erf(+-inf)=+-1 */ + return 1 - 2 * sign + 1 / x; + } + if (ix < 0x3f580000) { /* |x| < 0.84375 */ + if (ix < 0x31800000) { /* |x| < 2**-28 */ + /*avoid underflow */ + return 0.125f * (8 * x + efx8 * x); + } + z = x * x; + r = pp0 + z * (pp1 + z * (pp2 + z * (pp3 + z * pp4))); + s = 1 + z * (qq1 + z * (qq2 + z * (qq3 + z * (qq4 + z * qq5)))); + y = r / s; + return x + x * y; + } + if (ix < 0x40c00000) /* |x| < 6 */ + y = 1 - erfc2f(ix, x); + else + y = 1 - FLT_MIN; + return sign ? -y : y; } /********************************************************************* diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c index 77de4602918..9607ca94e7c 100644 --- a/dlls/msvcrt/unixlib.c +++ b/dlls/msvcrt/unixlib.c @@ -174,18 +174,6 @@ static double CDECL unix_erf(double x) } /********************************************************************* - * erff - */ -static float CDECL unix_erff(float x) -{ -#ifdef HAVE_ERFF - return erff(x); -#else - return unix_erf(x); -#endif -} - -/********************************************************************* * erfc */ static double CDECL unix_erfc(double x) @@ -567,7 +555,6 @@ static const struct unix_funcs funcs = unix_coshf, unix_erf, unix_erfc, - unix_erff, unix_exp, unix_expf, unix_exp2, diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h index 13912c68c99..58ec53d285c 100644 --- a/dlls/msvcrt/unixlib.h +++ b/dlls/msvcrt/unixlib.h @@ -35,7 +35,6 @@ struct unix_funcs float (CDECL *coshf)(float x); double (CDECL *erf)(double x); double (CDECL *erfc)(double x); - float (CDECL *erff)(float x); double (CDECL *exp)(double x); float (CDECL *expf)(float x); double (CDECL *exp2)(double x); diff --git a/include/config.h.in b/include/config.h.in index d7738888e27..b0e1fb55332 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -116,9 +116,6 @@ /* Define to 1 if you have the `erfc' function. */ #undef HAVE_ERFC -/* Define to 1 if you have the `erff' function. */ -#undef HAVE_ERFF - /* Define to 1 if you have the `exp2' function. */ #undef HAVE_EXP2 -- 2.11.4.GIT