Zebediah Figura : msvcr120: Add nexttoward implementation.

Alexandre Julliard julliard at winehq.org
Mon Feb 25 15:10:34 CST 2019


Module: wine
Branch: master
Commit: 28e74af742f984d58d293e6bc6e4d09b5c3fa844
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=28e74af742f984d58d293e6bc6e4d09b5c3fa844

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Sat Feb 23 14:46:46 2019 -0600

msvcr120: Add nexttoward implementation.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45631
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 configure                                          |  2 +
 configure.ac                                       |  2 +
 .../api-ms-win-crt-math-l1-1-0.spec                |  6 +-
 dlls/msvcr120/msvcr120.spec                        |  6 +-
 dlls/msvcr120/tests/msvcr120.c                     | 89 ++++++++++++++++++++++
 dlls/msvcr120_app/msvcr120_app.spec                |  6 +-
 dlls/msvcrt/math.c                                 | 38 +++++++++
 dlls/ucrtbase/ucrtbase.spec                        |  6 +-
 include/config.h.in                                |  6 ++
 9 files changed, 149 insertions(+), 12 deletions(-)

diff --git a/configure b/configure
index fa50a3c..793e2ff 100755
--- a/configure
+++ b/configure
@@ -18717,6 +18717,8 @@ for ac_func in \
 	lroundf \
 	nearbyint \
 	nearbyintf \
+	nexttoward \
+	nexttowardf \
 	powl \
 	remainder \
 	remainderf \
diff --git a/configure.ac b/configure.ac
index c661837..c978477 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2762,6 +2762,8 @@ AC_CHECK_FUNCS(\
 	lroundf \
 	nearbyint \
 	nearbyintf \
+	nexttoward \
+	nexttowardf \
 	powl \
 	remainder \
 	remainderf \
diff --git a/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec b/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec
index 0d645e5..f5e4fb1 100644
--- a/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec
+++ b/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec
@@ -297,9 +297,9 @@
 @ cdecl nextafter(double double) ucrtbase.nextafter
 @ cdecl nextafterf(float float) ucrtbase.nextafterf
 @ cdecl nextafterl(double double) ucrtbase.nextafterl
-@ stub nexttoward
-@ stub nexttowardf
-@ stub nexttowardl
+@ cdecl nexttoward(double double) ucrtbase.nexttoward
+@ cdecl nexttowardf(float double) ucrtbase.nexttowardf
+@ cdecl nexttowardl(double double) ucrtbase.nexttowardl
 @ stub norm
 @ stub normf
 @ stub norml
diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec
index 769ee50..7dfcabf 100644
--- a/dlls/msvcr120/msvcr120.spec
+++ b/dlls/msvcr120/msvcr120.spec
@@ -2302,9 +2302,9 @@
 @ cdecl nextafter(double double) MSVCRT__nextafter
 @ cdecl nextafterf(float float) MSVCRT__nextafterf
 @ cdecl nextafterl(double double) MSVCRT__nextafter
-@ stub nexttoward
-@ stub nexttowardf
-@ stub nexttowardl
+@ cdecl nexttoward(double double) MSVCRT_nexttoward
+@ cdecl nexttowardf(float double) MSVCRT_nexttowardf
+@ cdecl nexttowardl(double double) MSVCRT_nexttoward
 @ stub norm
 @ stub normf
 @ stub norml
diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c
index 79b667e..3077a18 100644
--- a/dlls/msvcr120/tests/msvcr120.c
+++ b/dlls/msvcr120/tests/msvcr120.c
@@ -127,6 +127,16 @@ static inline float __port_nan(void)
 }
 #define NAN __port_nan()
 
