Efficient Bit addressing in Python.

Mensanator mensanator at aol.com
Thu Oct 9 14:16:09 EDT 2008


On Oct 9, 5:30 pm, "Hendrik van Rooyen" <m... at microcorp.co.za> wrote:
> Is there a canonical way to address the bits in a structure
> like an array or string or struct?
>
> Or alternatively, is there a good way to combine eight
> ints that represent bits into one of the bytes in some
> array or string or whatever?
>
> It seems to me that there is a dilemma here :
>
> if you can write:
>
> bit3 = 1
>
> Then you have to jump through hoops to get
> bit0 through bit7 into some byte that you can send
> to an i/o routine.
>
> On the other hand, if you keep the bits "in" the
> byte, then you can write:
>
> byte[3] = '\x7e'
>
> but you have to jump through hoops to get at
> the individual bits.
>
> Is there a "best" way?
>
> It would be nice to be able to write:
>
> if io.byte2.bit3:
>    do_something()
>
> if io.byte2 == alarm_value:
>   do_something_else()
>
> where:
>
>  io.byte2 & 8   "is"  io.byte2.bit3
>
> Is this possible?
>
> - Hendrik

I use the gmpy module for all my bit related work and
have been very satisfied with the results.

Examples of functions pertinent to bit operations:

    digits(...)
        digits(x[,base]): returns Python string representing x in the
        given base (2 to 36, default 10 if omitted or 0); leading '-'
        present if x<0, but no leading '+' if x>=0. x must be an mpz,
        or else gets coerced into one.

    getbit(...)
        getbit(x,n): returns 0 or 1, the bit-value of bit n of x;
        n must be an ordinary Python int, >=0; x is an mpz, or else
        gets coerced to one.

    hamdist(...)
        hamdist(x,y): returns the Hamming distance (number of bit-
positions
        where the bits differ) between x and y.  x and y must be mpz,
or else
        get coerced to mpz.

    lowbits(...)
        lowbits(x,n): returns the n lowest bits of x; n must be an
        ordinary Python int, >0; x must be an mpz, or else gets
        coerced to one.

    numdigits(...)
        numdigits(x[,base]): returns length of string representing x
in
        the given base (2 to 36, default 10 if omitted or 0); the
value
        returned may sometimes be 1 more than necessary; no provision
        for any 'sign' characte, nor leading '0' or '0x' decoration,
        is made in the returned length.  x must be an mpz, or else
gets
        coerced into one.

    popcount(...)
        popcount(x): returns the number of 1-bits set in x; note that
        this is 'infinite' if x<0, and in that case, -1 is returned.
        x must be an mpz, or else gets coerced to one.

    scan0(...)
        scan0(x, n=0): returns the bit-index of the first 0-bit of x
(that
        is at least n); n must be an ordinary Python int, >=0.  If no
more
        0-bits are in x at or above bit-index n (which can only happen
for
        x<0, notionally extended with infinite 1-bits), None is
returned.
        x must be an mpz, or else gets coerced to one.

    scan1(...)
        scan1(x, n=0): returns the bit-index of the first 1-bit of x
(that
        is at least n); n must be an ordinary Python int, >=0.  If no
more
        1-bits are in x at or above bit-index n (which can only happen
for
        x>=0, notionally extended with infinite 0-bits), None is
returned.
        x must be an mpz, or else gets coerced to one.

    setbit(...)
        setbit(x,n,v=1): returns a copy of the value of x, with bit n
set
        to value v; n must be an ordinary Python int, >=0; v, 0 or !
=0;
        x must be an mpz, or else gets coerced to one.




More information about the Python-list mailing list