Piotr Caban : msvcrt/tests: Improve doubles comparison in strtod and atodbl tests.

Alexandre Julliard julliard at winehq.org
Thu Dec 26 15:44:39 CST 2019


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Thu Dec 26 18:30:48 2019 +0100

msvcrt/tests: Improve doubles comparison in strtod and atodbl tests.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/tests/string.c | 80 ++++++++++++++++++++++++----------------------
 1 file changed, 42 insertions(+), 38 deletions(-)

diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index fa2c8d6196..08bc0781e1 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -1880,17 +1880,21 @@ static void test__strtoi64(void)
     ok(errno == ERANGE, "errno = %x\n", errno);
 }
 
-static inline BOOL almost_equal(double d1, double d2) {
-    if(d1-d2>-1e-30 && d1-d2<1e-30)
-        return TRUE;
-    return FALSE;
-}
+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;
 
-static inline BOOL large_almost_equal(double d1, double d2) {
-    double diff = fabs(d1-d2);
-    if(diff / (fabs(d1) + fabs(d2)) < DBL_EPSILON)
-        return TRUE;
-    return FALSE;
+    return (x>y ? x-y : y-x) <= ulps;
 }
 
 static void test__strtod(void)
@@ -1908,34 +1912,34 @@ static void test__strtod(void)
     double d;
 
     d = strtod(double1, &end);
-    ok(almost_equal(d, 12.1), "d = %lf\n", d);
+    ok(d == 12.1, "d = %.16e\n", d);
     ok(end == double1+4, "incorrect end (%d)\n", (int)(end-double1));
 
     d = strtod(double2, &end);
-    ok(almost_equal(d, -13.721), "d = %lf\n", d);
+    ok(d == -13.721, "d = %.16e\n", d);
     ok(end == double2+7, "incorrect end (%d)\n", (int)(end-double2));
 
     d = strtod(double3, &end);
-    ok(almost_equal(d, 0), "d = %lf\n", d);
+    ok(d == 0, "d = %.16e\n", d);
     ok(end == double3, "incorrect end (%d)\n", (int)(end-double3));
 
     d = strtod(double4, &end);
-    ok(almost_equal(d, 210000000000.0), "d = %lf\n", d);
+    ok(d == 210000000000.0, "d = %.16e\n", d);
     ok(end == double4+6, "incorrect end (%d)\n", (int)(end-double4));
 
     d = strtod(double5, &end);
-    ok(almost_equal(d, 214.353), "d = %lf\n", d);
+    ok(d == 214.353, "d = %.16e\n", d);
     ok(end == double5+9, "incorrect end (%d)\n", (int)(end-double5));
 
     d = strtod(double6, &end);
-    ok(almost_equal(d, 0), "d = %lf\n", d);
+    ok(d == 0, "d = %.16e\n", d);
     ok(end == double6, "incorrect end (%d)\n", (int)(end-double6));
 
     d = strtod("12.1d2", NULL);
-    ok(almost_equal(d, 12.1e2), "d = %lf\n", d);
+    ok(d == 12.1e2, "d = %.16e\n", d);
 
     d = strtod(white_chars, &end);
-    ok(almost_equal(d, 0), "d = %lf\n", d);
+    ok(d == 0, "d = %.16e\n", d);
     ok(end == white_chars, "incorrect end (%d)\n", (int)(end-white_chars));
 
     if (!p__strtod_l)
@@ -1944,19 +1948,19 @@ static void test__strtod(void)
     {
         errno = EBADF;
         d = strtod(NULL, NULL);
-        ok(almost_equal(d, 0.0), "d = %lf\n", d);
+        ok(d == 0.0, "d = %.16e\n", d);
         ok(errno == EINVAL, "errno = %x\n", errno);
 
         errno = EBADF;
         end = (char *)0xdeadbeef;
         d = strtod(NULL, &end);
-        ok(almost_equal(d, 0.0), "d = %lf\n", d);
+        ok(d == 0.0, "d = %.16e\n", d);
         ok(errno == EINVAL, "errno = %x\n", errno);
         ok(!end, "incorrect end ptr %p\n", end);
 
         errno = EBADF;
         d = p__strtod_l(NULL, NULL, NULL);
-        ok(almost_equal(d, 0.0), "d = %lf\n", d);
+        ok(d == 0.0, "d = %.16e\n", d);
         ok(errno == EINVAL, "errno = %x\n", errno);
     }
 
@@ -1967,28 +1971,28 @@ static void test__strtod(void)
     }
 
     d = strtod("12.1", NULL);
-    ok(almost_equal(d, 12.0), "d = %lf\n", d);
+    ok(d == 12.0, "d = %.16e\n", d);
 
     d = strtod("12,1", NULL);
