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