[ros-diffs] [gdalsnes] 18386: Fix MulDiv. This fixes almost any progress-bar to stop showing negative values during installations or etc. Thanks to kichik for originally having found the bug.

gdalsnes at svn.reactos.com gdalsnes at svn.reactos.com
Mon Oct 10 00:13:05 CEST 2005


Fix MulDiv. This fixes almost any progress-bar to stop showing negative
values during installations or etc. Thanks to kichik for originally
having found the bug.
Patch by alex ionescu
Modified: trunk/reactos/lib/kernel32/misc/muldiv.c
  _____  

Modified: trunk/reactos/lib/kernel32/misc/muldiv.c
--- trunk/reactos/lib/kernel32/misc/muldiv.c	2005-10-09 22:09:02 UTC
(rev 18385)
+++ trunk/reactos/lib/kernel32/misc/muldiv.c	2005-10-09 22:12:56 UTC
(rev 18386)
@@ -13,48 +13,42 @@

  *
  * @implemented
  */
-INT STDCALL MulDiv(
-             INT nMultiplicand,
-             INT nMultiplier,
-             INT nDivisor)
+INT
+WINAPI
+MulDiv(INT nNumber,
+       INT nNumerator,
+       INT nDenominator)
 {
-#if SIZEOF_LONG_LONG >= 8
-    long long ret;
-
-    if (!nDivisor) return -1;
-
-    /* We want to deal with a positive divisor to simplify the logic.
*/
-    if (nDivisor < 0)
+    LARGE_INTEGER Result;
+    LONG Negative;
+ 
+    /* Find out if this will be a negative result */
+    Negative = nNumber ^ nNumerator ^ nDenominator;
+ 
+    /* Turn all the parameters into absolute values */
+    if (nNumber < 0) nNumber *= -1;
+    if (nNumerator < 0) nNumerator *= -1;
+    if (nDenominator < 0) nDenominator *= -1;
+ 
+    /* Calculate the result */
+    Result.QuadPart = Int32x32To64(nNumber, nNumerator) + (nDenominator
/ 2);
+ 
+    /* Now check for overflow */
+    if (nDenominator > Result.HighPart)
     {
-      nMultiplicand = - nMultiplicand;
-      nDivisor = -nDivisor;
+        /* Divide the product to get the quotient and remainder */
+        Result.LowPart =
RtlEnlargedUnsignedDivide(*(PULARGE_INTEGER)&Result,
+                                                   (ULONG)nDenominator,
+                                                   &Result.HighPart);
+ 
+        /* Do the sign changes */
+        if ((LONG)Result.LowPart >= 0)
+        {
+            return (Negative >= 0) ? Result.LowPart :
-(LONG)Result.LowPart;
+        }
     }
-
-    /* If the result is positive, we "add" to round. else, we subtract
to round. */
-    if ( ( (nMultiplicand <  0) && (nMultiplier <  0) ) ||
-         ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
-      ret = (((long long)nMultiplicand * nMultiplier) + (nDivisor/2)) /
nDivisor;
-    else
-      ret = (((long long)nMultiplicand * nMultiplier) - (nDivisor/2)) /
nDivisor;
-
-    if ((ret > 2147483647) || (ret < -2147483647)) return -1;
-    return ret;
-#else
-    if (!nDivisor) return -1;
-
-    /* We want to deal with a positive divisor to simplify the logic.
*/
-    if (nDivisor < 0)
-    {
-      nMultiplicand = - nMultiplicand;
-      nDivisor = -nDivisor;
-    }
-
-    /* If the result is positive, we "add" to round. else, we subtract
to round. */
-    if ( ( (nMultiplicand <  0) && (nMultiplier <  0) ) ||
-         ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
-      return ((nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
-
-    return ((nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
-
-#endif
+ 
+    /* Return overflow */
+    return - 1;
 }
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-diffs/attachments/20051010/c8f0e4dc/attachment.html


More information about the Ros-diffs mailing list