|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: equad.hxx ! 3: * ! 4: * A class version of LARGE_INTEGER's ! 5: * ! 6: * Created: 26-Apr-1991 12:48:13 ! 7: * Author: Kirk Olynyk [kirko] ! 8: * ! 9: * Copyright (c) 1991 Microsoft Corporation ! 10: * ! 11: \**************************************************************************/ ! 12: ! 13: // #define DEBUG_QUAD 1 ! 14: ! 15: /**************************************************************************\ ! 16: * !!!Hack Alert * ! 17: * * ! 18: * The following declarations are stolen directly from <ntrtl.h> * ! 19: * I find that I cannot include engine.hxx and <ntrtl.h> in the * ! 20: * same file without causing problems. So I have come up with the * ! 21: * following hack solution. The correct thing to do would be to * ! 22: * fix the include file clash. A better, but incorrect solution, * ! 23: * would be to do a sed script on <ntrtl.h> and bring in the stuff * ! 24: * that we need. * ! 25: * * ! 26: * Thu 30-May-1991 08:59:22 by Kirk Olynyk [kirko] * ! 27: \**************************************************************************/ ! 28: ! 29: ! 30: ! 31: #ifndef DOS_PLATFORM ! 32: extern "C" { ! 33: #endif //DOS_PLATFORM ! 34: ! 35: LARGE_INTEGER ! 36: RtlEnlargedIntegerMultiply ( ! 37: LONG Multiplicand, ! 38: LONG Multiplier ! 39: ); ! 40: ! 41: ULONG ! 42: RtlEnlargedUnsignedDivide ( ! 43: ULARGE_INTEGER Dividend, ! 44: ULONG Divisor, ! 45: PULONG Remainder ! 46: ); ! 47: ! 48: LARGE_INTEGER ! 49: RtlExtendedLargeIntegerDivide ( ! 50: LARGE_INTEGER Dividend, ! 51: ULONG Divisor, ! 52: PULONG Remainder ! 53: ); ! 54: ! 55: LARGE_INTEGER ! 56: RtlExtendedIntegerMultiply ( ! 57: LARGE_INTEGER Multiplicand, ! 58: LONG Multiplier ! 59: ); ! 60: #ifndef DOS_PLATFORM ! 61: }; ! 62: #endif //DOS_PLATFORM ! 63: ! 64: /*********************************Class************************************\ ! 65: * class EUQUAD ! 66: * ! 67: * Public Interface: ! 68: * ! 69: * History: ! 70: * Wed 05-Jun-1991 10:26:09 by Kirk Olynyk [kirko] ! 71: * Wrote it. ! 72: \**************************************************************************/ ! 73: ! 74: class EUQUAD ! 75: { ! 76: public: ! 77: ! 78: ULONG LowPart; ! 79: LONG HighPart; ! 80: ! 81: EUQUAD() {} ! 82: ! 83: EUQUAD(ULONG ul) ! 84: { ! 85: LowPart = ul; ! 86: HighPart = 0; ! 87: } ! 88: ! 89: BOOL bNegative(VOID) ! 90: { ! 91: return((LONG) HighPart < 0); ! 92: } ! 93: ! 94: BOOL bZero(VOID) ! 95: { ! 96: return(!(HighPart | LowPart)); ! 97: } ! 98: ! 99: BOOL bPositive(VOID) ! 100: { ! 101: return(!bNegative() && !bZero()); ! 102: } ! 103: ! 104: VOID vMulInit(ULONG ul1,ULONG ul2); ! 105: ! 106: // EUQUAD(ULONG,ULONG) -- initial value is the product of two ULONG's ! 107: ! 108: EUQUAD(ULONG ul1,ULONG ul2) ! 109: { ! 110: vMulInit(ul1,ul2); ! 111: } ! 112: ! 113: VOID operator=(ULONG ul) ! 114: { ! 115: LowPart = ul; ! 116: HighPart = 0; ! 117: } ! 118: ! 119: VOID operator=(EUQUAD& euq) ! 120: { ! 121: LowPart = euq.LowPart; ! 122: HighPart = euq.HighPart; ! 123: } ! 124: ! 125: operator ULONG() ! 126: { ! 127: return(LowPart); ! 128: } ! 129: ! 130: VOID operator+=(EUQUAD& euq) ! 131: { ! 132: LowPart += euq.LowPart; ! 133: HighPart += euq.HighPart + (LowPart < euq.LowPart); ! 134: } ! 135: ! 136: VOID operator-=(EUQUAD& euq) ! 137: { ! 138: register ULONG ulTemp = LowPart; ! 139: ! 140: LowPart -= euq.LowPart; ! 141: HighPart -= euq.HighPart + (LowPart > ulTemp); ! 142: } ! 143: ! 144: VOID operator+=(ULONG ul) ! 145: { ! 146: LowPart += ul; ! 147: HighPart += (LowPart < ul); ! 148: } ! 149: ! 150: VOID operator-=(ULONG ul) ! 151: { ! 152: register ULONG ulT = LowPart; ! 153: ! 154: LowPart -= ul; ! 155: HighPart -= (LowPart > ulT); ! 156: } ! 157: ! 158: VOID operator--(VOID) ! 159: { ! 160: register ULONG ulTemp = LowPart; ! 161: ! 162: LowPart--; ! 163: HighPart -= (LowPart > ulTemp); ! 164: } ! 165: ! 166: VOID vShiftLeft(INT i) ! 167: { ! 168: if (i > 63) ! 169: { ! 170: *this = 0; ! 171: } ! 172: else ! 173: { ! 174: if (i >= 32) ! 175: { ! 176: HighPart = (LONG) (LowPart << (i - 32)); ! 177: LowPart = 0; ! 178: } ! 179: else ! 180: { ! 181: HighPart <<= i; ! 182: HighPart |= (LONG) (LowPart >> (32 - i)); ! 183: LowPart <<= i; ! 184: } ! 185: } ! 186: } ! 187: ! 188: VOID operator<<=(INT i) ! 189: { ! 190: vShiftLeft(i); ! 191: } ! 192: ! 193: // vShiftRight -- unsigned shift right ! 194: ! 195: VOID vShiftRight(INT i) ! 196: { ! 197: if (i >= 64) ! 198: { ! 199: *this = 0; ! 200: } ! 201: else ! 202: { ! 203: i &= 63; ! 204: if (i >= 32) ! 205: { ! 206: LowPart = ((ULONG) HighPart) >> (i - 32); ! 207: HighPart = 0; ! 208: } ! 209: else ! 210: { ! 211: LowPart >>= i; ! 212: LowPart += ((ULONG) HighPart) << (32 - i); ! 213: *(ULONG*) &HighPart >>= i; ! 214: } ! 215: } ! 216: } ! 217: ! 218: VOID operator>>=(INT i) ! 219: { ! 220: vShiftRight(i); ! 221: } ! 222: ! 223: VOID vNeg(VOID) ! 224: { ! 225: LowPart = -(LONG) LowPart; ! 226: HighPart = -HighPart - (LowPart > 0); ! 227: } ! 228: ! 229: EUQUAD operator+(ULONG ul) ! 230: { ! 231: EUQUAD euqT = *this; ! 232: euqT += ul; ! 233: return(euqT); ! 234: } ! 235: ! 236: EUQUAD operator-(ULONG ul) ! 237: { ! 238: EUQUAD euqT = *this; ! 239: euqT.LowPart -= ul; ! 240: euqT.HighPart -= (euqT.LowPart > ul); ! 241: return(euqT); ! 242: } ! 243: ! 244: INT operator==(EUQUAD& euq) ! 245: { ! 246: return(HighPart == euq.HighPart && LowPart == euq.LowPart); ! 247: } ! 248: ! 249: INT operator!=(EUQUAD& euq) ! 250: { ! 251: return(!(*this == euq)); ! 252: } ! 253: ! 254: BOOL operator<(EUQUAD& euq) ! 255: { ! 256: return( ! 257: HighPart == euq.HighPart ? ! 258: (LowPart < euq.LowPart ) : ! 259: ((ULONG) HighPart < (ULONG) euq.HighPart) ! 260: ); ! 261: } ! 262: ! 263: BOOL operator>(EUQUAD& euq) ! 264: { ! 265: return( ! 266: HighPart == euq.HighPart ? ! 267: (LowPart > euq.LowPart ) : ! 268: ((ULONG) HighPart > (ULONG) euq.HighPart) ! 269: ); ! 270: } ! 271: ! 272: VOID operator*=(ULONG ul) ! 273: { ! 274: *(LARGE_INTEGER*) this = RtlExtendedIntegerMultiply(*(LARGE_INTEGER *)this, ! 275: (LONG) ul); ! 276: ! 277: EUQUAD euqTemp((ULONG) HighPart,ul); ! 278: euqTemp.HighPart = (LONG) euqTemp.LowPart; ! 279: euqTemp.HighPart = 0; ! 280: vMulInit(LowPart,ul); ! 281: *this += euqTemp; ! 282: } ! 283: ! 284: ULONG ulLow() ! 285: { ! 286: return(LowPart); ! 287: } ! 288: ! 289: ULONG ulHigh() ! 290: { ! 291: return((ULONG) HighPart); ! 292: } ! 293: ! 294: LONG lHigh(VOID) ! 295: { ! 296: return(HighPart); ! 297: } ! 298: ! 299: // ulLow, lHigh -- sets the new value while returning the old value ! 300: ! 301: ULONG ulLow(ULONG ul) ! 302: { ! 303: ULONG ulTemp = LowPart; ! 304: LowPart = ul; ! 305: return(ulTemp); ! 306: } ! 307: ! 308: LONG lHigh(LONG l) ! 309: { ! 310: LONG lTemp = HighPart; ! 311: HighPart = l; ! 312: return(lTemp); ! 313: } ! 314: ! 315: // ULONG ulDiv(ulDivisor, pulRemainder) ! 316: // ! 317: // This function takes an unsigned 64 bit value, divides it by a 32 bit ! 318: // value, to return a 32 bit quotient and remainder (you're on your own ! 319: // if the result doesn't fit in 32 bits). ! 320: ! 321: ULONG ulDiv(ULONG ulDivisor, ULONG* pulRemainder) ! 322: { ! 323: ! 324: return RtlEnlargedUnsignedDivide(*(ULARGE_INTEGER *)this, ! 325: ulDivisor, ! 326: pulRemainder); ! 327: } ! 328: ! 329: ! 330: // ULONG ulDiv(ulDivisor) ! 331: // ! 332: // This function takes an unsigned 64 bit value, divides it by a 32 bit ! 333: // value, to return a 32 bit quotient (you're on your own if the result ! 334: // doesn't fit in 32 bits). ! 335: ! 336: ULONG ulDiv(ULONG ulDivisor) ! 337: { ! 338: ! 339: // If the high dword of the numerator is zero, we can do the ! 340: // divide inline: ! 341: ! 342: if (HighPart == 0) ! 343: { ! 344: return (LowPart / ulDivisor); ! 345: } ! 346: else ! 347: { ! 348: return RtlEnlargedUnsignedDivide(*(ULARGE_INTEGER *)this, ! 349: ulDivisor, ! 350: (ULONG*) NULL); ! 351: } ! 352: } ! 353: ! 354: VOID vDiv(ULONG ulDivisor, ULONG* pulRemainder) ! 355: { ! 356: *(LARGE_INTEGER*) this = RtlExtendedLargeIntegerDivide(*(LARGE_INTEGER *)this, ! 357: ulDivisor, ! 358: pulRemainder); ! 359: } ! 360: ! 361: #ifdef DEBUG_QUAD ! 362: VOID vPrint(CHAR *psz) ! 363: { ! 364: DbgPrint("%s = %8lx:%8lx\n",psz,HighPart,LowPart); ! 365: } ! 366: #endif ! 367: ! 368: }; ! 369: ! 370: /*********************************Class************************************\ ! 371: * class EQUAD : public EUQUAD * ! 372: * * ! 373: * Signed 64-bit integer * ! 374: * * ! 375: * History: * ! 376: * Sat 27-Apr-1991 07:33:11 by Kirk Olynyk [kirko] * ! 377: * Wrote it. * ! 378: \**************************************************************************/ ! 379: ! 380: class EQUAD : public EUQUAD ! 381: { ! 382: public: ! 383: ! 384: EQUAD() : EUQUAD() {} ! 385: ! 386: EQUAD(LONG l) : EUQUAD() ! 387: { ! 388: this->LowPart = (ULONG) l; ! 389: this->HighPart = -(l < 0); ! 390: } ! 391: ! 392: EQUAD(LONG l1,LONG l2) : EUQUAD() ! 393: { ! 394: *(LARGE_INTEGER*) this = RtlEnlargedIntegerMultiply(l1,l2); ! 395: } ! 396: ! 397: VOID vImulInit(LONG l1,LONG l2) ! 398: { ! 399: *(LARGE_INTEGER*) this = RtlEnlargedIntegerMultiply(l1,l2); ! 400: } ! 401: ! 402: VOID operator+=(EQUAD& euq) ! 403: { ! 404: LowPart += euq.LowPart; ! 405: HighPart += euq.HighPart + (LowPart < euq.LowPart); ! 406: } ! 407: ! 408: VOID operator-=(EQUAD& euq) ! 409: { ! 410: register ULONG ulTemp = LowPart; ! 411: ! 412: LowPart -= euq.LowPart; ! 413: HighPart -= euq.HighPart + (LowPart > ulTemp); ! 414: } ! 415: ! 416: VOID vShiftRightOneNibble(VOID) ! 417: { ! 418: LowPart >>= 4; ! 419: LowPart |= (ULONG) (HighPart << 28); ! 420: HighPart >>= 4; ! 421: } ! 422: ! 423: operator LONG() ! 424: { ! 425: return((LONG) LowPart); ! 426: } ! 427: ! 428: VOID operator=(LONG l) ! 429: { ! 430: LowPart = (ULONG) l; ! 431: HighPart = -(l < 0); ! 432: } ! 433: ! 434: // !!! Fix for compiler bug: [andrewgo] ! 435: ! 436: VOID operator=(EQUAD& eq) ! 437: { ! 438: LowPart = eq.LowPart; ! 439: HighPart = eq.HighPart; ! 440: } ! 441: ! 442: // vArithShiftRight -- arithmetic shift right ! 443: ! 444: VOID vArithShiftRight(INT iShift) ! 445: { ! 446: if (iShift > 63) ! 447: { ! 448: HighPart = - (LONG) (HighPart < 0); ! 449: LowPart = (ULONG) HighPart; ! 450: } ! 451: else ! 452: { ! 453: iShift &= 63; ! 454: if (iShift > 31) ! 455: { ! 456: LowPart = (ULONG) (HighPart >> (iShift - 32)); ! 457: HighPart = - (HighPart < 0); ! 458: } ! 459: else ! 460: { ! 461: LowPart >>= iShift; ! 462: LowPart += (ULONG) (HighPart << (32 - iShift)); ! 463: HighPart >>= iShift; ! 464: } ! 465: } ! 466: } ! 467: ! 468: // operator>>= -- signed shift right ! 469: ! 470: VOID operator>>=(INT iShift) ! 471: { ! 472: vArithShiftRight(iShift); ! 473: } ! 474: ! 475: BOOL operator<(EQUAD& eq) ! 476: { ! 477: return( ! 478: HighPart == eq.HighPart ? ! 479: (LowPart < eq.LowPart ) : ! 480: ((LONG) HighPart < (LONG) eq.HighPart) ! 481: ); ! 482: } ! 483: ! 484: BOOL operator>(EQUAD& eq) ! 485: { ! 486: return( ! 487: HighPart == eq.HighPart ? ! 488: (LowPart > eq.LowPart ) : ! 489: ((LONG) HighPart > (LONG) eq.HighPart) ! 490: ); ! 491: } ! 492: ! 493: BOOL operator<=(EQUAD& eq) ! 494: { ! 495: return(!(*this > eq)); ! 496: } ! 497: ! 498: BOOL operator>=(EQUAD& eq) ! 499: { ! 500: return(!(*this < eq)); ! 501: } ! 502: ! 503: VOID operator-=(LONG l) ! 504: { ! 505: EQUAD eqT(l); ! 506: *this -= eqT; ! 507: } ! 508: ! 509: VOID operator+=(LONG l) ! 510: { ! 511: EQUAD eqT(l); ! 512: *this += eqT; ! 513: } ! 514: ! 515: // !!! Hack for signed divide. [wendywu] ! 516: // The quotient is adjusted so that the remainder is always > 0. ! 517: ! 518: VOID operator/=(LONG l) ! 519: { ! 520: ULONG ulRem; ! 521: BOOL bNegNum = bNegative(); ! 522: BOOL bNegDen = (l < 0); ! 523: ! 524: if (bNegNum) ! 525: vNeg(); ! 526: ! 527: if (bNegDen) ! 528: l = -l; ! 529: ! 530: *(LARGE_INTEGER *)this = ! 531: RtlExtendedLargeIntegerDivide(*(LARGE_INTEGER *)this, l, &ulRem); ! 532: ! 533: if ((bNegNum ^ bNegDen) != 0) ! 534: { ! 535: vNeg(); ! 536: if (bNegNum) ! 537: *this -= 1; ! 538: } ! 539: } ! 540: }; ! 541:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.