Annotation of researchv10no/cmd/cfront/libC/misc/Bits.c, revision 1.1

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

unix.superglobalmegacorp.com

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