|
|
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.