-    ok(almost_equal(d, 12.1), "d = %lf\n", d);
+    ok(d == 12.1, "d = %.16e\n", d);
 
     setlocale(LC_ALL, "C");
 
     /* Precision tests */
     d = strtod("0.1", NULL);
-    ok(almost_equal(d, 0.1), "d = %lf\n", d);
+    ok(d == 0.1, "d = %.16e\n", d);
     d = strtod("-0.1", NULL);
-    ok(almost_equal(d, -0.1), "d = %lf\n", d);
+    ok(d == -0.1, "d = %.16e\n", d);
     d = strtod("0.1281832188491894198128921", NULL);
-    ok(almost_equal(d, 0.1281832188491894198128921), "d = %lf\n", d);
+    ok(d == 0.1281832188491894198128921, "d = %.16e\n", d);
     d = strtod("0.82181281288121", NULL);
-    ok(almost_equal(d, 0.82181281288121), "d = %lf\n", d);
+    ok(d == 0.82181281288121, "d = %.16e\n", d);
     d = strtod("21921922352523587651128218821", NULL);
-    ok(almost_equal(d, 21921922352523587651128218821.0), "d = %lf\n", d);
+    ok(d == 21921922352523587651128218821.0, "d = %.16e\n", d);
     d = strtod("0.1d238", NULL);
-    ok(almost_equal(d, 0.1e238L), "d = %lf\n", d);
+    ok(d == 0.1e238, "d = %.16e\n", d);
     d = strtod("0.1D-4736", NULL);
-    ok(almost_equal(d, 0.1e-4736L), "d = %lf\n", d);
+    ok(d == 0.0, "d = %.16e\n", d);
 
     errno = 0xdeadbeef;
     strtod(overflow, &end);
@@ -3067,7 +3071,7 @@ static void test__atodbl(void)
             if (expected < DBL_MIN || expected > DBL_MAX) continue;
             snprintf(num, sizeof(num), "%de%d", i, j);
             ret = _atodbl(&d, num);
-            ok(large_almost_equal(d.x, expected), "d.x = %le, expected %le\n", d.x, expected);
+            ok(compare_double(d.x, expected, 2), "d.x = %.16e, expected %.16e\n", d.x, expected);
         }
     }
 
@@ -3075,10 +3079,10 @@ static void test__atodbl(void)
     strcpy(num, "1e-309");
     ret = p__atodbl_l(&d, num, NULL);
     ok(ret == _UNDERFLOW, "_atodbl_l(&d, \"1e-309\", NULL) returned %d, expected _UNDERFLOW\n", ret);
-    ok(d.x!=0 && almost_equal(d.x, 0.1e-308), "d.x = %le, expected 0.1e-308\n", d.x);
+    ok(compare_double(d.x, 1e-309, 1), "d.x = %.16e, expected 0\n", d.x);
     ret = _atodbl(&d, num);
     ok(ret == _UNDERFLOW, "_atodbl(&d, \"1e-309\") returned %d, expected _UNDERFLOW\n", ret);
-    ok(d.x!=0 && almost_equal(d.x, 0.1e-308), "d.x = %le, expected 0.1e-308\n", d.x);
+    ok(compare_double(d.x, 1e-309, 1), "d.x = %.16e, expected 0\n", d.x);
 
     strcpy(num, "1e309");
     ret = p__atodbl_l(&d, num, NULL);
@@ -3283,13 +3287,13 @@ static void test_atof(void)
     double d;
 
     d = atof("0.0");
-    ok(almost_equal(d, 0.0), "d = %lf\n", d);
+    ok(d == 0.0, "d = %lf\n", d);
 
     d = atof("1.0");
-    ok(almost_equal(d, 1.0), "d = %lf\n", d);
+    ok(d == 1.0, "d = %lf\n", d);
 
     d = atof("-1.0");
-    ok(almost_equal(d, -1.0), "d = %lf\n", d);
+    ok(d == -1.0, "d = %lf\n", d);
 
     if (!p__atof_l)
     {
@@ -3299,12 +3303,12 @@ static void test_atof(void)
 
     errno = EBADF;
     d = atof(NULL);
-    ok(almost_equal(d, 0.0), "d = %lf\n", d);
+    ok(d == 0.0, "d = %lf\n", d);
     ok(errno == EINVAL, "errno = %x\n", errno);
 
     errno = EBADF;
     d = p__atof_l(NULL, NULL);
-    ok(almost_equal(d, 0.0), "d = %lf\n", d);
+    ok(d == 0.0, "d = %lf\n", d);
     ok(errno == EINVAL, "errno = %x\n", errno);
 }
 




More information about the wine-cvs mailing list