;

Java has got much faster in the last few years but when you need the ultimate in speed you can drop to bit operations. By manipulating bits some operations can be greatly sped up. The class below shows some examples of ways that bit operations can be used in code. Generally speaking bit operations are much harder to read and understand than regular code so use these sparingly and only where they are really need for speed improvements. The possible exception to this rule is negating a number which is just as readable with a bit operation as not. The thrid example here shows how a single int or other primative can be used to hold a large number of options. This is the same system that is used for unix file permissions.

package example;

public class BitOperations {

 
public BitOperations() {
   
//Flipping Between Two Values
   
long start = System.currentTimeMillis();
    flipBetweenVariablesSimple
();
   
long end = System.currentTimeMillis();
    printTiming
( start, end, "flipBetweenVariableSimple" );
   
    start = System.currentTimeMillis
();
    flipBetweenVariablesBit
();
    end = System.currentTimeMillis
();
    printTiming
( start, end, "flipBetweenVariableBit" );
   
   
//Negating a Value
   
start = System.currentTimeMillis();
    negateSimple
();
    end = System.currentTimeMillis
();
    printTiming
( start, end, "negateSimple" );
   
    start = System.currentTimeMillis
();
    negateBit
();
    end = System.currentTimeMillis
();
    printTiming
( start, end, "negateBit" );
   
   
//Bit Map Options
   
bitMapOptions();
 
}
 
 
private void flipBetweenVariablesSimple() {
   
int a = 10, b = 12, c = 10;
   
long total = 0;
   
   
for( int i = 0, n = 100000000; i < n; i ++ ) {
     
if( c == a ) {
       
c = b;
     
} else {
       
c = a;
     
}
     
total += c;
   
}
  }
 
 
/**
   *
<p>Shows how c can be flipped between the value of a and b with a simple XOR
   * opperation. The variable c must start of and always remain the same as either
   * a or b.
</p>
  
*
   *
<p>This works because repeating an XOR operation effectivly reverses that operation.
   * In binary for example:
</p>
  
* <pre>
  
* a   b   c  c   b   a
   * 0 ^ 1 = 1, 1 ^ 1 = 0
   * 1 ^ 1 = 0, 0 ^ 1 = 1
   *
</pre>
  
*/
 
private void flipBetweenVariablesBit() {
   
int a = 10, b = 12, c = 10;
   
long total = 0;
   
   
for( int i = 0, n = 100000000; i < n; i ++ ) {
     
c = a ^ b ^ c;
      total += c;
   
}
  }
 
 
private void negateSimple() {
   
int a = 12345;
   
long total = 0;
   
   
for( int i = 0, n = 100000000; i < n; i ++ ) {
     
a = a * -1;
      total += a;
   
}
  }
 
 
/**
   *
<p>A positve number can be converted to a negative number by
   * negating every bit and adding one. In binary this looks like this:
</p>
  
* <pre>
  
*  6                -7                -6
   * 0110 - negate -> 1001 - add one -> 1010
   *
</pre>
  
*/
 
private void negateBit() {
   
int a = 12345;
   
long total = 0;
   
   
for( int i = 0, n = 100000000; i < n; i ++ ) {
     
a = ~a + 1;
      total += a;
   
}
  }
 
 
private void bitMapOptions() {
   
final int foo = 1 << 0;
   
final int bar = 1 << 1;
   
final int baz = 1 << 2;
   
final int boz = 1 << 3;
   
   
int primaryOptions = foo + baz;
   
int secondaryOptions = bar + boz;
   
   
int allOptions = primaryOptions + secondaryOptions;
   
   
//Is boz set in the primary options?
   
int on;
   
if( ( on = primaryOptions & boz ) > 0 ) {
     
System.out.println( "Boz is set as a primary option." );
   
} else {
     
System.out.println( "Boz is not set as a primary option." );
   
}
   
   
//Is boz set in the secondary options?
   
if( ( on = secondaryOptions & boz ) > 0 ) {
     
System.out.println( "Boz is set as a secondary option." );
   
} else {
     
System.out.println( "Boz is not set as a secondary option." );
   
}
  }
 
 
private void printTiming( long start, long end, String name ) {
   
System.out.println( name + ": " + ( end - start ) + "ms" );
 
}
 
 
public static void main(String[] args) {
   
new BitOperations();
 
}

}