How to test whether bit is set within a flag with Python ?

Mensanator mensanator at aol.com
Wed May 12 18:56:45 EDT 2010


On May 12, 1:40 pm, MRAB <pyt... at mrabarnett.plus.com> wrote:
> robert somerville wrote:
> > I am trying to determine how to test whether variors bits are set within
> > a byte (or larger flag) , the python 'and' and 'or' do not seem to be
> > doing what i want .. does anybody have some sample code showing how to
> > do it ??
>
> > e.g. (in "C")
>
> > unsigned char a = 6;
>
> > is 3rd bit set ??
>
> > a & 4 =,  true in this case ....
>
> 'and', 'or' and 'not' are Boolean.
>
> Python borrows its bitwise operators from C:
>
>      &     bitwise and
>      |     bitwise or
>      ^     bitwise xor
>      ~     bitwise not (ones' complement)
>      <<    shift left
>      >>    shift right
>
> You also need to remember that Python's integers are of (virtually)
> unlimited length.

The gmpy module has a wonderful set of functions tailored to the
bit twiddler:

FUNCTIONS
    bit_length(...)
        bit_length(x): returns length of string representing x in base
2

>>> gmpy.bit_length(275)
9

    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.

>>> gmpy.digits(275,2)
'100010011'

    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.

>>> a = 275    # '100010011'
>>> b = 333    # '101001101'
               #    x xxxx
>>> gmpy.hamdist(a,b)
5

    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.

>>> gmpy.digits(gmpy.lowbits(333,8),2)
'1001101' # (bit 7 was a 0)

    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' character, nor leading '0' or '0x' decoration,
        is made in the returned length.  x must be an mpz, or else
gets
        coerced into one.

>>> import collatz_functions
>>> c = collatz_functions.Type12MH(6,1)
>>> gmpy.numdigits(c,2)
177149

    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.

>>> gmpy.popcount(3**33)
34
>>> gmpy.digits(3**33,2)
'10011101111111110111110100110010110101011101110000011'

    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.

>>> gmpy.scan0(3**33,4) # find first 0 bit starting at bit4
4
'10011101111111110111110100110010110101011101110000011'
                                                 x
    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.

>>> gmpy.scan1(3**33,4) # find first 1 bit starting at bit4
7
'10011101111111110111110100110010110101011101110000011'
                                              x

    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.

>>> a = 2**24+1
>>> gmpy.digits(a,2)
'1000000000000000000000001'
>>> a = gmpy.setbit(a,12,1)
>>> gmpy.digits(a,2)
'1000000000001000000000001'



More information about the Python-list mailing list