Piotr Caban : msvcrt: Fix round implementation when 24-bit precision is used.

Alexandre Julliard julliard at winehq.org
Mon May 3 16:37:05 CDT 2021


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon May  3 14:01:57 2021 +0200

msvcrt: Fix round implementation when 24-bit precision is used.

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

---

 dlls/msvcrt/math.c | 42 ++++++++++++++----------------------------
 1 file changed, 14 insertions(+), 28 deletions(-)

diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index a29ed5786e2..1da6a0162da 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -87,14 +87,6 @@ static inline float fp_barrierf(float x)
     return y;
 }
 
-#if _MSVCR_VER>=120
-static inline double fp_barrier(double x)
-{
-    volatile double y = x;
-    return y;
-}
-#endif
-
 static inline double CDECL ret_nan( BOOL update_sw )
 {
     double x = 1.0;
@@ -4330,32 +4322,26 @@ short CDECL _dclass(double x)
 /*********************************************************************
  *      round (MSVCR120.@)
  *
- * Copied from musl: src/math/round.c
+ * Based on musl implementation: src/math/round.c
  */
 double CDECL round(double x)
 {
-    static const double toint = 1 / DBL_EPSILON;
+    ULONGLONG llx = *(ULONGLONG*)&x, tmp;
+    int e = (llx >> 52 & 0x7ff) - 0x3ff;
 
-    ULONGLONG llx = *(ULONGLONG*)&x;
-    int e = llx >> 52 & 0x7ff;
-    double y;
+    if (e >= 52)
+        return x;
+    if (e < -1)
+        return 0 * x;
+    else if (e == -1)
+        return signbit(x) ? -1 : 1;
 
-    if (e >= 0x3ff + 52)
+    tmp = 0x000fffffffffffffULL >> e;
+    if (!(llx & tmp))
         return x;
-    if (llx >> 63)
-        x = -x;
-    if (e < 0x3ff - 1)
-        return 0 * *(double*)&llx;
-    y = fp_barrier(x + toint) - toint - x;
-    if (y > 0.5)
-        y = y + x - 1;
-    else if (y <= -0.5)
-        y = y + x + 1;
-    else
-        y = y + x;
-    if (llx >> 63)
-        y = -y;
-    return y;
+    llx += 0x0008000000000000ULL >> e;
+    llx &= ~tmp;
+    return *(double*)&llx;
 }
 
 /*********************************************************************




More information about the wine-cvs mailing list