mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-23 21:06:24 +00:00
msvcrt: Use the round()/roundf() implementation from the bundled musl library.
With the changes from df9c11ffa8
.
This commit is contained in:
parent
77b6cf56c1
commit
9db27802c3
|
@ -467,27 +467,6 @@ recompute:
|
||||||
return n & 7;
|
return n & 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Based on musl implementation: src/math/round.c */
|
|
||||||
static double __round(double x)
|
|
||||||
{
|
|
||||||
ULONGLONG llx = *(ULONGLONG*)&x, tmp;
|
|
||||||
int e = (llx >> 52 & 0x7ff) - 0x3ff;
|
|
||||||
|
|
||||||
if (e >= 52)
|
|
||||||
return x;
|
|
||||||
if (e < -1)
|
|
||||||
return 0 * x;
|
|
||||||
else if (e == -1)
|
|
||||||
return signbit(x) ? -1 : 1;
|
|
||||||
|
|
||||||
tmp = 0x000fffffffffffffULL >> e;
|
|
||||||
if (!(llx & tmp))
|
|
||||||
return x;
|
|
||||||
llx += 0x0008000000000000ULL >> e;
|
|
||||||
llx &= ~tmp;
|
|
||||||
return *(double*)&llx;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef __i386__
|
#ifndef __i386__
|
||||||
/* Copied from musl: src/math/__sindf.c */
|
/* Copied from musl: src/math/__sindf.c */
|
||||||
static float __sindf(double x)
|
static float __sindf(double x)
|
||||||
|
@ -945,7 +924,7 @@ float CDECL expf( float x )
|
||||||
/* Round and convert z to int, the result is in [-150*N, 128*N] and
|
/* Round and convert z to int, the result is in [-150*N, 128*N] and
|
||||||
ideally ties-to-even rule is used, otherwise the magnitude of r
|
ideally ties-to-even rule is used, otherwise the magnitude of r
|
||||||
can be bigger which gives larger approximation error. */
|
can be bigger which gives larger approximation error. */
|
||||||
kd = __round(z);
|
kd = round(z);
|
||||||
ki = (INT64)kd;
|
ki = (INT64)kd;
|
||||||
r = z - kd;
|
r = z - kd;
|
||||||
|
|
||||||
|
@ -1037,7 +1016,7 @@ static float powf_exp2(double xd, UINT32 sign_bias)
|
||||||
double kd, z, r, r2, y, s;
|
double kd, z, r, r2, y, s;
|
||||||
|
|
||||||
/* N*x = k + r with r in [-1/2, 1/2] */
|
/* N*x = k + r with r in [-1/2, 1/2] */
|
||||||
kd = __round(xd); /* k */
|
kd = round(xd); /* k */
|
||||||
ki = (INT64)kd;
|
ki = (INT64)kd;
|
||||||
r = xd - kd;
|
r = xd - kd;
|
||||||
|
|
||||||
|
@ -2187,7 +2166,7 @@ double CDECL exp( double x )
|
||||||
/* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */
|
/* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */
|
||||||
/* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */
|
/* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */
|
||||||
z = invln2N * x;
|
z = invln2N * x;
|
||||||
kd = __round(z);
|
kd = round(z);
|
||||||
ki = (INT64)kd;
|
ki = (INT64)kd;
|
||||||
|
|
||||||
r = x + kd * negln2hiN + kd * negln2loN;
|
r = x + kd * negln2hiN + kd * negln2loN;
|
||||||
|
@ -2495,7 +2474,7 @@ static double pow_exp(double argx, double argy, double x, double xtail, UINT32 s
|
||||||
/* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */
|
/* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */
|
||||||
/* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */
|
/* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */
|
||||||
z = invln2N * x;
|
z = invln2N * x;
|
||||||
kd = __round(z);
|
kd = round(z);
|
||||||
ki = (INT64)kd;
|
ki = (INT64)kd;
|
||||||
r = x + kd * negln2hiN + kd * negln2loN;
|
r = x + kd * negln2hiN + kd * negln2loN;
|
||||||
/* The code assumes 2^-200 < |xtail| < 2^-8/N. */
|
/* The code assumes 2^-200 < |xtail| < 2^-8/N. */
|
||||||
|
@ -5336,45 +5315,6 @@ __int64 CDECL llrintf(float x)
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* round (MSVCR120.@)
|
|
||||||
*/
|
|
||||||
double CDECL round(double x)
|
|
||||||
{
|
|
||||||
return __round(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* roundf (MSVCR120.@)
|
|
||||||
*
|
|
||||||
* Copied from musl: src/math/roundf.c
|
|
||||||
*/
|
|
||||||
float CDECL roundf(float x)
|
|
||||||
{
|
|
||||||
static const float toint = 1 / FLT_EPSILON;
|
|
||||||
|
|
||||||
unsigned int ix = *(unsigned int*)&x;
|
|
||||||
int e = ix >> 23 & 0xff;
|
|
||||||
float y;
|
|
||||||
|
|
||||||
if (e >= 0x7f + 23)
|
|
||||||
return x;
|
|
||||||
if (ix >> 31)
|
|
||||||
x = -x;
|
|
||||||
if (e < 0x7f - 1)
|
|
||||||
return 0 * *(float*)&ix;
|
|
||||||
y = fp_barrierf(x + toint) - toint - x;
|
|
||||||
if (y > 0.5f)
|
|
||||||
y = y + x - 1;
|
|
||||||
else if (y <= -0.5f)
|
|
||||||
y = y + x + 1;
|
|
||||||
else
|
|
||||||
y = y + x;
|
|
||||||
if (ix >> 31)
|
|
||||||
y = -y;
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* lround (MSVCR120.@)
|
* lround (MSVCR120.@)
|
||||||
*
|
*
|
||||||
|
|
|
@ -5,31 +5,25 @@
|
||||||
#elif FLT_EVAL_METHOD==2
|
#elif FLT_EVAL_METHOD==2
|
||||||
#define EPS LDBL_EPSILON
|
#define EPS LDBL_EPSILON
|
||||||
#endif
|
#endif
|
||||||
static const double_t toint = 1/EPS;
|
|
||||||
|
|
||||||
double __cdecl round(double x)
|
double __cdecl round(double x)
|
||||||
{
|
{
|
||||||
union {double f; uint64_t i;} u = {x};
|
union {double f; uint64_t i;} u = {x};
|
||||||
int e = u.i >> 52 & 0x7ff;
|
uint64_t tmp;
|
||||||
|
int e = (u.i >> 52 & 0x7ff) - 0x3ff;
|
||||||
double_t y;
|
double_t y;
|
||||||
|
|
||||||
if (e >= 0x3ff+52)
|
if (e >= 52)
|
||||||
return x;
|
return x;
|
||||||
if (u.i >> 63)
|
if (e < -1)
|
||||||
x = -x;
|
|
||||||
if (e < 0x3ff-1) {
|
|
||||||
/* raise inexact if x!=0 */
|
|
||||||
FORCE_EVAL(x + toint);
|
|
||||||
return 0*u.f;
|
return 0*u.f;
|
||||||
}
|
if (e == -1)
|
||||||
y = x + toint - toint - x;
|
return (u.i >> 63) ? -1 : 1;
|
||||||
if (y > 0.5)
|
|
||||||
y = y + x - 1;
|
tmp = 0x000fffffffffffffULL >> e;
|
||||||
else if (y <= -0.5)
|
if (!(u.i & tmp))
|
||||||
y = y + x + 1;
|
return x;
|
||||||
else
|
u.i += 0x0008000000000000ULL >> e;
|
||||||
y = y + x;
|
u.i &= ~tmp;
|
||||||
if (u.i >> 63)
|
return u.f;
|
||||||
y = -y;
|
|
||||||
return y;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ float __cdecl roundf(float x)
|
||||||
FORCE_EVAL(x + toint);
|
FORCE_EVAL(x + toint);
|
||||||
return 0*u.f;
|
return 0*u.f;
|
||||||
}
|
}
|
||||||
y = x + toint - toint - x;
|
y = fp_barrierf(x + toint) - toint - x;
|
||||||
if (y > 0.5f)
|
if (y > 0.5f)
|
||||||
y = y + x - 1;
|
y = y + x - 1;
|
||||||
else if (y <= -0.5f)
|
else if (y <= -0.5f)
|
||||||
|
|
Loading…
Reference in a new issue