From: MRAB on
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.
From: cjw on
On 12-May-10 14:40 PM, MRAB 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.

a= 6
if a & 2:
print 'hit'
else:
print 'miss'

This hits.

Colin W.

From: Mensanator on
On May 12, 1:40 pm, MRAB <pyt...(a)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'