faqts : Computers : Programming : Languages : Python : Snippets

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

3 of 5 people (60%) answered Yes
Recently 0 of 2 people (0%) answered Yes

Entry

bitcount

Jul 5th, 2000 10:00
Nathan Wallace, Hans Nowak, Snippet 151, Christian Tismer


"""
Packages: maths.bit_twiddling
"""
"""
> > A curious thing in Python is that you can't march over the bits of a long in
> > linear time without resorting to hex() or marshal.dumps.  This really
> > complicates lookup methods, which *can* work in O(B) time straightforwardly
> > in C.
> 
> I remember being quite aggravated by this some time back, when I was
> trying to implement a reasonably fast sqrt routine for Python longs
> that worked even when they were too big to be converted into a float.
> 
> I was using the time honoured method
> 
> x -> (x+a/x)/2
> 
> which works pretty well, but to find an initial guess I thought I'd
> bitshift the number by half it's (bit) length. Finding the length
> seemed to be impossible, without doing something like
> (len(hex(a))-1)/4, which strikes me as silly, not to mention very
> memory wasteful.
> 
> Mini-proposal: len(a) for a long returns the length of the number in
> radix-256.
bitcount2 is not very slow, see here:
"""
def bitlen1(x):
    """number of bytes necessary to store a number"""
    sign = x<0
    x = abs(long(x))
    h = hex(x)
    l = (len(h)-3)*4
    if sign and h[2] >= "8":
        l = l+1
    return (l+7)/8
import marshal
def bitlen2(x):
    """number of bytes necessary to store a number"""
    sign = x<0
    x = long(x)
    b=marshal.dumps(x)
    l = (len(b)-5)*15 / 2
    hi = ord(b[-1])*256 + ord(b[-2])
    l = l + sign -15
    while hi:
        l = l + 1
        hi = hi >> 1
    return max(1, (l+7)/8)