+static inline int isnormal(double d)
+{
+    return _fpclass(d) & (_FPCLASS_PN | _FPCLASS_NN);
+}
+
+static inline int isinf(double d)
+{
+    return _fpclass(d) & (_FPCLASS_PINF | _FPCLASS_NINF);
+}
+
 struct MSVCRT_lconv
 {
     char* decimal_point;
@@ -192,6 +202,9 @@ static unsigned short (__cdecl *p_wctype)(const char*);
 static int (__cdecl *p_vsscanf)(const char*, const char *, __ms_va_list valist);
 static _Dcomplex* (__cdecl *p__Cbuild)(_Dcomplex*, double, double);
 static double (__cdecl *p_creal)(_Dcomplex);
+static double (__cdecl *p_nexttoward)(double, double);
+static float (__cdecl *p_nexttowardf)(float, double);
+static double (__cdecl *p_nexttowardl)(double, double);
 
 /* make sure we use the correct errno */
 #undef errno
@@ -252,6 +265,9 @@ static BOOL init(void)
     SET(p_vsscanf, "vsscanf");
     SET(p__Cbuild, "_Cbuild");
     SET(p_creal, "creal");
+    SET(p_nexttoward, "nexttoward");
+    SET(p_nexttowardf, "nexttowardf");
+    SET(p_nexttowardl, "nexttowardl");
     if(sizeof(void*) == 8) { /* 64-bit initialization */
         SET(p_critical_section_ctor,
                 "??0critical_section at Concurrency@@QEAA at XZ");
@@ -964,6 +980,78 @@ static void test__Cbuild(void)
     ok(d == 3.0, "creal returned %lf\n", d);
 }
 
+static void test_nexttoward(void)
+{
+    errno_t e;
+    double d;
+    float f;
+    int i;
+
+    struct
+    {
+        double source;
+        double dir;
+        float f;
+        double d;
+    }
+    tests[] =
+    {
+        {0.0,                      0.0,                      0.0f,        0.0},
+        {0.0,                      1.0,                      1.0e-45f,    5.0e-324},
+        {0.0,                     -1.0,                     -1.0e-45f,   -5.0e-324},
+        {2.2250738585072009e-308,  0.0,                      0.0f,        2.2250738585072004e-308},
+        {2.2250738585072009e-308,  2.2250738585072010e-308,  1.0e-45f,    2.2250738585072009e-308},
+        {2.2250738585072009e-308,  1.0,                      1.0e-45f,    2.2250738585072014e-308},
+        {2.2250738585072014e-308,  0.0,                      0.0f,        2.2250738585072009e-308},
+        {2.2250738585072014e-308,  2.2250738585072014e-308,  1.0e-45f,    2.2250738585072014e-308},
+        {2.2250738585072014e-308,  1.0,                      1.0e-45f,    2.2250738585072019e-308},
+        {1.0,                      2.0,                      1.00000012f, 1.0000000000000002},
+        {1.0,                      0.0,                      0.99999994f, 0.9999999999999999},
+        {1.0,                      1.0,                      1.0f,        1.0},
+        {0.0,                      INFINITY,                 1.0e-45f,    5.0e-324},
+        {FLT_MAX,                  INFINITY,                 INFINITY,    3.402823466385289e+038},
+        {DBL_MAX,                  INFINITY,                 INFINITY,    INFINITY},
+        {INFINITY,                 INFINITY,                 INFINITY,    INFINITY},
+        {INFINITY,                 0,                        FLT_MAX,     DBL_MAX},
+    };
+
+    for (i = 0; i < ARRAY_SIZE(tests); ++i)
+    {
+        f = p_nexttowardf(tests[i].source, tests[i].dir);
+        ok(f == tests[i].f, "Test %d: expected %0.8ef, got %0.8ef.\n", i, tests[i].f, f);
+
+        errno = -1;
+        d = p_nexttoward(tests[i].source, tests[i].dir);
+        e = errno;
+        ok(d == tests[i].d, "Test %d: expected %0.16e, got %0.16e.\n", i, tests[i].d, d);
+        if (!isnormal(d) && !isinf(tests[i].source))
+            ok(e == ERANGE, "Test %d: expected ERANGE, got %d.\n", i, e);
+        else
+            ok(e == -1, "Test %d: expected no error, got %d.\n", i, e);
+
+        d = p_nexttowardl(tests[i].source, tests[i].dir);
+        ok(d == tests[i].d, "Test %d: expected %0.16e, got %0.16e.\n", i, tests[i].d, d);
+    }
+
+    errno = -1;
+    d = p_nexttoward(NAN, 0);
+    e = errno;
+    ok(_isnan(d), "Expected NAN, got %0.16e.\n", d);
+    ok(e == -1, "Expected no error, got %d.\n", e);
+
+    errno = -1;
+    d = p_nexttoward(NAN, NAN);
+    e = errno;
+    ok(_isnan(d), "Expected NAN, got %0.16e.\n", d);
+    ok(e == -1, "Expected no error, got %d.\n", e);
+
+    errno = -1;
+    d = p_nexttoward(0, NAN);
+    e = errno;
+    ok(_isnan(d), "Expected NAN, got %0.16e.\n", d);
+    ok(e == -1, "Expected no error, got %d.\n", e);
+}
+
 START_TEST(msvcr120)
 {
     if (!init()) return;
@@ -983,4 +1071,5 @@ START_TEST(msvcr120)
     test_wctype();
     test_vsscanf();
     test__Cbuild();
+    test_nexttoward();
 }
diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec
index e3323dd..d78d26f 100644
--- a/dlls/msvcr120_app/msvcr120_app.spec
+++ b/dlls/msvcr120_app/msvcr120_app.spec
@@ -1965,9 +1965,9 @@
 @ cdecl nextafter(double double) msvcr120.nextafter
 @ cdecl nextafterf(float float) msvcr120.nextafterf
 @ cdecl nextafterl(double double) msvcr120.nextafterl
-@ stub nexttoward
-@ stub nexttowardf
-@ stub nexttowardl
+@ cdecl nexttoward(double double) msvcr120.nexttoward
+@ cdecl nexttowardf(float double) msvcr120.nexttowardf
+@ cdecl nexttowardl(double double) msvcr120.nexttowardl
 @ stub norm
 @ stub normf
 @ stub norml
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index d4785d3..dc12cb1 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -1529,6 +1529,44 @@ float CDECL MSVCRT_nearbyintf(float num)
 #endif
 }
 
