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