|
|
1.1 ! root 1: // ! 2: // C++ multiple precision integer arithmetic library. ! 3: // ! 4: ! 5: #ifndef BIGNUM_H ! 6: #define BIGNUM_H ! 7: #include <stream.h> ! 8: ! 9: typedef void (*OutFn)(char); ! 10: ! 11: class INT_REP { ! 12: ! 13: short refcnt; // Reference count. ! 14: long *wt; // First unused space. ! 15: long *beg; // Start of allocated memory. ! 16: long *last; // End of allocated memory. ! 17: ! 18: INT_REP (INT_REP *); // Duplicate INT_REP. ! 19: ! 20: void More (); // Realloc. ! 21: void Zero(); // Zero out everything. ! 22: void Print(iostream &); // Print using iostream. ! 23: void Print(OutFn, int); // Print using user supplied fn. ! 24: void Prt(); // Print internal representation. ! 25: void Chsign (); // Change sign. ! 26: void StripZero(); // Strip redundant zeros. ! 27: void StripMinus(); // Strip redundant -1's. ! 28: int Twos(); ! 29: ! 30: int Length() { return (wt-beg); } ! 31: int isNegative() { return ((wt > beg) && (*(wt-1) < 0)); } ! 32: int isZero () { return (wt == beg); } ! 33: int isNonzero () { return (wt != beg); } ! 34: int isOdd () { return (*beg & 0x1); } // Assuming positive. ! 35: int isEven () { return (!(*beg & 0x1)); } // Assuming positive. ! 36: void SetZero () { wt = beg; } ! 37: void Putc(long c) { if (wt==last) More(); *wt++ = c; } ! 38: void Alterc(int c, long *p) { if (p == last) More(); *p++ = c; if (p > wt) wt = p; } ! 39: ! 40: void FillDec(char *, char *); ! 41: void FillHex(char *, char *); ! 42: void FillOct(char *, char *); ! 43: void FillLong(unsigned long); ! 44: ! 45: INT_REP *PutDec(); ! 46: INT_REP *PutHex(); ! 47: INT_REP *PutOct(); ! 48: ! 49: int Store(char *, int, int); ! 50: ! 51: int Comp(INT_REP *); ! 52: long Trunc(int &); ! 53: INT_REP *Add(INT_REP *); ! 54: INT_REP *Sub(INT_REP *); ! 55: INT_REP *Mult(INT_REP *); ! 56: INT_REP *DivMod(INT_REP *, int); ! 57: INT_REP *Div(INT_REP *b) { return DivMod(b,0); } ! 58: INT_REP *Mod(INT_REP *b) { return DivMod(b,1); } ! 59: INT_REP *Exp(INT_REP *b); ! 60: INT_REP *GCD(INT_REP *b); ! 61: ! 62: INT_REP *And(INT_REP *); ! 63: INT_REP *Or(INT_REP *); ! 64: INT_REP *Xor(INT_REP *); ! 65: INT_REP *Not(); ! 66: INT_REP *LeftShift(long); ! 67: INT_REP *RightShift(long); ! 68: INT_REP *LeftShift(INT_REP *); ! 69: INT_REP *RightShift(INT_REP *); ! 70: ! 71: public : ! 72: ! 73: static void IRMorehd (); ! 74: ! 75: INT_REP (int, int = 1); // Create INT_REP of specified size. ! 76: INT_REP (long); // Create INT_REP of long. ! 77: INT_REP (char *); // Create INT_REP from ascii representation. ! 78: ~INT_REP (); ! 79: ! 80: friend class INT; ! 81: friend INT_REP *IRAllocRep (); ! 82: friend INT operator >> (INT b, long a); ! 83: friend INT operator << (INT b, long a); ! 84: }; ! 85: ! 86: extern INT_REP ZeroRep; ! 87: ! 88: class INT { ! 89: INT_REP *rep; ! 90: ! 91: INT Reset (INT_REP *newrep) ! 92: { ! 93: rep->refcnt--; ! 94: if (rep->refcnt == 0) ! 95: delete rep; ! 96: rep = newrep; ! 97: rep->refcnt++; ! 98: return (*this); ! 99: } ! 100: ! 101: void Print(iostream &i) // Print decimal representation on iostream. ! 102: { rep->Print(i); } ! 103: ! 104: public : ! 105: ! 106: INT(long i) // Initialized to i. ! 107: { rep = new INT_REP (i); if (rep) rep->refcnt++; } ! 108: INT () // Initialized to zero. ! 109: { rep = &ZeroRep; rep->refcnt++; } ! 110: INT (INT_REP *r) // For return values from INT_REP operations. ! 111: { rep = r; if(r) r->refcnt++; } ! 112: INT (INT &a) // For assignment. ! 113: { rep = a.rep; if(rep) rep->refcnt++; } ! 114: INT (char *s) // Character representation, in decimal, octal or hex. ! 115: { rep = new INT_REP (s); if(rep) rep->refcnt++; } ! 116: ~INT () ! 117: { rep->refcnt--; if(rep->refcnt == 0) delete rep; } ! 118: ! 119: // Assignment operators. ! 120: INT operator= (INT &a) { return (Reset (a.rep)); } ! 121: INT operator+= (INT &a) { return (Reset (rep->Add(a.rep))); } ! 122: INT operator-= (INT &a) { return (Reset (rep->Sub(a.rep))); } ! 123: INT operator*= (INT &a) { return (Reset (rep->Mult(a.rep))); } ! 124: INT operator/= (INT &a) { return (Reset (rep->Div(a.rep))); } ! 125: INT operator%= (INT &a) { return (Reset (rep->Mod(a.rep))); } ! 126: INT operator|= (INT &a) { return (Reset (rep->Or(a.rep))); } ! 127: INT operator&= (INT &a) { return (Reset (rep->And(a.rep))); } ! 128: INT operator^= (INT &a) { return (Reset (rep->Xor(a.rep))); } ! 129: INT operator<<= (INT &a) { return (Reset (rep->LeftShift(a.rep))); } ! 130: INT operator>>= (INT &a) { return (Reset (rep->RightShift(a.rep))); } ! 131: ! 132: // Increment/decrement. ! 133: INT operator++ () { INT_REP orep(1l); return (Reset (rep->Add(&orep))); } ! 134: INT operator-- () { INT_REP orep(-1l); return (Reset (rep->Add(&orep))); } ! 135: ! 136: // Binary arithmetic operators. ! 137: INT operator + (INT b) { return INT(rep->Add(b.rep)); } ! 138: INT operator - (INT b) { return INT(rep->Sub(b.rep)); } ! 139: INT operator * (INT b) { return INT(rep->Mult(b.rep)); } ! 140: INT operator / (INT b) { return INT(rep->Div(b.rep)); } ! 141: INT operator % (INT b) { return INT(rep->Mod(b.rep)); } ! 142: ! 143: // Logical operators. ! 144: int operator <= (INT b) { return (rep->Comp(b.rep) == 1 ? 0 : 1); } ! 145: int operator >= (INT b) { return (rep->Comp(b.rep) == -1 ? 0 : 1); } ! 146: int operator < (INT b) { return (rep->Comp(b.rep) == -1 ? 1 : 0); } ! 147: int operator > (INT b) { return (rep->Comp(b.rep) == 1 ? 1 : 0); } ! 148: int operator == (INT b) { return (rep->Comp(b.rep) == 0 ? 1 : 0); } ! 149: int operator != (INT b) { return (rep->Comp(b.rep) == 0 ? 0 : 1); } ! 150: int operator ! () { return (rep->isZero() ? 1 : 0); } ! 151: int operator || (INT b) ! 152: { return (rep->isNonzero()>0 ? 1 : (b.rep->isNonzero()>0 ? 1 : 0)); } ! 153: int operator && (INT b) ! 154: { return (rep->isZero() ? 0 : (b.rep->isZero() ? 0 : 1)); } ! 155: ! 156: // Bitwise operators. ! 157: INT operator >> (INT b) { return INT(rep->RightShift(b.rep)); } ! 158: INT operator << (INT b) { return INT(rep->LeftShift(b.rep)); } ! 159: INT operator | (INT b) { return INT(rep->Or(b.rep)); } ! 160: INT operator & (INT b) { return INT(rep->And(b.rep)); } ! 161: INT operator ^ (INT b) { return INT(rep->Xor(b.rep)); } ! 162: INT operator ~ () { return INT(rep->Not()); } ! 163: ! 164: // Miscellaneous. ! 165: INT operator - () // Unary minus. ! 166: { INT_REP *b = new INT_REP(rep); b->Chsign(); return INT(b); } ! 167: INT Exp (INT b) // Exponentiate this to the given power. ! 168: { return INT(rep->Exp(b.rep)); } ! 169: INT GCD (INT b) // GCD of this and parameter. ! 170: { return INT(rep->GCD(b.rep)); } ! 171: long Long(int &error) // Convert this to signed long; ! 172: { return (rep->Trunc(error)); } // if bits are lost, error will be nonzero. ! 173: operator void * () ! 174: { return (rep->isZero() ? (void *)0 : (void *)rep); } ! 175: ! 176: // Output. ! 177: int Dec (char *buf, int buflen = -1) { return (rep->Store (buf, buflen, 0)); } ! 178: int Oct (char *buf, int buflen = -1) { return (rep->Store (buf, buflen, 1)); } ! 179: int Hex (char *buf, int buflen = -1) { return (rep->Store (buf, buflen, 2)); } ! 180: void Dec (OutFn fn) { rep->Print (fn, 0); } ! 181: void Oct (OutFn fn) { rep->Print (fn, 1); } ! 182: void Hex (OutFn fn) { rep->Print (fn, 2); } ! 183: friend iostream & operator << (iostream &i, INT n) ! 184: { n.Print(i); return(i); } ! 185: #ifdef DEBUG ! 186: void Prt() // Print internal representation. ! 187: { rep->Prt(); } ! 188: #endif DEBUG ! 189: ! 190: // Friends. ! 191: friend INT operator >> (INT b, long a); ! 192: friend INT operator << (INT b, long a); ! 193: ! 194: }; ! 195: ! 196: ! 197: /* Mixed long and INT functions. */ ! 198: ! 199: // Binary arithmetic operators. ! 200: inline INT operator + (long a, INT b) { return (INT(a) + b); } ! 201: inline INT operator + (INT b, long a) { return (INT(a) + b); } ! 202: inline INT operator - (long a, INT b) { return (INT(a) - b); } ! 203: inline INT operator - (INT b, long a) { return (INT(a) - b); } ! 204: inline INT operator * (long a, INT b) { return (INT(a) * b); } ! 205: inline INT operator * (INT b, long a) { return (INT(a) * b); } ! 206: inline INT operator / (long a, INT b) { return (INT(a) / b); } ! 207: inline INT operator / (INT b, long a) { return (INT(a) / b); } ! 208: inline INT operator % (long a, INT b) { return (INT(a) % b); } ! 209: inline INT operator % (INT b, long a) { return (INT(a) % b); } ! 210: ! 211: // Logical operators. ! 212: inline int operator <= (long a, INT b) { return (INT(a) <= b); } ! 213: inline int operator <= (INT b, long a) { return (INT(a) <= b); } ! 214: inline int operator >= (long a, INT b) { return (INT(a) >= b); } ! 215: inline int operator >= (INT b, long a) { return (INT(a) >= b); } ! 216: inline int operator < (long a, INT b) { return (INT(a) < b); } ! 217: inline int operator < (INT b, long a) { return (INT(a) < b); } ! 218: inline int operator > (long a, INT b) { return (INT(a) > b); } ! 219: inline int operator > (INT b, long a) { return (INT(a) > b); } ! 220: inline int operator == (long a, INT b) { return (INT(a) == b); } ! 221: inline int operator == (INT b, long a) { return (INT(a) == b); } ! 222: inline int operator != (long a, INT b) { return (INT(a) != b); } ! 223: inline int operator != (INT b, long a) { return (INT(a) != b); } ! 224: inline int operator || (long a, INT b) { return (a ? 1 : (b ? 1 : 0)); } ! 225: inline int operator || (INT b, long a) { return (b ? 1 : (a ? 1 : 0)); } ! 226: inline int operator && (long a, INT b) { return (a==0 ? 0 : (b ? 1 : 0)); } ! 227: inline int operator && (INT b, long a) { return (!b ? 0 : (a==0 ? 0 : 1)); } ! 228: ! 229: // Bitwise operators. ! 230: inline INT operator >> (long a, INT b) { return (INT(a)>>b); } ! 231: inline INT operator >> (INT b, long a) { return INT(b.rep->RightShift(a)); } ! 232: inline INT operator << (long a, INT b) { return (INT(a)<<b); } ! 233: inline INT operator << (INT b, long a) { return INT(b.rep->LeftShift(a)); } ! 234: inline INT operator | (long a, INT b) { return (INT(a) | b); } ! 235: inline INT operator | (INT b, long a) { return (INT(a) | b); } ! 236: inline INT operator & (long a, INT b) { return (INT(a) & b); } ! 237: inline INT operator & (INT b, long a) { return (INT(a) & b); } ! 238: inline INT operator ^ (long a, INT b) { return (INT(a) ^ b); } ! 239: inline INT operator ^ (INT b, long a) { return (INT(a) ^ b); } ! 240: ! 241: // Miscellaneous functions. ! 242: overload Exp; ! 243: overload GCD; ! 244: inline INT Exp (long a, INT b) { return (INT(a).Exp(b)); } ! 245: inline INT Exp (INT b, long a) { return (b.Exp(INT(a))); } ! 246: inline INT GCD (long a, INT b) { return (b.GCD(INT(a))); } ! 247: inline INT GCD (INT b, long a) { return (b.GCD(INT(a))); } ! 248: ! 249: #endif BIGNUM_H
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.