xref: /reactos/win32ss/gdi/eng/math.c (revision 40462c92)
1 /* Math functions for i387.
2    Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by John C. Bowman <bowman@ipp-garching.mpg.de>, 1995.
5 
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10 
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15 
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19    Boston, MA 02110-1301, USA.
20 */
21 
22 #include <win32k.h>
23 
24 INT
25 APIENTRY
26 EngMulDiv(
27     _In_ INT iMultiplicand,
28     _In_ INT iMultiplier,
29     _In_ INT iDivisor)
30 {
31     INT64 i64Multiplied, i64Result;
32 
33     /* Check for divide by zero */
34     if (iDivisor == 0)
35     {
36         /* Quick sign check and return "infinite" */
37         return ((iMultiplicand ^ iMultiplier) < 0) ? INT_MIN : INT_MAX;
38     }
39 
40     /* We want to deal with a positive divisor to simplify the logic. */
41     if (iDivisor < 0)
42     {
43         iMultiplicand = -iMultiplicand;
44         iDivisor = -iDivisor;
45     }
46 
47     /* Do the multiplication */
48     i64Multiplied = Int32x32To64(iMultiplicand, iMultiplier);
49 
50     /* If the result is positive, we add to round, else we subtract to round. */
51     if (i64Multiplied >= 0)
52     {
53         i64Multiplied += (iDivisor / 2);
54     }
55     else
56     {
57         i64Multiplied -= (iDivisor / 2);
58     }
59 
60     /* Now do the divide */
61     i64Result = i64Multiplied / iDivisor;
62 
63     /* Check for positive overflow */
64     if (i64Result > INT_MAX)
65     {
66         return INT_MAX;
67     }
68 
69     /* Check for negative overflow. */
70     if (i64Result < INT_MIN)
71     {
72         return INT_MIN;
73     }
74 
75     return (INT)i64Result;
76 }
77 
78