views:

423

answers:

5
x = 1        # 0001
x << 2       # Shift left 2 bits: 0100
# Result: 4

x | 2        # Bitwise OR: 0011
# Result: 3

x & 1        # Bitwise AND: 0001 
# Result: 1

I can understand the arithmetic operators in Python (and other langs), but I never understood 'bitwise' operators quite well. In the above example (from a Python book), I understand the left-shift but not the other two.

Also, what are bitwise operators actually used for? I'd appreciate some examples.

Thanks!

+3  A: 

One typical usage :

| is used to set certain bit to 1

& is used to test or clear a certaint bit

  • Set a bit (where n is the bit number, and 0 is the least significant bit):

    unsigned char a |= (1 << n);

  • Clear a bit:

    unsigned char b &= ~(1 << n);

  • Toggle a bit:

    unsigned char c ^= (1 << n);

  • Test a bit:

    unsigned char e = d & (1 << n);

Take the case your list for example:

x | 2 is used to set bit 1 of x to 1

x & 1 is used to test if bit 0 of x is 1 or 0

pierr
+14  A: 

Bitwise operators are operators that work on a multi-bit value but conceptually one bit at a time.

  • AND is 1 only if both of its inputs are 1.
  • OR is 1 if one or more of its inputs are 1.
  • XOR is 1 only if exactly one of its inputs are 1.
  • NOT is 1 only if its input are 0.

These can be best described as truth tables. Inputs possibilities are on the top and left, the resultant bit is one of the four (two in the case of NOT since it only has one input) values shown at the intersection of the two inputs.

AND | 0 1     OR | 0 1     XOR | 0 1    NOT | 0 1
----+-----    ---+----     ----+----    ----+----
 0  | 0 0      0 | 0 1       0 | 0 1        | 1 0
 1  | 0 1      1 | 1 1       1 | 1 0

One example is if you only want the lower 4 bits of an integer, you AND it with 15 (binary 1111) so:

    201: 1100 1001
AND  15: 0000 1111
------------------
 IS   9  0000 1001

Another example is if you have two 4-bit values that you want to pack into an 8-bit one, you can use all three of your operators (left-shift, and and or):

packed_val = ((val1 & 15) << 4) | (val2 & 15)
  • The & 15 operation will make sure that both values only have the lower 4 bits.
  • The << 4 is a 4-bit shift left to move val1 into the top 4 bits of an 8-bit value.
  • The | simply combines these two together.

If val1 is 7 and val2 is 4:

                val1            val2
                ====            ====
 & 15 (and)   xxxx-0111       xxxx-0100  & 15
 << 4 (left)  0111-0000           |
                  |               |
                  +-------+-------+
                          |
| (or)                0111-0100
paxdiablo
+1  A: 

Hope this clarifies those two:

x | 2

0001 //x
0010 //2

0011 //result = 3


x & 1

0001 //x
0001 //1

0001 //result = 1
Amarghosh
not quite 2 has only one bit set.
stonemetal
Oops... tried to be the fastest gun in the west.... ended up as an idiot who doesn't even know binary for two :( Fixed it.
Amarghosh
A: 

Think of 0 as false and 1 as true. Then bitwise and(&) and or(|) work just like regular and and or except they do all of the bits in the value at once. Typically you will see them used for flags if you have 30 options that can be set (say as draw styles on a window) you don't want to have to pass in 30 separate boolean values to set or unset each one so you use | to combine options into a single value and then you use & to check if each option is set. This style of flag passing is heavily used by OpenGL. Since each bit is a separate flag you get flag values on powers of two(aka numbers that have only one bit set) 1(2^0) 2(2^1) 4(2^2) 8(2^3) the power of two tells you which bit is set if the flag is on.

Also note 2 = 10 so x|2 is 110(6) not 111(7) If none of the bits overlap(which is true in this case) | acts like addition.

stonemetal
+3  A: 

what are bitwise operators actually used for? I'd appreciate some examples.

One of the most common uses of bitwise operations is for parsing hexadecimal colours.

For example, here's a python function that accepts a String like #FF09BE and returns a tuple of its Red, Green and Blue values.

def hexToRgb(value):
    //convert string to hexadecimal number (base 16)
    num = (int(value.lstrip("#"), 16))
    //shift 16 bits to the right, and then binary AND to obtain 8 bits representing red
    r = ((num >> 16) & 0xFF)
    //shift 8 bits to the right, and then binary AND to obtain 8 bits representing green
    g = ((num >> 8) & 0xFF)
    //simply binary AND to obtain 8 bits representing blue
    b = (num & 0xFF)
    return (r, g, b)

I know that there are more efficient ways to acheive this, but I believe that this is a really concise example illustrating both shifts and bitwise boolean operations.

bguiz