From: Piotr Caban Subject: [PATCH] msvcrt: Improve acosf compatibility with native ucrtbase. Message-Id: Date: Thu, 25 Feb 2021 15:39:23 +0100 It reduces number of different acosf results from 5678739 to 240905. Signed-off-by: Piotr Caban --- dlls/msvcrt/math.c | 57 +++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index b1bf60d57ea..0543b2ce87c 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -287,28 +287,29 @@ int CDECL _isnanf( float num ) return (u.i & 0x7fffffff) > 0x7f800000; } -/********************************************************************* - * acosf (MSVCRT.@) - * - * Copied from musl: src/math/acosf.c - */ -static float acosf_R(float z) +static float asinf_R(float z) { - static const float pS0 = 1.6666586697e-01, - pS1 = -4.2743422091e-02, - pS2 = -8.6563630030e-03, - qS1 = -7.0662963390e-01; + /* coefficients for R(x^2) */ + static const float p1 = 1.66666672e-01, + p2 = -5.11644611e-02, + p3 = -1.21124933e-02, + p4 = -3.58742251e-03, + q1 = -7.56982703e-01; float p, q; - p = z * (pS0 + z * (pS1 + z * pS2)); - q = 1.0f + z * qS1; + p = z * (p1 + z * (p2 + z * (p3 + z * p4))); + q = 1.0f + z * q1; return p / q; } +/********************************************************************* + * acosf (MSVCRT.@) + * + * Copied from musl: src/math/acosf.c + */ float CDECL acosf( float x ) { - static const float pio2_hi = 1.5707962513e+00, - pio2_lo = 7.5497894159e-08; + static const double pio2_lo = 6.12323399573676603587e-17; float z, w, s, c, df; unsigned int hx, ix; @@ -319,7 +320,7 @@ float CDECL acosf( float x ) if (ix >= 0x3f800000) { if (ix == 0x3f800000) { if (hx >> 31) - return 2 * pio2_lo + 2 * pio2_hi + 7.5231638453e-37; + return M_PI; return 0; } if (isnan(x)) return x; @@ -328,23 +329,22 @@ float CDECL acosf( float x ) /* |x| < 0.5 */ if (ix < 0x3f000000) { if (ix <= 0x32800000) /* |x| < 2**-26 */ - return pio2_lo + pio2_hi + 7.5231638453e-37; - return pio2_hi - (x - (pio2_lo - x * acosf_R(x * x))); + return M_PI_2; + return M_PI_2 - (x - (pio2_lo - x * asinf_R(x * x))); } /* x < -0.5 */ if (hx >> 31) { z = (1 + x) * 0.5f; s = sqrtf(z); - w = acosf_R(z) * s - pio2_lo; - return 2 * (pio2_hi - (s + w)); + return M_PI - 2 * (s + ((double)s * asinf_R(z))); } /* x > 0.5 */ z = (1 - x) * 0.5f; s = sqrtf(z); - hx = *(unsigned int*)&s & 0xfffff000; + hx = *(unsigned int*)&s & 0xffff0000; df = *(float*)&hx; c = (z - df * df) / (s + df); - w = acosf_R(z) * s + c; + w = asinf_R(z) * s + c; return 2 * (df + w); } @@ -353,21 +353,6 @@ float CDECL acosf( float x ) * * Copied from musl: src/math/asinf.c */ -static float asinf_R(float z) -{ - /* coefficients for R(x^2) */ - static const float p1 = 1.66666672e-01, - p2 = -5.11644611e-02, - p3 = -1.21124933e-02, - p4 = -3.58742251e-03, - q1 = -7.56982703e-01; - - float p, q; - p = z * (p1 + z * (p2 + z * (p3 + z * p4))); - q = 1.0f + z * q1; - return p / q; -} - float CDECL asinf( float x ) { static const double pio2 = 1.570796326794896558e+00;