forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			361 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			361 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// File: ArithUtil.cpp
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Desc: DirectShow base classes - implements helper classes for building
							 | 
						||
| 
								 | 
							
								//       multimedia filters.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Copyright (c) 1992-2004 Microsoft Corporation.  All rights reserved.
							 | 
						||
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <streams.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Declare function from largeint.h we need so that PPC can build
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Enlarged integer divide - 64-bits / 32-bits > 32-bits
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef _X86_
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define LLtoU64(x) (*(unsigned __int64*)(void*)(&(x)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								__inline
							 | 
						||
| 
								 | 
							
								ULONG
							 | 
						||
| 
								 | 
							
								WINAPI
							 | 
						||
| 
								 | 
							
								EnlargedUnsignedDivide (
							 | 
						||
| 
								 | 
							
								    IN ULARGE_INTEGER Dividend,
							 | 
						||
| 
								 | 
							
								    IN ULONG Divisor,
							 | 
						||
| 
								 | 
							
								    IN PULONG Remainder
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								        // return remainder if necessary
							 | 
						||
| 
								 | 
							
								        if (Remainder != NULL)
							 | 
						||
| 
								 | 
							
								                *Remainder = (ULONG)(LLtoU64(Dividend) % Divisor);
							 | 
						||
| 
								 | 
							
								        return (ULONG)(LLtoU64(Dividend) / Divisor);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								__inline
							 | 
						||
| 
								 | 
							
								ULONG
							 | 
						||
| 
								 | 
							
								WINAPI
							 | 
						||
| 
								 | 
							
								EnlargedUnsignedDivide (
							 | 
						||
| 
								 | 
							
								    IN ULARGE_INTEGER Dividend,
							 | 
						||
| 
								 | 
							
								    IN ULONG Divisor,
							 | 
						||
| 
								 | 
							
								    IN PULONG Remainder
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ULONG ulResult;
							 | 
						||
| 
								 | 
							
								    _asm {
							 | 
						||
| 
								 | 
							
								        mov eax,Dividend.LowPart
							 | 
						||
| 
								 | 
							
								        mov edx,Dividend.HighPart
							 | 
						||
| 
								 | 
							
								        mov ecx,Remainder
							 | 
						||
| 
								 | 
							
								        div Divisor
							 | 
						||
| 
								 | 
							
								        or  ecx,ecx
							 | 
						||
| 
								 | 
							
								        jz  short label
							 | 
						||
| 
								 | 
							
								        mov [ecx],edx
							 | 
						||
| 
								 | 
							
								label:
							 | 
						||
| 
								 | 
							
								        mov ulResult,eax
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return ulResult;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*  Arithmetic functions to help with time format conversions
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _M_ALPHA
							 | 
						||
| 
								 | 
							
								// work around bug in version 12.00.8385 of the alpha compiler where
							 | 
						||
| 
								 | 
							
								// UInt32x32To64 sign-extends its arguments (?)
							 | 
						||
| 
								 | 
							
								#undef UInt32x32To64
							 | 
						||
| 
								 | 
							
								#define UInt32x32To64(a, b) (((ULONGLONG)((ULONG)(a)) & 0xffffffff) * ((ULONGLONG)((ULONG)(b)) & 0xffffffff))
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*   Compute (a * b + d) / c */
							 | 
						||
| 
								 | 
							
								LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG d)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /*  Compute the absolute values to avoid signed arithmetic problems */
							 | 
						||
| 
								 | 
							
								    ULARGE_INTEGER ua, ub;
							 | 
						||
| 
								 | 
							
								    DWORDLONG uc;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
							 | 
						||
| 
								 | 
							
								    ub.QuadPart = (DWORDLONG)(b >= 0 ? b : -b);
							 | 
						||
| 
								 | 
							
								    uc          = (DWORDLONG)(c >= 0 ? c : -c);
							 | 
						||
| 
								 | 
							
								    BOOL bSign = (a < 0) ^ (b < 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  Do long multiplication */
							 | 
						||
| 
								 | 
							
								    ULARGE_INTEGER p[2];
							 | 
						||
| 
								 | 
							
								    p[0].QuadPart  = UInt32x32To64(ua.LowPart, ub.LowPart);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  This next computation cannot overflow into p[1].HighPart because
							 | 
						||
| 
								 | 
							
								        the max number we can compute here is:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                 (2 ** 32 - 1) * (2 ** 32 - 1) +  // ua.LowPart * ub.LowPart
							 | 
						||
| 
								 | 
							
								    (2 ** 32) *  (2 ** 31) * (2 ** 32 - 1) * 2    // x.LowPart * y.HighPart * 2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    == 2 ** 96 - 2 ** 64 + (2 ** 64 - 2 ** 33 + 1)
							 | 
						||
| 
								 | 
							
								    == 2 ** 96 - 2 ** 33 + 1
							 | 
						||
| 
								 | 
							
								    < 2 ** 96
							 | 
						||
| 
								 | 
							
								    */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ULARGE_INTEGER x;
							 | 
						||
| 
								 | 
							
								    x.QuadPart     = UInt32x32To64(ua.LowPart, ub.HighPart) +
							 | 
						||
| 
								 | 
							
								                     UInt32x32To64(ua.HighPart, ub.LowPart) +
							 | 
						||
| 
								 | 
							
								                     p[0].HighPart;
							 | 
						||
| 
								 | 
							
								    p[0].HighPart  = x.LowPart;
							 | 
						||
| 
								 | 
							
								    p[1].QuadPart  = UInt32x32To64(ua.HighPart, ub.HighPart) + x.HighPart;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (d != 0) {
							 | 
						||
| 
								 | 
							
								        ULARGE_INTEGER ud[2];
							 | 
						||
| 
								 | 
							
								        if (bSign) {
							 | 
						||
| 
								 | 
							
								            ud[0].QuadPart = (DWORDLONG)(-d);
							 | 
						||
| 
								 | 
							
								            if (d > 0) {
							 | 
						||
| 
								 | 
							
								                /*  -d < 0 */
							 | 
						||
| 
								 | 
							
								                ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                ud[1].QuadPart = (DWORDLONG)0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            ud[0].QuadPart = (DWORDLONG)d;
							 | 
						||
| 
								 | 
							
								            if (d < 0) {
							 | 
						||
| 
								 | 
							
								                ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                ud[1].QuadPart = (DWORDLONG)0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        /*  Now do extended addition */
							 | 
						||
| 
								 | 
							
								        ULARGE_INTEGER uliTotal;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Add ls DWORDs */
							 | 
						||
| 
								 | 
							
								        uliTotal.QuadPart  = (DWORDLONG)ud[0].LowPart + p[0].LowPart;
							 | 
						||
| 
								 | 
							
								        p[0].LowPart       = uliTotal.LowPart;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Propagate carry */
							 | 
						||
| 
								 | 
							
								        uliTotal.LowPart   = uliTotal.HighPart;
							 | 
						||
| 
								 | 
							
								        uliTotal.HighPart  = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Add 2nd most ls DWORDs */
							 | 
						||
| 
								 | 
							
								        uliTotal.QuadPart += (DWORDLONG)ud[0].HighPart + p[0].HighPart;
							 | 
						||
| 
								 | 
							
								        p[0].HighPart      = uliTotal.LowPart;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Propagate carry */
							 | 
						||
| 
								 | 
							
								        uliTotal.LowPart   = uliTotal.HighPart;
							 | 
						||
| 
								 | 
							
								        uliTotal.HighPart  = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Add MS DWORDLONGs - no carry expected */
							 | 
						||
| 
								 | 
							
								        p[1].QuadPart     += ud[1].QuadPart + uliTotal.QuadPart;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Now see if we got a sign change from the addition */
							 | 
						||
| 
								 | 
							
								        if ((LONG)p[1].HighPart < 0) {
							 | 
						||
| 
								 | 
							
								            bSign = !bSign;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            /*  Negate the current value (ugh!) */
							 | 
						||
| 
								 | 
							
								            p[0].QuadPart  = ~p[0].QuadPart;
							 | 
						||
| 
								 | 
							
								            p[1].QuadPart  = ~p[1].QuadPart;
							 | 
						||
| 
								 | 
							
								            p[0].QuadPart += 1;
							 | 
						||
| 
								 | 
							
								            p[1].QuadPart += (p[0].QuadPart == 0);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  Now for the division */
							 | 
						||
| 
								 | 
							
								    if (c < 0) {
							 | 
						||
| 
								 | 
							
								        bSign = !bSign;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  This will catch c == 0 and overflow */
							 | 
						||
| 
								 | 
							
								    if (uc <= p[1].QuadPart) {
							 | 
						||
| 
								 | 
							
								        return bSign ? (LONGLONG)0x8000000000000000 :
							 | 
						||
| 
								 | 
							
								                       (LONGLONG)0x7FFFFFFFFFFFFFFF;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORDLONG ullResult;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  Do the division */
							 | 
						||
| 
								 | 
							
								    /*  If the dividend is a DWORD_LONG use the compiler */
							 | 
						||
| 
								 | 
							
								    if (p[1].QuadPart == 0) {
							 | 
						||
| 
								 | 
							
								        ullResult = p[0].QuadPart / uc;
							 | 
						||
| 
								 | 
							
								        return bSign ? -(LONGLONG)ullResult : (LONGLONG)ullResult;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  If the divisor is a DWORD then its simpler */
							 | 
						||
| 
								 | 
							
								    ULARGE_INTEGER ulic;
							 | 
						||
| 
								 | 
							
								    ulic.QuadPart = uc;
							 | 
						||
| 
								 | 
							
								    if (ulic.HighPart == 0) {
							 | 
						||
| 
								 | 
							
								        ULARGE_INTEGER uliDividend;
							 | 
						||
| 
								 | 
							
								        ULARGE_INTEGER uliResult;
							 | 
						||
| 
								 | 
							
								        DWORD dwDivisor = (DWORD)uc;
							 | 
						||
| 
								 | 
							
								        // ASSERT(p[1].HighPart == 0 && p[1].LowPart < dwDivisor);
							 | 
						||
| 
								 | 
							
								        uliDividend.HighPart = p[1].LowPart;
							 | 
						||
| 
								 | 
							
								        uliDividend.LowPart = p[0].HighPart;
							 | 
						||
| 
								 | 
							
								#ifndef USE_LARGEINT
							 | 
						||
| 
								 | 
							
								        uliResult.HighPart = (DWORD)(uliDividend.QuadPart / dwDivisor);
							 | 
						||
| 
								 | 
							
								        p[0].HighPart = (DWORD)(uliDividend.QuadPart % dwDivisor);
							 | 
						||
| 
								 | 
							
								        uliResult.LowPart = 0;
							 | 
						||
| 
								 | 
							
								        uliResult.QuadPart = p[0].QuadPart / dwDivisor + uliResult.QuadPart;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        /*  NOTE - this routine will take exceptions if
							 | 
						||
| 
								 | 
							
								            the result does not fit in a DWORD
							 | 
						||
| 
								 | 
							
								        */
							 | 
						||
| 
								 | 
							
								        if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) {
							 | 
						||
| 
								 | 
							
								            uliResult.HighPart = EnlargedUnsignedDivide(
							 | 
						||
| 
								 | 
							
								                                     uliDividend,
							 | 
						||
| 
								 | 
							
								                                     dwDivisor,
							 | 
						||
| 
								 | 
							
								                                     &p[0].HighPart);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            uliResult.HighPart = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        uliResult.LowPart = EnlargedUnsignedDivide(
							 | 
						||
| 
								 | 
							
								                                 p[0],
							 | 
						||
| 
								 | 
							
								                                 dwDivisor,
							 | 
						||
| 
								 | 
							
								                                 NULL);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        return bSign ? -(LONGLONG)uliResult.QuadPart :
							 | 
						||
| 
								 | 
							
								                        (LONGLONG)uliResult.QuadPart;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ullResult = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  OK - do long division */
							 | 
						||
| 
								 | 
							
								    for (int i = 0; i < 64; i++) {
							 | 
						||
| 
								 | 
							
								        ullResult <<= 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Shift 128 bit p left 1 */
							 | 
						||
| 
								 | 
							
								        p[1].QuadPart <<= 1;
							 | 
						||
| 
								 | 
							
								        if ((p[0].HighPart & 0x80000000) != 0) {
							 | 
						||
| 
								 | 
							
								            p[1].LowPart++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        p[0].QuadPart <<= 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Compare */
							 | 
						||
| 
								 | 
							
								        if (uc <= p[1].QuadPart) {
							 | 
						||
| 
								 | 
							
								            p[1].QuadPart -= uc;
							 | 
						||
| 
								 | 
							
								            ullResult += 1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return bSign ? - (LONGLONG)ullResult : (LONGLONG)ullResult;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG d)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ULARGE_INTEGER ua;
							 | 
						||
| 
								 | 
							
								    DWORD ub;
							 | 
						||
| 
								 | 
							
								    DWORD uc;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  Compute the absolute values to avoid signed arithmetic problems */
							 | 
						||
| 
								 | 
							
								    ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
							 | 
						||
| 
								 | 
							
								    ub = (DWORD)(b >= 0 ? b : -b);
							 | 
						||
| 
								 | 
							
								    uc = (DWORD)(c >= 0 ? c : -c);
							 | 
						||
| 
								 | 
							
								    BOOL bSign = (a < 0) ^ (b < 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  Do long multiplication */
							 | 
						||
| 
								 | 
							
								    ULARGE_INTEGER p0;
							 | 
						||
| 
								 | 
							
								    DWORD p1;
							 | 
						||
| 
								 | 
							
								    p0.QuadPart  = UInt32x32To64(ua.LowPart, ub);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (ua.HighPart != 0) {
							 | 
						||
| 
								 | 
							
								        ULARGE_INTEGER x;
							 | 
						||
| 
								 | 
							
								        x.QuadPart     = UInt32x32To64(ua.HighPart, ub) + p0.HighPart;
							 | 
						||
| 
								 | 
							
								        p0.HighPart  = x.LowPart;
							 | 
						||
| 
								 | 
							
								        p1   = x.HighPart;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        p1 = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (d != 0) {
							 | 
						||
| 
								 | 
							
								        ULARGE_INTEGER ud0;
							 | 
						||
| 
								 | 
							
								        DWORD ud1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (bSign) {
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            //  Cast d to LONGLONG first otherwise -0x80000000 sign extends
							 | 
						||
| 
								 | 
							
								            //  incorrectly
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            ud0.QuadPart = (DWORDLONG)(-(LONGLONG)d);
							 | 
						||
| 
								 | 
							
								            if (d > 0) {
							 | 
						||
| 
								 | 
							
								                /*  -d < 0 */
							 | 
						||
| 
								 | 
							
								                ud1 = (DWORD)-1;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                ud1 = (DWORD)0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            ud0.QuadPart = (DWORDLONG)d;
							 | 
						||
| 
								 | 
							
								            if (d < 0) {
							 | 
						||
| 
								 | 
							
								                ud1 = (DWORD)-1;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                ud1 = (DWORD)0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        /*  Now do extended addition */
							 | 
						||
| 
								 | 
							
								        ULARGE_INTEGER uliTotal;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Add ls DWORDs */
							 | 
						||
| 
								 | 
							
								        uliTotal.QuadPart  = (DWORDLONG)ud0.LowPart + p0.LowPart;
							 | 
						||
| 
								 | 
							
								        p0.LowPart       = uliTotal.LowPart;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Propagate carry */
							 | 
						||
| 
								 | 
							
								        uliTotal.LowPart   = uliTotal.HighPart;
							 | 
						||
| 
								 | 
							
								        uliTotal.HighPart  = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Add 2nd most ls DWORDs */
							 | 
						||
| 
								 | 
							
								        uliTotal.QuadPart += (DWORDLONG)ud0.HighPart + p0.HighPart;
							 | 
						||
| 
								 | 
							
								        p0.HighPart      = uliTotal.LowPart;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Add MS DWORDLONGs - no carry expected */
							 | 
						||
| 
								 | 
							
								        p1 += ud1 + uliTotal.HighPart;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*  Now see if we got a sign change from the addition */
							 | 
						||
| 
								 | 
							
								        if ((LONG)p1 < 0) {
							 | 
						||
| 
								 | 
							
								            bSign = !bSign;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            /*  Negate the current value (ugh!) */
							 | 
						||
| 
								 | 
							
								            p0.QuadPart  = ~p0.QuadPart;
							 | 
						||
| 
								 | 
							
								            p1 = ~p1;
							 | 
						||
| 
								 | 
							
								            p0.QuadPart += 1;
							 | 
						||
| 
								 | 
							
								            p1 += (p0.QuadPart == 0);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  Now for the division */
							 | 
						||
| 
								 | 
							
								    if (c < 0) {
							 | 
						||
| 
								 | 
							
								        bSign = !bSign;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  This will catch c == 0 and overflow */
							 | 
						||
| 
								 | 
							
								    if (uc <= p1) {
							 | 
						||
| 
								 | 
							
								        return bSign ? (LONGLONG)0x8000000000000000 :
							 | 
						||
| 
								 | 
							
								                       (LONGLONG)0x7FFFFFFFFFFFFFFF;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  Do the division */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*  If the divisor is a DWORD then its simpler */
							 | 
						||
| 
								 | 
							
								    ULARGE_INTEGER uliDividend;
							 | 
						||
| 
								 | 
							
								    ULARGE_INTEGER uliResult;
							 | 
						||
| 
								 | 
							
								    DWORD dwDivisor = uc;
							 | 
						||
| 
								 | 
							
								    uliDividend.HighPart = p1;
							 | 
						||
| 
								 | 
							
								    uliDividend.LowPart = p0.HighPart;
							 | 
						||
| 
								 | 
							
								    /*  NOTE - this routine will take exceptions if
							 | 
						||
| 
								 | 
							
								        the result does not fit in a DWORD
							 | 
						||
| 
								 | 
							
								    */
							 | 
						||
| 
								 | 
							
								    if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) {
							 | 
						||
| 
								 | 
							
								        uliResult.HighPart = EnlargedUnsignedDivide(
							 | 
						||
| 
								 | 
							
								                                 uliDividend,
							 | 
						||
| 
								 | 
							
								                                 dwDivisor,
							 | 
						||
| 
								 | 
							
								                                 &p0.HighPart);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        uliResult.HighPart = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    uliResult.LowPart = EnlargedUnsignedDivide(
							 | 
						||
| 
								 | 
							
								                             p0,
							 | 
						||
| 
								 | 
							
								                             dwDivisor,
							 | 
						||
| 
								 | 
							
								                             NULL);
							 | 
						||
| 
								 | 
							
								    return bSign ? -(LONGLONG)uliResult.QuadPart :
							 | 
						||
| 
								 | 
							
								                    (LONGLONG)uliResult.QuadPart;
							 | 
						||
| 
								 | 
							
								}
							 |