Annotation of researchv10no/cmd/cfront/ptcfront/Bits.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.