+/*********************************************************************
+ *              nexttoward (MSVCR120.@)
+ */
+double CDECL MSVCRT_nexttoward(double num, double next)
+{
+#ifdef HAVE_NEXTTOWARD
+    double ret = nexttoward(num, next);
+    if (!(MSVCRT__fpclass(ret) & (MSVCRT__FPCLASS_PN | MSVCRT__FPCLASS_NN
+            | MSVCRT__FPCLASS_SNAN | MSVCRT__FPCLASS_QNAN)) && !isinf(num))
+    {
+        *MSVCRT__errno() = MSVCRT_ERANGE;
+    }
+    return ret;
+#else
+    FIXME("not implemented\n");
+    return 0;
+#endif
+}
+
+/*********************************************************************
+ *              nexttowardf (MSVCR120.@)
+ */
+float CDECL MSVCRT_nexttowardf(float num, double next)
+{
+#ifdef HAVE_NEXTTOWARDF
+    float ret = nexttowardf(num, next);
+    if (!(MSVCRT__fpclass(ret) & (MSVCRT__FPCLASS_PN | MSVCRT__FPCLASS_NN
+            | MSVCRT__FPCLASS_SNAN | MSVCRT__FPCLASS_QNAN)) && !isinf(num))
+    {
+        *MSVCRT__errno() = MSVCRT_ERANGE;
+    }
+    return ret;
+#else
+    FIXME("not implemented\n");
+    return 0;
+#endif
+}
+
 #endif /* _MSVCR_VER>=120 */
 
 /*********************************************************************
diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec
index eb08843..00c8064 100644
--- a/dlls/ucrtbase/ucrtbase.spec
+++ b/dlls/ucrtbase/ucrtbase.spec
@@ -2438,9 +2438,9 @@
 @ cdecl nextafter(double double) MSVCRT__nextafter
 @ cdecl nextafterf(float float) MSVCRT__nextafterf
 @ cdecl nextafterl(double double) MSVCRT__nextafter
-@ stub nexttoward
-@ stub nexttowardf
-@ stub nexttowardl
+@ cdecl nexttoward(double double) MSVCRT_nexttoward
+@ cdecl nexttowardf(float double) MSVCRT_nexttowardf
+@ cdecl nexttowardl(double double) MSVCRT_nexttoward
 @ stub norm
 @ stub normf
 @ stub norml
diff --git a/include/config.h.in b/include/config.h.in
index 0c99a8c..149e8b1 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -696,6 +696,12 @@
 /* Define to 1 if you have the <net/route.h> header file. */
 #undef HAVE_NET_ROUTE_H
 
+/* Define to 1 if you have the `nexttoward' function. */
+#undef HAVE_NEXTTOWARD
+
+/* Define to 1 if you have the `nexttowardf' function. */
+#undef HAVE_NEXTTOWARDF
+
 /* Define to 1 if `_msg_ptr' is a member of `ns_msg'. */
 #undef HAVE_NS_MSG__MSG_PTR
 




More information about the wine-cvs mailing list