msvcrt: Import erf implementation from musl.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2021-05-19 15:26:39 +02:00 committed by Alexandre Julliard
parent 7b0e5b2b69
commit 9bc856dfaf
6 changed files with 39 additions and 28 deletions

1
configure vendored
View File

@ -19622,7 +19622,6 @@ for ac_func in \
asinhf \
atanh \
atanhf \
erf \
exp2 \
exp2f \
expm1 \

View File

@ -2662,7 +2662,6 @@ AC_CHECK_FUNCS(\
asinhf \
atanh \
atanhf \
erf \
exp2 \
exp2f \
expm1 \

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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