22 #define LLtoU64(x) (*(unsigned __int64*)(void*)(&(x)))
28 IN ULARGE_INTEGER Dividend,
34 if (Remainder !=
NULL)
44 IN ULARGE_INTEGER Dividend,
51 mov eax,Dividend.LowPart
52 mov edx,Dividend.HighPart
73 #define UInt32x32To64(a, b) (((ULONGLONG)((ULONG)(a)) & 0xffffffff) * ((ULONGLONG)((ULONG)(b)) & 0xffffffff))
77 LONGLONG WINAPI
llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG d)
80 ULARGE_INTEGER ua, ub;
83 ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
84 ub.QuadPart = (DWORDLONG)(b >= 0 ? b : -b);
85 uc = (DWORDLONG)(c >= 0 ? c : -c);
86 BOOL bSign = (a < 0) ^ (b < 0);
90 p[0].QuadPart = UInt32x32To64(ua.LowPart, ub.LowPart);
104 x.QuadPart = UInt32x32To64(ua.LowPart, ub.HighPart) +
105 UInt32x32To64(ua.HighPart, ub.LowPart) +
107 p[0].HighPart = x.LowPart;
108 p[1].QuadPart = UInt32x32To64(ua.HighPart, ub.HighPart) + x.HighPart;
111 ULARGE_INTEGER ud[2];
113 ud[0].QuadPart = (DWORDLONG)(-d);
116 ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
118 ud[1].QuadPart = (DWORDLONG)0;
121 ud[0].QuadPart = (DWORDLONG)d;
123 ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
125 ud[1].QuadPart = (DWORDLONG)0;
129 ULARGE_INTEGER uliTotal;
132 uliTotal.QuadPart = (DWORDLONG)ud[0].LowPart + p[0].LowPart;
133 p[0].LowPart = uliTotal.LowPart;
136 uliTotal.LowPart = uliTotal.HighPart;
137 uliTotal.HighPart = 0;
140 uliTotal.QuadPart += (DWORDLONG)ud[0].HighPart + p[0].HighPart;
141 p[0].HighPart = uliTotal.LowPart;
144 uliTotal.LowPart = uliTotal.HighPart;
145 uliTotal.HighPart = 0;
148 p[1].QuadPart += ud[1].QuadPart + uliTotal.QuadPart;
151 if ((LONG)p[1].HighPart < 0) {
155 p[0].QuadPart = ~p[0].QuadPart;
156 p[1].QuadPart = ~p[1].QuadPart;
158 p[1].QuadPart += (p[0].QuadPart == 0);
169 if (uc <= p[1].QuadPart) {
170 return bSign ? (LONGLONG)0x8000000000000000 :
171 (LONGLONG)0x7FFFFFFFFFFFFFFF;
178 if (p[1].QuadPart == 0) {
179 ullResult = p[0].QuadPart / uc;
180 return bSign ? -(LONGLONG)ullResult : (LONGLONG)ullResult;
186 if (ulic.HighPart == 0) {
187 ULARGE_INTEGER uliDividend;
188 ULARGE_INTEGER uliResult;
189 DWORD dwDivisor = (DWORD)uc;
191 uliDividend.HighPart = p[1].LowPart;
192 uliDividend.LowPart = p[0].HighPart;
194 uliResult.HighPart = (DWORD)(uliDividend.QuadPart / dwDivisor);
195 p[0].HighPart = (DWORD)(uliDividend.QuadPart % dwDivisor);
196 uliResult.LowPart = 0;
197 uliResult.QuadPart = p[0].QuadPart / dwDivisor + uliResult.QuadPart;
202 if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) {
208 uliResult.HighPart = 0;
215 return bSign ? -(LONGLONG)uliResult.QuadPart :
216 (LONGLONG)uliResult.QuadPart;
223 for (
int i = 0; i < 64; i++) {
228 if ((p[0].HighPart & 0x80000000) != 0) {
234 if (uc <= p[1].QuadPart) {
240 return bSign ? - (LONGLONG)ullResult : (LONGLONG)ullResult;
250 ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
251 ub = (DWORD)(b >= 0 ? b : -b);
252 uc = (DWORD)(c >= 0 ? c : -c);
253 BOOL bSign = (a < 0) ^ (b < 0);
258 p0.QuadPart = UInt32x32To64(ua.LowPart, ub);
260 if (ua.HighPart != 0) {
262 x.QuadPart = UInt32x32To64(ua.HighPart, ub) + p0.HighPart;
263 p0.HighPart = x.LowPart;
278 ud0.QuadPart = (DWORDLONG)(-(LONGLONG)d);
286 ud0.QuadPart = (DWORDLONG)d;
294 ULARGE_INTEGER uliTotal;
297 uliTotal.QuadPart = (DWORDLONG)ud0.LowPart + p0.LowPart;
298 p0.LowPart = uliTotal.LowPart;
301 uliTotal.LowPart = uliTotal.HighPart;
302 uliTotal.HighPart = 0;
305 uliTotal.QuadPart += (DWORDLONG)ud0.HighPart + p0.HighPart;
306 p0.HighPart = uliTotal.LowPart;
309 p1 += ud1 + uliTotal.HighPart;
316 p0.QuadPart = ~p0.QuadPart;
319 p1 += (p0.QuadPart == 0);
331 return bSign ? (LONGLONG)0x8000000000000000 :
332 (LONGLONG)0x7FFFFFFFFFFFFFFF;
338 ULARGE_INTEGER uliDividend;
339 ULARGE_INTEGER uliResult;
340 DWORD dwDivisor = uc;
341 uliDividend.HighPart = p1;
342 uliDividend.LowPart = p0.HighPart;
346 if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) {
352 uliResult.HighPart = 0;
358 return bSign ? -(LONGLONG)uliResult.QuadPart :
359 (LONGLONG)uliResult.QuadPart;