xref: /reactos/dll/win32/kernel32/wine/muldiv.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS system libraries
4  * FILE:            dll/win32/kernel32/wine/muldiv.c
5  * PURPOSE:
6  * PROGRAMMER:      Casper S. Hornstrup
7  *                  Gunnar Andre Dalsnes
8  * UPDATE HISTORY:
9  *                  Created 06/12/2002
10  */
11 
12 #include <k32.h>
13 
14 /***********************************************************************
15  *           MulDiv   (KERNEL32.@)
16  * RETURNS
17  *      Result of multiplication and division
18  *      -1: Overflow occurred or Divisor was 0
19  * FIXME! move to correct file
20  *
21  * @implemented
22  */
23 INT
24 WINAPI
MulDiv(INT nNumber,INT nNumerator,INT nDenominator)25 MulDiv(INT nNumber,
26        INT nNumerator,
27        INT nDenominator)
28 {
29     LARGE_INTEGER Result;
30     LONG Negative;
31 
32     /* Find out if this will be a negative result */
33     Negative = nNumber ^ nNumerator ^ nDenominator;
34 
35     /* Turn all the parameters into absolute values */
36     if (nNumber < 0) nNumber *= -1;
37     if (nNumerator < 0) nNumerator *= -1;
38     if (nDenominator < 0) nDenominator *= -1;
39 
40     /* Calculate the result */
41     Result.QuadPart = Int32x32To64(nNumber, nNumerator) + (nDenominator / 2);
42 
43     /* Now check for overflow */
44     if (nDenominator > Result.HighPart)
45     {
46         /* Divide the product to get the quotient and remainder */
47         Result.LowPart = RtlEnlargedUnsignedDivide(*(PULARGE_INTEGER)&Result,
48                                                    (ULONG)nDenominator,
49                                                    (PULONG)&Result.HighPart);
50 
51         /* Do the sign changes */
52         if ((LONG)Result.LowPart >= 0)
53         {
54             return (Negative >= 0) ? (LONG)Result.LowPart : -(LONG)Result.LowPart;
55         }
56     }
57 
58     /* Return overflow */
59     return - 1;
60 }
61 
62