Re: bitwise operator, bits dont go into bitbucket..?

2015-11-10 Thread Chris Angelico
On Wed, Nov 11, 2015 at 9:27 AM, kent nyberg  wrote:
> Im reading about bitwise operators and is it true to say they dont work 100% 
> as in C?
> bitwise operators in C seem to result in bits going to the so called 
> bitbucket.
> For example, 0b0001. Shifting it >> 1  in C it seems to add on zero to 
> the left and the 1 to the right gets throwned away.
>
> But doing it in python just adds one more bit, from the left.
> That is, 0b0001 >> 1 = 0b1.

I'm not sure what you're expecting Python to do here, but
right-shifting the integer 1 results in the integer 0:

>>> 0b01 >> 1
0

> Bitwise operators in C (when reading examples,) gives some time code that 
> check specific bits by
> shifting the bits left and right to make every bit but the specific one to 
> zeros.
> As I understand bitwise operators in python, this is not possible then?

If you want to check specific bits (in C or Python, either way), it's
much more common to use bitwise AND than bit shifts:

>>> 0b100011011101010110 & 0b0001
16
>>> print(bin(_))
0b1

This will be either the same number as the right hand side (if the bit
had been set) or zero (if it hadn't).

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: bitwise operator, bits dont go into bitbucket..?

2015-11-10 Thread kent nyberg
On Wed, Nov 11, 2015 at 09:33:38AM +1100, Chris Angelico wrote:
> On Wed, Nov 11, 2015 at 9:27 AM, kent nyberg  wrote:

> 
> If you want to check specific bits (in C or Python, either way), it's
> much more common to use bitwise AND than bit shifts:
> 
> >>> 0b100011011101010110 & 0b0001
> 16
> >>> print(bin(_))
> 0b1
> 

So, to check if 0b010[this one bit]010 is set,   i do   & 0b0001000

That is,  I set just that one to 1 in the other and then the & operator will 
make it return
0 if its not set. Since every other is zero, the return will be zero if its 
not. Since & operator sets 0
if not both are 1. Right?  

Id so, Thanks.   

My misunderstanding was that
0b01000   (for example,) first could be shifted left. To become 0b1.
And then shifted right to become 0b1. 
The shifting would turn every other digit to 0 and leave only the wanted one 
untouched. 
That way, I could check if its 0 or 1.  If you understand my own logic of how 
it works.
But I got it wrong,  and I think I know how to do it with & operator.

> This will be either the same number as the right hand side (if the bit
> had been set) or zero (if it hadn't).
> 
> ChrisA
> -- 
> https://mail.python.org/mailman/listinfo/python-list
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: bitwise operator, bits dont go into bitbucket..?

2015-11-10 Thread Chris Angelico
On Wed, Nov 11, 2015 at 9:56 AM, kent nyberg  wrote:
> So, to check if 0b010[this one bit]010 is set,   i do   & 0b0001000
>
> That is,  I set just that one to 1 in the other and then the & operator will 
> make it return
> 0 if its not set. Since every other is zero, the return will be zero if its 
> not. Since & operator sets 0
> if not both are 1. Right?
>
> Id so, Thanks.

Exactly! It's common to have named constants for things that matter to
you; for example, you can find out if a file/directory is
world-writable like this:

>>> import stat
>>> os.stat("/").st_mode & stat.S_IWOTH
0
>>> os.stat("/tmp").st_mode & stat.S_IWOTH
2

So my root directory is not world writable (result of zero), and the
/tmp directory is. (This is not surprising.) The S_IWOTH constant is
simply the integer 2, but giving it a name makes it a bit easier to
see what's going on in the code. (Not that the name is abundantly
clear... it could be improved on. But it's better than just '2'.)

> My misunderstanding was that
> 0b01000   (for example,) first could be shifted left. To become 0b1.
> And then shifted right to become 0b1.
> The shifting would turn every other digit to 0 and leave only the wanted one 
> untouched.
> That way, I could check if its 0 or 1.  If you understand my own logic of how 
> it works.
> But I got it wrong,  and I think I know how to do it with & operator.

That's true of right shifting, but when you left shift, you're
depending on a specific word size. Even in C, it's possible to get
burned by that (eg when you move from 32-bit to 64-bit), and in
Python, integers have infinite size. If you definitely want that
behaviour, you can do this:

(0b01000 << 1) & 0b1

which will mask off your result to just five bits, giving you the
"drop the top bit" effect. But for bit testing and manipulation, it's
way easier to use AND/OR/XOR than shifts.

The one place you might want to use bit shifts is in _creating_ those
constants. For instance:

STYLE_FOO = 1 << 0
STYLE_BAR = 1 << 1
STYLE_BAZ = 1 << 2
STYLE_ABC = 1 << 3
STYLE_QWE = 1 << 4
STYLE_XYZ = 1 << 5

>From this table, it's obvious that they've been assigned successive
bits. You can do the same with an enumeration:

>>> class Style(enum.IntEnum):
... FOO = 1 << 0
... BAR = 1 << 1
... BAZ = 1 << 2
... ABC = 1 << 3
... QWE = 1 << 4
... XYZ = 1 << 5
...
>>> Style.BAR

>>> Style.QWE


And then you can test to see if some style was chosen:

>>> widget = Style.FOO | Style.QWE
>>> widget & Style.ABC
0
>>> widget & Style.QWE
16

Does that make things a bit easier to read?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list