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