Piotr Caban : msvcrt: Import erf implementation from musl.
Alexandre Julliard
julliard at winehq.org
Wed May 19 14:55:13 CDT 2021
Module: wine
Branch: master
Commit: 9bc856dfaf80f9f69eb5b19f1c7f0159de58a630
URL: https://source.winehq.org/git/wine.git/?a=commit;h=9bc856dfaf80f9f69eb5b19f1c7f0159de58a630
Author: Piotr Caban <piotr at codeweavers.com>
Date: Wed May 19 15:26:39 2021 +0200
msvcrt: Import erf implementation from musl.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
configure | 1 -
configure.ac | 1 -
dlls/msvcrt/math.c | 40 +++++++++++++++++++++++++++++++++++++++-
dlls/msvcrt/unixlib.c | 21 ---------------------
dlls/msvcrt/unixlib.h | 1 -
include/config.h.in | 3 ---
6 files changed, 39 insertions(+), 28 deletions(-)
diff --git a/configure b/configure
index 8e15b71d74e..ecfe7745900 100755
--- a/configure
+++ b/configure
@@ -19622,7 +19622,6 @@ for ac_func in \
asinhf \
atanh \
atanhf \
- erf \
exp2 \
exp2f \
expm1 \
diff --git a/configure.ac b/configure.ac
index 90522c22867..c144fa1bbdd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2662,7 +2662,6 @@ AC_CHECK_FUNCS(\
asinhf \
atanh \
atanhf \
- erf \
exp2 \
exp2f \
expm1 \
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index 787bb18ddad..2e2161e91c4 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -5304,7 +5304,45 @@ static double erfc2(uint32_t ix, double x)
*/
double CDECL erf(double x)
{
- return unix_funcs->erf( x );
+ static const double efx8 = 1.02703333676410069053e+00,
+ pp0 = 1.28379167095512558561e-01,
+ pp1 = -3.25042107247001499370e-01,
+ pp2 = -2.84817495755985104766e-02,
+ pp3 = -5.77027029648944159157e-03,
+ pp4 = -2.37630166566501626084e-05,
+ qq1 = 3.97917223959155352819e-01,
+ qq2 = 6.50222499887672944485e-02,
+ qq3 = 5.08130628187576562776e-03,
+ qq4 = 1.32494738004321644526e-04,
+ qq5 = -3.96022827877536812320e-06;
+
+ double r, s, z, y;
+ UINT32 ix;
+ int sign;
+
+ ix = *(UINT64*)&x >> 32;
+ sign = ix >> 31;
+ ix &= 0x7fffffff;
+ if (ix >= 0x7ff00000) {
+ /* erf(nan)=nan, erf(+-inf)=+-1 */
+ return 1 - 2 * sign + 1 / x;
+ }
+ if (ix < 0x3feb0000) { /* |x| < 0.84375 */
+ if (ix < 0x3e300000) { /* |x| < 2**-28 */
+ /* avoid underflow */
+ return 0.125 * (8 * x + efx8 * x);
+ }
+ z = x * x;
+ r = pp0 + z * (pp1 + z * (pp2 + z * (pp3 + z * pp4)));
+ s = 1.0 + z * (qq1 + z * (qq2 + z * (qq3 + z * (qq4 + z * qq5))));
+ y = r / s;
+ return x + x * y;
+ }
+ if (ix < 0x40180000) /* 0.84375 <= |x| < 6 */
+ y = 1 - erfc2(ix, x);
+ else
+ y = 1 - DBL_MIN;
+ return sign ? -y : y;
}
static float erfc1f(float x)
diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c
index 59f8ce4cee7..fd82c5afb94 100644
--- a/dlls/msvcrt/unixlib.c
+++ b/dlls/msvcrt/unixlib.c
@@ -153,26 +153,6 @@ static float CDECL unix_coshf( float x )
return coshf( x );
}
-/*********************************************************************
- * erf
- */
-static double CDECL unix_erf(double x)
-{
-#ifdef HAVE_ERF
- return erf(x);
-#else
- /* Abramowitz and Stegun approximation, maximum error: 1.5*10^-7 */
- double t, y;
- int sign = signbit(x);
-
- if (sign) x = -x;
- t = 1 / (1 + 0.3275911 * x);
- y = ((((1.061405429*t - 1.453152027)*t + 1.421413741)*t - 0.284496736)*t + 0.254829592)*t;
- y = 1.0 - y*exp(-x*x);
- return sign ? -y : y;
-#endif
-}
-
/*********************************************************************
* exp
*/
@@ -541,7 +521,6 @@ static const struct unix_funcs funcs =
unix_cosf,
unix_cosh,
unix_coshf,
- unix_erf,
unix_exp,
unix_expf,
unix_exp2,
diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h
index 9793fca93bd..95b4a6488de 100644
--- a/dlls/msvcrt/unixlib.h
+++ b/dlls/msvcrt/unixlib.h
@@ -33,7 +33,6 @@ struct unix_funcs
float (CDECL *cosf)(float x);
double (CDECL *cosh)(double x);
float (CDECL *coshf)(float x);
- double (CDECL *erf)(double 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 befb0af9f7e..74d54a942a6 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -110,9 +110,6 @@
/* Define to 1 if you have the `epoll_create' function. */
#undef HAVE_EPOLL_CREATE
-/* Define to 1 if you have the `erf' function. */
-#undef HAVE_ERF
-
/* Define to 1 if you have the `exp2' function. */
#undef HAVE_EXP2
More information about the wine-cvs
mailing list