From: Daniel Lehman dlehman25@gmail.com
--- dlls/msvcr120/tests/msvcr120.c | 71 ++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index 856e9251e61..7c62a921a7e 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -195,6 +195,23 @@ static _Cancellation_beacon* (__thiscall *p__Cancellation_beacon_ctor)(_Cancella static void (__thiscall *p__Cancellation_beacon_dtor)(_Cancellation_beacon*); static MSVCRT_bool (__thiscall *p__Cancellation_beacon__Confirm_cancel)(_Cancellation_beacon*);
+static inline BOOL compare_double(double f, double g, unsigned int ulps) +{ + ULONGLONG x = *(ULONGLONG *)&f; + ULONGLONG y = *(ULONGLONG *)&g; + + if (f < 0) + x = ~x + 1; + else + x |= ((ULONGLONG)1)<<63; + if (g < 0) + y = ~y + 1; + else + y |= ((ULONGLONG)1)<<63; + + return (x>y ? x-y : y-x) <= ulps; +} + #define SETNOFAIL(x,y) x = (void*)GetProcAddress(module,y) #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
@@ -1786,6 +1803,59 @@ static void test__fsopen(void) setlocale(LC_ALL, "C"); }
+static int matherr_called; +static int CDECL matherr_callback(struct _exception *e) +{ + matherr_called = 1; + return 0; +} + +static void test_exp(void) +{ + static const struct { + double x, exp; + errno_t e; + BOOL todo; + } tests[] = { + { NAN, NAN, EDOM, TRUE }, + { -NAN, -NAN, EDOM, TRUE }, + { INFINITY, INFINITY }, + { -INFINITY, 0.0 }, + { 0.0, 1.0 }, + { 1.0, 2.7182818284590451 }, + { 709.7, 1.6549840276802644e+308 }, + { 709.782712893384, 1.7976931348622732e+308 }, + { 709.782712893385, INFINITY, ERANGE }, + }; + errno_t e; + double r; + int i; + + __setusermatherr(matherr_callback); + + for(i=0; i<ARRAY_SIZE(tests); i++) { + errno = 0; + matherr_called = 0; + r = exp(tests[i].x); + e = errno; + if(_isnan(tests[i].exp)) + ok(_isnan(r), "expected NAN, got %0.16e for %d\n", r, i); + else + ok(compare_double(r, tests[i].exp, 16), "expected %0.16e, got %0.16e for %d\n", tests[i].exp, r, i); + ok(signbit(r) == signbit(tests[i].exp), "expected sign %x, got %x for %d\n", + signbit(tests[i].exp), signbit(r), i); + todo_wine_if(tests[i].todo) { + ok(e == tests[i].e, "expected errno %i, but got %i for %d\n", tests[i].e, e, i); + if (tests[i].e) + ok(matherr_called, "matherr wasn't called for %d\n", i); + else + ok(!matherr_called, "matherr was called for %d\n", i); + } + } + + __setusermatherr(NULL); +} + START_TEST(msvcr120) { if (!init()) return; @@ -1813,4 +1883,5 @@ START_TEST(msvcr120) test_strcmp(); test_gmtime64(); test__fsopen(); + test_exp(); }