🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.compression.research
Article #46

Re: Algorithm for finding set bits in a bit-string (and MSB).

#46
From: Alan Wm Paeth
Date: Tue, 28 Jul 1992 19:37
53 lines
2744 bytes
Given a 'very sparse' integer having only one bit set in position 'p', this
C fragment detects 'very sparseness' and returns p. It is based on two entries
appearing in _Graphics Gems II_ (Academic Press, 1992, ed: Jim Arvo). These
describe integer operations combining bitwise-logic and arithmetic to perform
sparesness tests, bit tallying, etc. (The two entries are by Ken Shoemake and
Alan Paeth; I've forgotten their exact titles).

int sparsebit(i)
    long i;
    {
    int p;
    p = 0;
/* return position 'p' on range [0..31] of a "lone bit" integer (value 2^p) */
/* otherwise, return -1. This is "little-Endian form" as the lsb is at p=0. */
    if (i == 0) return(-1);		/* no bits set */
    if ((i & (-i)) != i) return(-1);	/* two or more bits set */
    if (i & 0xAAAAAAAA) p++;
    if (i & 0xCCCCCCCC) p += 2;
    if (i & 0xF0F0F0F0) p += 4;
    if (i & 0xFF00FF00) p += 8;
    if (i & 0xFFFF0000) p += 16;
    return(p);
    }


The msb of a sparse word having any number of bits set can be found by using:

int msbbit(i)
    long i;
    {
    long i2;
/* return the bit position of the msb as [0..31]; return -1 on arg of zero */
    while (i2 = (i & (-i)) i = i2;
    return(sparsebit(i));
    }

which removes the set bits (if any) having least weight until merely the msb
remains and then invokes the first subroutine. (This is described in the second
Gem). Note that the first algorithm has worse-case running time which grows
by log2(W) for world length W: 32-bit longs and especially 64-bit longs are big
wins. The bit-discard loop of the second procedure has run time proportional to
the number of 'on' bits in the input. Its worst-case running time occurs when
called with an input of -1 (W passes through the loop).

When non-sparse input is anticipated the stock shift-and-test or byte-table
methods give much better average-case performance. In these cases msbbit()
can be sped up significantly with simple heuristics. For instance, a prefacing

    if (i < 0) return(-1);

in msbbit() gives fast returns for 50% of its input, including the worst case.

   /Alan Paeth
Technical Details
Message-ID: <Bs46JC.35n@watcgl.uwaterloo.ca>
Path: arc1-ca.pugleaf.net!sparky!uunet!utcsri!skule.ecf!torn!watserv1!watmath!watcgl!watpix.waterloo.edu!awpaeth
References: <1992Jul26.010325.9885@infonode.ingr.com> <MOSS.92Jul25222337@ibis.cs.umass.edu> <Bs3yBx.7AA@watserv1.uwaterloo.ca>

Show Full Headers
Complete Article Headers
Newsgroups: comp.compression.research,comp.arch,comp.lang.c
Path: arc1-ca.pugleaf.net!sparky!uunet!utcsri!skule.ecf!torn!watserv1!watmath!watcgl!watpix.waterloo.edu!awpaeth
From: awpaeth@watpix.waterloo.edu (Alan Wm Paeth)
Subject: Re: Algorithm for finding set bits in a bit-string (and MSB).
Message-ID: <Bs46JC.35n@watcgl.uwaterloo.ca>
Sender: news@watcgl.uwaterloo.ca (USENET News System)
Organization: University of Waterloo
References: <1992Jul26.010325.9885@infonode.ingr.com> <MOSS.92Jul25222337@ibis.cs.umass.edu> <Bs3yBx.7AA@watserv1.uwaterloo.ca>
Date: Tue, 28 Jul 1992 19:37:58 GMT
Lines: 53