/* ULong64 Class * * This class implements 64 bit integers for use with the GUID allocator. * The operators all allows both other ULong64's and longs for addition * and subtraction. Typecasting to long is allowed, however anything * greater in value than 0xFFFFFFFF is mapped to 0xFFFFFFFF. * * Revision History * * richardw, 17 July 1990, Initial Coding * richardw, 10 Aug 1990, Amended from code review * davidst, 5 Mar 1992, Added ToHexString and FromHexString, >>= */ #include #include #include "ulong64.hxx" #define DIGITS_IN_A_ULONG64 16 // // Puts the current value of 'this' out to a string in hex // char PAPI * ULong64::ToHexString( char PAPI *OutString ) { ULong64 Tmp = *this; int i; for (i=0 ; i>=1; } OutString[DIGITS_IN_A_ULONG64] = '\0'; return OutString; } // // Sets the value based on the hex string passed in. // void ULong64::FromHexString( char PAPI *String ) { char TmpChar; long val; *this=0; for ( ; *String ; String++) { (*this) <<= 4; // this *= 16 TmpChar = *String; if ( (TmpChar > 'a') && (TmpChar < 'z') ) { val = TmpChar - 'a'; } else if ( (TmpChar > 'A') && (TmpChar < 'Z') ) { val = TmpChar -'A'; } else { if ( (TmpChar < '0') || (TmpChar > '9') ) { val = 0; } else { val = TmpChar -'0'; } } *this += val; } } // // maximum unsigned long integer // #define MAX_ULONG 0xffffffff #ifndef TRUE #define TRUE 1==1 #define FALSE 1==0 #endif /* TRUE */ // // addition operators // void operator+=(ULong64 PAPI & a, ULong64 PAPI & b) { if (MAX_ULONG - a.low < b.low) { a.high++; // carry } a.high += b.high; a.low += b.low; } void operator+=(ULong64 PAPI & a, unsigned long b) { if (MAX_ULONG - a.low < b) { a.high++; // carry } a.low += b; } // // subtraction operator // void operator-=(ULong64 & a, ULong64 & b) { if (b.low > a.low) { a.high--; // "borrow" } a.high -= b.high; a.low -= b.low; } void operator-= (ULong64 & a, unsigned long b) { if (b > a.low) { a.high--; } a.low -= b; } //ULong64 ULong64 :: operator-(ULong64 & a) //{ // return ULong64(high - a.high, low - a.low); //} /* Here we are multiplying a 64 bit number by a 32 bit number. We do this by doing a base 65535 multiplication. In this, we can think of the ulong64 as having four digits and the 32 bit having two. In this case, we have: abcd x ef ---- (f*d) (f*c)0 (f*b)00 (f*a)000 (e*d)0 (e*c)00 (e*b)000 + (e*a)0000 <-- can throw this one out as overflow. ------- (Answer) */ #define ushort unsigned short #define ulong unsigned long void operator*= (ULong64 & x, unsigned long y) { //unsigned long t1,t2; // temporary storage ULong64 t3; unsigned short a,b,c,d,e,f; a = (ushort) (x.high >>16 ); b = (ushort) (x.high & 0xffff); c = (ushort) (x.low >> 16); d = (ushort) (x.low & 0xffff); e = (ushort) (y >> 16); f = (ushort) (y & 0xffff); x = (ulong)f * (ulong)d; t3.low = (ulong)f * (ulong)c; t3 <<= 16; x += t3; t3.low = (ulong)f * (ulong)b; t3 <<= 32; x += t3; t3.low = (ulong)f * (ulong)a; t3 <<= 48; x += t3; t3.low = (ulong)e * (ulong)d; t3 <<= 16; x += t3; t3.low = (ulong)e * (ulong)c; t3 <<= 32; x += t3; t3.low = (ulong)e * (ulong)b; t3 <<= 48; x += t3; } // // left shift operator (valid for n <= 63. for n >= 64, n is reduced // to n <= 63. // void operator<<=(ULong64 PAPI & a, unsigned int n) { if (n >= 64) { a = ULong64(0); } else { if (n > 31) { a.high = a.low << (n - 32); a.low = 0; } else { a.high <<= n; a.high |= a.low >> (32-n); a.low <<= n; } } } // // right shift operator (valid for n <= 63. for n >= 64, n is reduced // to n <= 63. // void operator>>=(ULong64 PAPI & a, unsigned int n) { if (n >= 64) { a = ULong64(0); } else { if (n > 31) { a.low = a.high >> (n - 32); a.high = 0; } else { a.low >>= n; a.low |= a.high >> (32-n); a.high >>= n; } } } // // a >= b comparision operator // int operator>=(ULong64 & a, ULong64 & b) { if (a.high > b.high) { return TRUE; } if (a.high < b.high) { return FALSE; } // a.high == b.high if (a.low >= b.low) { return TRUE; } return FALSE; } // // a <= b comparision operator // int operator<=(ULong64 & a, ULong64 & b) { if (a.high < b.high) { return TRUE; } if (a.high > b.high) { return FALSE; } // a.high == b.high if (a.low <= b.low) { return TRUE; } return FALSE; }