diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 5ecbb8bf037..05571a7fe20 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -1312,9 +1312,30 @@ float CDECL sinf( float x ) */ float CDECL sinhf( float x ) { - float ret = unix_funcs->sinhf( x ); - if (isnan(x)) return math_error(_DOMAIN, "sinhf", x, 0, ret); - return ret; + UINT32 ui = *(UINT32*)&x; + float t, h, absx; + + h = 0.5; + if (ui >> 31) + h = -h; + /* |x| */ + ui &= 0x7fffffff; + absx = *(float*)&ui; + + /* |x| < log(FLT_MAX) */ + if (ui < 0x42b17217) { + t = __expm1f(absx); + if (ui < 0x3f800000) { + if (ui < 0x3f800000 - (12 << 23)) + return x; + return h * (2 * t - t * t / (t + 1)); + } + return h * (t + t / (t + 1)); + } + + /* |x| > logf(FLT_MAX) or nan */ + t = __expo2f(absx, 2 * h); + return t; } static BOOL sqrtf_validate( float *x ) diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c index 2f447533fb6..918c7e6ed71 100644 --- a/dlls/msvcrt/unixlib.c +++ b/dlls/msvcrt/unixlib.c @@ -268,14 +268,6 @@ static float CDECL unix_powf( float x, float y ) return powf( x, y ); } -/********************************************************************* - * sinhf - */ -static float CDECL unix_sinhf( float x ) -{ - return sinhf( x ); -} - /********************************************************************* * tanh */ @@ -343,7 +335,6 @@ static const struct unix_funcs funcs = unix_log2f, unix_pow, unix_powf, - unix_sinhf, unix_tanh, unix_tanhf, unix_tgamma, diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h index 80a150b9031..0e3074be0c5 100644 --- a/dlls/msvcrt/unixlib.h +++ b/dlls/msvcrt/unixlib.h @@ -46,7 +46,6 @@ struct unix_funcs float (CDECL *log2f)(float x); double (CDECL *pow)(double x, double y); float (CDECL *powf)(float x, float y); - float (CDECL *sinhf)(float x); double (CDECL *tanh)(double x); float (CDECL *tanhf)(float x); double (CDECL *tgamma)(double x);