|
|
1.1 ! root 1: // Bits.c ! 2: ! 3: // The numbering scheme in this library is consistently ! 4: // ``little-end'' -- bit 0 is the low-order bit of the word ! 5: // stored in the lowest location of a class. ! 6: ! 7: #include "Bits.h" ! 8: ! 9: Blockimplement(Bits_chunk) ! 10: ! 11: Bits::Bits(register Bits_chunk val, register unsigned ct) ! 12: { ! 13: if (ct < Bits_len) { ! 14: register Bits_chunk mask = ~Bits_chunk(0) << ct; ! 15: while (val & mask) { ! 16: ct++; ! 17: mask <<= 1; ! 18: } ! 19: } ! 20: if (size(ct)) ! 21: *b = val; ! 22: } ! 23: ! 24: unsigned ! 25: Bits::size(unsigned x) ! 26: { ! 27: int newsize = bound(x); ! 28: if (b.size() != newsize) ! 29: b.size(newsize); ! 30: n = b.size()? x: 0; ! 31: ! 32: normalize(); ! 33: ! 34: return n; ! 35: } ! 36: ! 37: Bits& ! 38: Bits::operator&= (const Bits& x) ! 39: { ! 40: if (size() < x.size()) ! 41: size(x.size()); ! 42: ! 43: register Bits_chunk* p = b; ! 44: register const Bits_chunk* q = x.b; ! 45: register const Bits_chunk* lim = x.limit(); ! 46: ! 47: while (q < lim) ! 48: *p++ &= *q++; ! 49: ! 50: lim = limit(); ! 51: while (p < lim) ! 52: *p++ = 0; ! 53: ! 54: return *this; ! 55: } ! 56: ! 57: Bits& ! 58: Bits::operator|= (const Bits& x) ! 59: { ! 60: if (size() < x.size()) ! 61: size(x.size()); ! 62: ! 63: register Bits_chunk* p = b; ! 64: register const Bits_chunk* q = x.b; ! 65: register const Bits_chunk* lim = x.limit(); ! 66: ! 67: while (q < lim) ! 68: *p++ |= *q++; ! 69: ! 70: return *this; ! 71: } ! 72: ! 73: Bits& ! 74: Bits::operator^= (const Bits& x) ! 75: { ! 76: if (size() < x.size()) ! 77: size(x.size()); ! 78: ! 79: register Bits_chunk* p = b; ! 80: register const Bits_chunk* q = x.b; ! 81: register const Bits_chunk* lim = x.limit(); ! 82: ! 83: while (q < lim) ! 84: *p++ ^= *q++; ! 85: ! 86: return *this; ! 87: } ! 88: ! 89: Bits& ! 90: Bits::compl() ! 91: { ! 92: register Bits_chunk* p = b; ! 93: register const Bits_chunk* lim = limit(); ! 94: ! 95: while (p < lim) { ! 96: *p = ~*p; ! 97: p++; ! 98: } ! 99: ! 100: normalize(); ! 101: ! 102: return *this; ! 103: } ! 104: ! 105: unsigned ! 106: Bits::count() const ! 107: { ! 108: register const Bits_chunk* p = b; ! 109: register const Bits_chunk* lim = limit(); ! 110: register unsigned r = 0; ! 111: ! 112: while (p < lim) { ! 113: register unsigned long x = *p++; ! 114: register int i = Bits_len; ! 115: ! 116: while (--i >= 0) { ! 117: if (x & 1) ! 118: r++; ! 119: x >>= 1; ! 120: } ! 121: } ! 122: ! 123: return r; ! 124: } ! 125: ! 126: Bits::operator Bits_chunk() const ! 127: { ! 128: register const Bits_chunk* p = b; ! 129: register const Bits_chunk* lim = limit(); ! 130: ! 131: while (p < lim) { ! 132: if (*p++) ! 133: return p[-1]; ! 134: } ! 135: ! 136: return 0; ! 137: } ! 138: ! 139: Bits ! 140: operator& (const Bits& x, const Bits& y) ! 141: { ! 142: Bits r = x; ! 143: r &= y; ! 144: return r; ! 145: } ! 146: ! 147: Bits ! 148: operator| (const Bits& x, const Bits& y) ! 149: { ! 150: Bits r = x; ! 151: r |= y; ! 152: return r; ! 153: } ! 154: ! 155: Bits ! 156: operator^ (const Bits& x, const Bits& y) ! 157: { ! 158: Bits r = x; ! 159: r ^= y; ! 160: return r; ! 161: } ! 162: ! 163: Bits ! 164: operator~ (const Bits& x) ! 165: { ! 166: Bits r = x; ! 167: r.compl(); ! 168: return r; ! 169: } ! 170: ! 171: Bits ! 172: operator<< (const Bits& x, int n) ! 173: { ! 174: Bits r = x; ! 175: r <<= n; ! 176: return r; ! 177: } ! 178: ! 179: Bits ! 180: operator>> (const Bits& x, int n) ! 181: { ! 182: Bits r = x; ! 183: r >>= n; ! 184: return r; ! 185: } ! 186: ! 187: int ! 188: Bits::compare(const Bits& x) const ! 189: { ! 190: int w = bound(size()); ! 191: int xw = bound(x.size()); ! 192: int len, r; ! 193: register const Bits_chunk* p; ! 194: register const Bits_chunk* q; ! 195: register const Bits_chunk* lim; ! 196: ! 197: // two null strings are equal ! 198: if (w == 0 && xw == 0) ! 199: return 0; ! 200: ! 201: // a null string is the smallest string ! 202: if (w == 0) ! 203: return -1; ! 204: if (xw == 0) ! 205: return 1; ! 206: ! 207: // if the lengths differ, check the high-order ! 208: // part of the longer string; leave shorter length ! 209: // in len if we get out of this ! 210: if (w != xw) { ! 211: if (w > xw) { ! 212: len = xw; ! 213: p = &b[len]; ! 214: q = &b[w]; ! 215: r = 1; ! 216: } else { ! 217: len = w; ! 218: p = &x.b[len]; ! 219: q = &x.b[xw]; ! 220: r = -1; ! 221: } ! 222: ! 223: do { ! 224: if (*p++) ! 225: return r; ! 226: } while (p < q); ! 227: } else ! 228: len = w; ! 229: ! 230: // now compare low-order parts, going from high-order ! 231: // end to low-order end (the direction is important!) ! 232: p = b + len; ! 233: q = x.b + len; ! 234: lim = b; ! 235: while (p > lim) { ! 236: if (*--p != *--q) ! 237: return *p < *q? -1: 1; ! 238: } ! 239: ! 240: // the bits are equal -- length determines the result ! 241: return int(size()) - int(x.size()); ! 242: } ! 243: ! 244: // Are two bit strings identical? ! 245: int ! 246: Bits::equal(const Bits& x) const ! 247: { ! 248: // two strings of different sizes are not equal ! 249: if (size() != x.size()) ! 250: return 0; ! 251: ! 252: // two null strings are equal ! 253: if (size() == 0) ! 254: return 1; ! 255: ! 256: // else go the long route ! 257: return compare(x) == 0; ! 258: } ! 259: ! 260: ! 261: // The following routines can surely be made more efficient. ! 262: // I have not done so for two reasons: ! 263: // ! 264: // 1. The function call and memory allocation overhead ! 265: // will probably dominate for all but the largest of ! 266: // bit strings. ! 267: // ! 268: // 2. This code is tricky. Further optimization would ! 269: // erode my confidence in getting it right. ! 270: ! 271: Bits& ! 272: Bits::operator<<= (int k) ! 273: { ! 274: // Quick test for shift by 0 or negative ! 275: if (k <= 0) { ! 276: if (k < 0) ! 277: operator>>= (-k); ! 278: return *this; ! 279: } ! 280: ! 281: // Enlarge the structure to contain the result; return on error ! 282: if (size(size() + k) == 0) ! 283: return *this; ! 284: ! 285: register Bits_chunk* lim = b; ! 286: ! 287: // If needed, shift left by chunks ! 288: int chunkoffset = k >> Bits_shift; ! 289: if (chunkoffset) { ! 290: register Bits_chunk* dest = limit(); ! 291: register const Bits_chunk* src = dest - chunkoffset; ! 292: ! 293: do *--dest = *--src; ! 294: while (src > lim); ! 295: ! 296: do *--dest = 0; ! 297: while (dest > lim); ! 298: } ! 299: ! 300: // If needed, shift left by bits ! 301: register int bitoffset = k & Bits_mask; ! 302: if (bitoffset) { ! 303: register Bits_chunk* p = limit(); ! 304: register int compoffset = Bits_len - bitoffset; ! 305: ! 306: while (--p > lim) ! 307: *p = (*p << bitoffset) | (*(p-1) >> compoffset); ! 308: ! 309: // Shift low-order chunk ! 310: *lim <<= bitoffset; ! 311: } ! 312: ! 313: normalize(); ! 314: ! 315: return *this; ! 316: } ! 317: ! 318: Bits& ! 319: Bits::operator>>= (int k) ! 320: { ! 321: // Quick test for shift by 0 or negative ! 322: if (k <= 0) { ! 323: if (k < 0) ! 324: operator<<= (-k); ! 325: return *this; ! 326: } ! 327: ! 328: // Check for shifting all significance out ! 329: int newsize = size() - k; ! 330: if (newsize <= 0) { ! 331: size(0); ! 332: return *this; ! 333: } ! 334: ! 335: // If needed, shift right by chunks, leaving high-order ! 336: // garbage words that will be sized out later ! 337: int chunkoffset = k >> Bits_shift; ! 338: if (chunkoffset) { ! 339: register Bits_chunk* dest = b; ! 340: register Bits_chunk* src = dest + chunkoffset; ! 341: register const Bits_chunk* lim = limit(); ! 342: ! 343: do *dest++ = *src++; ! 344: while (src < lim); ! 345: } ! 346: ! 347: // If needed, shift right by bits ! 348: register int bitoffset = k & Bits_mask; ! 349: if (bitoffset) { ! 350: register Bits_chunk* p = b; ! 351: register Bits_chunk* lim = p + chunk(newsize-1); ! 352: register int compoffset = Bits_len - bitoffset; ! 353: ! 354: while (p < lim) { ! 355: *p = (*p >> bitoffset) | (*(p+1) << compoffset); ! 356: p++; ! 357: } ! 358: ! 359: // Shift high-order chunk right ! 360: *lim >>= bitoffset; ! 361: if (lim+1 < limit()) ! 362: *lim |= *(lim+1) << compoffset; ! 363: } ! 364: ! 365: // Finally, make the size right, discarding junk bits ! 366: size(newsize); ! 367: ! 368: return *this; ! 369: } ! 370: ! 371: // How many significant bits? ! 372: unsigned ! 373: Bits::signif() const ! 374: { ! 375: if (size() == 0) ! 376: return 0; ! 377: ! 378: register const Bits_chunk* p = limit(); ! 379: register const Bits_chunk* lim = b; ! 380: ! 381: while (--p >= lim) { ! 382: if (*p) { ! 383: register Bits_chunk x = *p; ! 384: register k = Bits_len; ! 385: ! 386: while (--k >= 0) { ! 387: if (x & (Bits_chunk(1) << k)) ! 388: return k + 1 + Bits_len * (p - lim); ! 389: } ! 390: } ! 391: } ! 392: ! 393: return 0; ! 394: } ! 395: ! 396: Bits& ! 397: Bits::concat(const Bits& x) ! 398: { ! 399: operator<<= (x.size()); ! 400: operator|= (x); ! 401: return *this; ! 402: } ! 403: ! 404: Bits ! 405: concat(const Bits& x, const Bits& y) ! 406: { ! 407: Bits r = x; ! 408: r.concat(y); ! 409: return r; ! 410: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.