Snippet: bitcount()

Tim Peters tim_one at email.msn.com
Sat Jul 17 14:30:28 EDT 1999


This has been beaten beyond death so often I don't have the heart to do it
all again <wink>.  Some factoids:

+ Christian's post summarizes best efforts pre-1.5.2.  For popcount4 it's
missing the nbits function.  Here's an elegant one that's reasonably fast:

def nbits(x):   # x >= 0 assumed
    if x <= 2:
        return x
    sum = 1
    while x:
        shift = 1
        x = x2 = x >> 1
        while x2:
            x = x2
            sum = sum + shift
            shift = shift + shift
            x2 = x >> shift
    return sum

Jurjen N.E. Bos's implementation of the constructive reals (Python FTP
contrib) contains a marshal-based method that's quicker for very large
longs.

+ nbits *should* be a constant-time operation, but there's no way to do that
in Python today.

+ hex(long) takes time linear in the number of bits in 1.5.2.  It used to be
quadratic-time.  This makes old tradeoffs open to question.  The notion that
it's too memory-intensive is misguided (longs are immutable -- you can't
even add 1 to a long without consuming 2*nbits(long) bits, and hex(long) is
no worse wrt memory than adding 1 twice <wink>).

+ "long1 & long2" (both > 0) takes time proportional to
       min(nbits(long1), nbits(long2))
in 1.5.2.  It used to take time proportional to the max of those.  This
makes shift-and-mask methods more attractive than they used to be.

+ The format of Python longs is defined in the source distribution's
    Include/longintrepr.h
  marshal-based tricks exploit that more-than-less directly.

+ About once a year someone gets excited about providing a pile of fast,
basic longint ops (via extension module or adding methods to longs -- like
popcount, trailing zero count, parity, nbits, long <-> int vector
conversions, set/clear/test/invert bit number i, find closest 0/1 bit
before/after bit number i).  Unfortunately, nobody has persisted long enough
to write a line of code, perhaps because people take such delight in endless
argument about what to name things <0.1 wink>.

the-next-person-to-get-excited-should-keep-it-a-secret-until-the-code-
    is-released-ly y'rs  - tim






More information about the Python-list mailing list