bitwise operators




The bitwise operators allow you to manipulate the bits of a primitive integer storage location (any integer type).

Examples:


Remember that all primitive data types are represented internally in binary.  The ... represents missing bits.
A bit is represented as a 1 (true) or a 0 (false).  A 1 represents that we have that value, a 0 represents that
we do not have that value.  The left most bit represents the sign (0 is positive and 1 is negative).  Negative
numbers are represented in two's complement form (~n + 1).  ~n means to flip all of the bits.

For example:
...001101 --> 13   since in binary each position represents a power of 2.

... + 25 + 24 + 23 + 22 + 21 + 20 
... + 0 +  0 +  1 +  1 +  0 + 1
... + 0 +  0 +  8 +  4 +  0 + 1

So, we have 1 23 + 1 22 + 1 20
              8  +   4  +   1  = 13
					
Note: ...1111111110011 --> -13  where this is the two's complement of 13.  (flip all bits and add 1)



The unary ~ operator flips or inverts all of the bits.  A zero bit is changed to a 1 and a 1 bit is changed
to a 0.  This happens for all bits, including the sign bit.  This is known as the 1's complement of a number.  The 
two's complement of a number is the one's complement + 1.

~12  --> -13
~-13 --> 12

~0  --> -1
~-1 --> 0

In general, ~(n) --> (-n) - 1



The bitwise & operator performs a bit by bit and operation.  A 1 & 1 is a 1, else we get a 0.  This follows the
same pattern as with the logical operator && (and).  A 1 is a true, and a 0 is a false.  The sign bits are involved.
So, if two negative numbers are involved, the outcome is negative, else it is positive. 

value &&  value   result
-----     -----   ------
true  &&  true    true
true  &&  false   false
false &&  true    false
false &&  false   false

int x = 13 & 9;

  ...01101 (13)  
& ...01001 ( 9)
----------
  ...01001 ( 9)


The bitwise | operator performs a bit by bit or operation.  A 0 | 0 is a 0, else we get a 1.  This follows the
same pattern as with the logical operator || (or).  A 1 is a true, and a 0 is a false.  The sign bits are involved.
So, the only way to end up with a positive outcome is to have two positive numbers.

value ||  value   result
-----     -----   ------
true  ||  true    true
true  ||  false   true
false ||  true    true
false ||  false   false

int x = 13 | 9;
 
  ...01101 (13) 
| ...01001 ( 9)
----------
  ...01101 (13)



Bit Shift Operators


The bitwise shift operator >> will shift all the bits to the right the specified number of positions.  The
sign bit is retained (the left most bit always stays the same).  So positive numbers stay positive, 
and negative numbers stay negative.

...110110 >> 1  --> ...11011  (note that the right most bit 0 fell off the edge of the world) 
So 54 >> 1 will give us 27.   54/21 = 54/2 = 27 
int x = 54 >> 1;

...110110 >> 2  --> ...1101   (note that the right most 2 bits 10 fell off the edge of the world) 
So 54 >> 2 will give us 13.   54/22 = 54/4 = 13 (truncated since it is an int)
int x = 54 >> 2;
  
...110110 >> 3  --> ...110    (note that the right most 3 bits 110 fell off the edge of the world) 
So 54 >> 3 will give us 6.    54/23 = 54/8 = 6 (truncated since it is an int)
int x = 54 >> 3;
  



The bitwise shift operator << will shift all the bits to the left the specified number of positions.  The
sign bit is retained (the left most bit always stays the same).  So positive numbers stay positive, 
and negative numbers stay negative.

...000110 << 1  --> ...1100   (note that the bit at the right is now a 0)
So 6 << 1 will give us 12.    6*21 = 6*2 = 12 
int x = 6 << 1;

...000110 << 2  --> ...11000  (note that the right most 2 bits are now 0) 
So 6 << 2 will give us 24.    6*22 = 6*4 = 24 
int x = 6 << 2;
  
...000110 << 3  --> ...110000 (note that the right most 3 bits are now 0) 
So 6 << 3 will give us 48.    6*23 = 6*8 = 48 
int x = 6 << 3;



The bitwise shift operator >>> (unsigned) will shift all the bits to the right the specified number of positions.  
However, 0's are shifted in from the left.  This makes all numbers positive.  So, if you start with a 
positive number, this is the same as a >> operation.  However, negatives will be drastically different.


...110110 >>> 1  --> ...11011  (note that the right most bit 0 fell off the edge of the world) 
So 54 >>> 1 will give us 27.   54/21 = 54/2 = 27 
int x = 54 >>> 1;

...110110 >>> 2  --> ...1101   (note that the right most 2 bits 10 fell off the edge of the world) 
So 54 >>> 2 will give us 13.   54/22 = 54/4 = 13 (truncated since it is an int)
int x = 54 >>> 2;
  
...110110 >>> 3  --> ...110    (note that the right most 3 bits 110 fell off the edge of the world) 
So 54 >>> 3 will give us 6.    54/23 = 54/8 = 6 (truncated since it is an int)
int x = 54 >>> 3;

Here is an example with -1.  
-1>>>2 = 1073741823   (11111111111111111111111111111111 >>> 2 = 00111111111111111111111111111111)




Download BinaryMath.java (program to do bit manipulation)