From: Daniel Lehman Subject: msvcr120: Add erf functions (try 2) Message-Id: <2EE9C16F5A58104387BC411DC1EFA8F9D89F5700@RED-INF-EXMB-P1.esri.com> Date: Wed, 13 May 2015 17:48:54 +0000 Try2: Added tests and removed erfc (needs to handle ERANGE) From 370c40cfa4f62720f886e72b149fddb50031a6b4 Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Fri, 8 May 2015 10:39:09 -0700 Subject: [PATCH 1/2] msvcr120: Add erf functions --- dlls/msvcr120/msvcr120.spec | 6 +++--- dlls/msvcr120/tests/msvcr120.c | 30 ++++++++++++++++++++++++++++++ dlls/msvcrt/math.c | 26 ++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 811dcee..fab53e2 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2119,12 +2119,12 @@ @ stub ctanhl @ stub ctanl @ cdecl -ret64 div(long long) MSVCRT_div -@ stub erf +@ cdecl erf(double) MSVCRT_erf @ stub erfc @ stub erfcf @ stub erfcl -@ stub erff -@ stub erfl +@ cdecl erff(double) MSVCRT_erff +@ cdecl erfl(double) MSVCRT_erfl @ cdecl exit(long) MSVCRT_exit @ cdecl exp(double) MSVCRT_exp @ cdecl exp2(double) MSVCR120_exp2 diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index c0a582f..c07f522 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -61,6 +61,7 @@ struct MSVCRT_lconv static char* (CDECL *p_setlocale)(int category, const char* locale); static struct MSVCRT_lconv* (CDECL *p_localeconv)(void); static size_t (CDECL *p_wcstombs_s)(size_t *ret, char* dest, size_t sz, const wchar_t* src, size_t max); +static double (CDECL *p_erf)(double); static BOOL init(void) { @@ -76,6 +77,7 @@ static BOOL init(void) p_setlocale = (void*)GetProcAddress(module, "setlocale"); p_localeconv = (void*)GetProcAddress(module, "localeconv"); p_wcstombs_s = (void*)GetProcAddress(module, "wcstombs_s"); + p_erf = (void*)GetProcAddress(module, "erf"); return TRUE; } @@ -148,8 +150,36 @@ static void test_lconv(void) test_lconv_helper(locstrs[i]); } +static inline int almost_equal(double d1, double d2) +{ + return d1-d2 > -1e-10 && d1-d2 < 1e-10; +} + +static void test_erf(void) +{ + int i; + double out; + struct test { double in, out; } tests[] = + { + { -2.0, -0.9953222650 }, + { -1.5, -0.9661051465 }, + { -1.0, -0.8427007929 }, + { 0.0, 0.0 }, + { 1.0, 0.8427007929 }, + { 2.0, 0.9953222650 } + }; + + for(i = 0; i < sizeof(tests)/sizeof(tests[0]); i ++) + { + out = p_erf(tests[i].in); + ok(almost_equal(tests[i].out, out), "for %.1f, expected %.10f got %.10f\n", + tests[i].in, tests[i].out, out); + } +} + START_TEST(msvcr120) { if (!init()) return; test_lconv(); + test_erf(); } diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 7c971d3..aed46e6 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -73,6 +73,32 @@ int CDECL MSVCRT__set_SSE2_enable(int flag) return sse2_enabled; } +#if _MSVCR_VER>=120 +/********************************************************************* + * erff (MSVCRT.@) + */ +float CDECL MSVCRT_erff( float num ) +{ + return erff(num); +} + +/********************************************************************* + * erf (MSVCRT.@) + */ +double CDECL MSVCRT_erf( double num ) +{ + return erf(num); +} + +/********************************************************************* + * erfl (MSVCRT.@) + */ +double CDECL MSVCRT_erfl( double num ) +{ + return erf(num); /* long double is just a double */ +} +#endif + #if defined(__x86_64__) || defined(__arm__) || _MSVCR_VER>=120 /********************************************************************* -- 1.9.5