msvcrt: Import expm1f implementation from musl.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5b025c7175
commit
7d0d7690eb
|
@ -19618,7 +19618,6 @@ fi
|
|||
for ac_func in \
|
||||
exp2 \
|
||||
exp2f \
|
||||
expm1f \
|
||||
fma \
|
||||
fmaf \
|
||||
lgamma \
|
||||
|
|
|
@ -2658,7 +2658,6 @@ fi
|
|||
AC_CHECK_FUNCS(\
|
||||
exp2 \
|
||||
exp2f \
|
||||
expm1f \
|
||||
fma \
|
||||
fmaf \
|
||||
lgamma \
|
||||
|
|
|
@ -5856,12 +5856,93 @@ double CDECL expm1(double x)
|
|||
|
||||
/*********************************************************************
|
||||
* expm1f (MSVCR120.@)
|
||||
*
|
||||
* Copied from musl: src/math/expm1f.c
|
||||
*/
|
||||
float CDECL expm1f(float x)
|
||||
{
|
||||
float ret = unix_funcs->expm1f( x );
|
||||
if (isfinite(x) && !isfinite(ret)) *_errno() = ERANGE;
|
||||
return ret;
|
||||
static const float ln2_hi = 6.9313812256e-01,
|
||||
ln2_lo = 9.0580006145e-06,
|
||||
invln2 = 1.4426950216e+00,
|
||||
Q1 = -3.3333212137e-2,
|
||||
Q2 = 1.5807170421e-3;
|
||||
|
||||
float y, hi, lo, c, t, e, hxs, hfx, r1, twopk;
|
||||
union {float f; UINT32 i;} u = {x};
|
||||
UINT32 hx = u.i & 0x7fffffff;
|
||||
int k, sign = u.i >> 31;
|
||||
|
||||
/* filter out huge and non-finite argument */
|
||||
if (hx >= 0x4195b844) { /* if |x|>=27*ln2 */
|
||||
if (hx >= 0x7f800000) /* NaN */
|
||||
return u.i == 0xff800000 ? -1 : x;
|
||||
if (sign)
|
||||
return math_error(_UNDERFLOW, "exp", x, 0, -1);
|
||||
if (hx > 0x42b17217) /* x > log(FLT_MAX) */
|
||||
return math_error(_OVERFLOW, "exp", x, 0, fp_barrierf(x * FLT_MAX));
|
||||
}
|
||||
|
||||
/* argument reduction */
|
||||
if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
|
||||
if (hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
|
||||
if (!sign) {
|
||||
hi = x - ln2_hi;
|
||||
lo = ln2_lo;
|
||||
k = 1;
|
||||
} else {
|
||||
hi = x + ln2_hi;
|
||||
lo = -ln2_lo;
|
||||
k = -1;
|
||||
}
|
||||
} else {
|
||||
k = invln2 * x + (sign ? -0.5f : 0.5f);
|
||||
t = k;
|
||||
hi = x - t * ln2_hi; /* t*ln2_hi is exact here */
|
||||
lo = t * ln2_lo;
|
||||
}
|
||||
x = hi - lo;
|
||||
c = (hi - x) - lo;
|
||||
} else if (hx < 0x33000000) { /* when |x|<2**-25, return x */
|
||||
if (hx < 0x00800000)
|
||||
fp_barrierf(x * x);
|
||||
return x;
|
||||
} else
|
||||
k = 0;
|
||||
|
||||
/* x is now in primary range */
|
||||
hfx = 0.5f * x;
|
||||
hxs = x * hfx;
|
||||
r1 = 1.0f + hxs * (Q1 + hxs * Q2);
|
||||
t = 3.0f - r1 * hfx;
|
||||
e = hxs * ((r1 - t) / (6.0f - x * t));
|
||||
if (k == 0) /* c is 0 */
|
||||
return x - (x * e - hxs);
|
||||
e = x * (e - c) - c;
|
||||
e -= hxs;
|
||||
/* exp(x) ~ 2^k (x_reduced - e + 1) */
|
||||
if (k == -1)
|
||||
return 0.5f * (x - e) - 0.5f;
|
||||
if (k == 1) {
|
||||
if (x < -0.25f)
|
||||
return -2.0f * (e - (x + 0.5f));
|
||||
return 1.0f + 2.0f * (x - e);
|
||||
}
|
||||
u.i = (0x7f + k) << 23; /* 2^k */
|
||||
twopk = u.f;
|
||||
if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */
|
||||
y = x - e + 1.0f;
|
||||
if (k == 128)
|
||||
y = y * 2.0f * 0x1p127f;
|
||||
else
|
||||
y = y * twopk;
|
||||
return y - 1.0f;
|
||||
}
|
||||
u.i = (0x7f-k) << 23; /* 2^-k */
|
||||
if (k < 23)
|
||||
y = (x - e + (1 - u.f)) * twopk;
|
||||
else
|
||||
y = (x - (e + u.f) + 1) * twopk;
|
||||
return y;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
|
@ -98,18 +98,6 @@ static float CDECL unix_exp2f( float x )
|
|||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* expm1f
|
||||
*/
|
||||
static float CDECL unix_expm1f(float x)
|
||||
{
|
||||
#ifdef HAVE_EXPM1F
|
||||
return expm1f(x);
|
||||
#else
|
||||
return exp(x) - 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* fma
|
||||
*/
|
||||
|
@ -362,7 +350,6 @@ static const struct unix_funcs funcs =
|
|||
unix_expf,
|
||||
unix_exp2,
|
||||
unix_exp2f,
|
||||
unix_expm1f,
|
||||
unix_fma,
|
||||
unix_fmaf,
|
||||
unix_frexp,
|
||||
|
|
|
@ -29,7 +29,6 @@ struct unix_funcs
|
|||
float (CDECL *expf)(float x);
|
||||
double (CDECL *exp2)(double x);
|
||||
float (CDECL *exp2f)(float x);
|
||||
float (CDECL *expm1f)(float x);
|
||||
double (CDECL *fma)(double x, double y, double z);
|
||||
float (CDECL *fmaf)(float x, float y, float z);
|
||||
double (CDECL *frexp)(double x, int *exp);
|
||||
|
|
|
@ -98,9 +98,6 @@
|
|||
/* Define to 1 if you have the `exp2f' function. */
|
||||
#undef HAVE_EXP2F
|
||||
|
||||
/* Define to 1 if you have the `expm1f' function. */
|
||||
#undef HAVE_EXPM1F
|
||||
|
||||
/* Define to 1 if you have the `F3DAudioInitialize8' function. */
|
||||
#undef HAVE_F3DAUDIOINITIALIZE8
|
||||
|
||||
|
|
Loading…
Reference in New Issue