Sunday, August 21, 2011

Followup to the Integer toggle code

My good friend Greg mentioned that I should use bitwise operators to perform a toggle, as opposed to my earlier method of using integer math to manipulate the state.  I had not done that because the bitwise implementation is imho not comprehensible by a developer who does not have a CS degree.

As an example it is not at ALL clear to most people that ~2<<10 != ~(2<<10)

Although I suppose that's the point of a method name.



/**
 * A simple way to implement a toggle switch using an integer to store the state
 * and bitwise operators to manipulate the toggle
 * 
 * @author Dan Fishman http://www.fishdan.com
 *
 * This code released to the public under the CreativeCommons 3.0 license by
 * the author on 8/21/2011
 * 
 * http://creativecommons.org/licenses/by/3.0/
 */

public class TestToggle {

  public static int toggleState=0;
  
  public static void main(String argv[]){
      for(int x=0;x<32;x++){
        System.out.println(x+":"+Integer.toBinaryString(toggleState));
        System.out.println(x+":"+Integer.toBinaryString(2 << x));
        toggle(true,x);
        System.out.println("-----------------------");
        System.out.println(x+":"+Integer.toBinaryString(toggleState));
        System.out.println("isOn "+x+" == "+toggleIsOn(x));
        toggle (false,x);
        System.out.println("isOn "+x+" == "+toggleIsOn(x));
        System.out.println("");
      }    
      
      //PAY ATTENTION TO THESE TWO LINES  order of operations can be tricky in bitwise
      // see http://www.uni-bonn.de/~manfear/javaoperators.php
      System.out.println("**"+Integer.toBinaryString(~2<<10));
      System.out.println("**"+Integer.toBinaryString(~(2<<10)));
  }

  /**
  * if onOff==true we set the value at pos == 1 aka on
  * else we set it to 0;
  * @param onOff
  * @param pos
  */
 public static void toggle(boolean onOff, int pos){
     if(onOff==true){
         toggleState |= 2 << pos;
     }
     else{
         toggleState &= ~(2<<pos);
     }
 }
 
 public static boolean toggleIsOn(int x){
     return (toggleState & 2<<x) == 2<<x;
 }        
    
}

Saturday, August 20, 2011

Using an integer to implement a binary toggle switch in Java

We were talking about a way to use an integer to indicate teh state of a series of switches.  e.g. if there were 5 switches and the first 3 were on we would say think of that as 11100, or 28

Not a bad method -- you can very quickly toggle switches on and off by calling

toggle(boolean on,int position)

and you can quickly check it the toggle at a position is on by calling

toggleIsOn(int position);

The code snippet is below, comments welcome.  you have to declare toggleState yourself of course...;



public int toggleState=0;

       /**
     * if onOff==true we set the value at pos == 1 aka on
     * else we set it to 0;
     * @param onOff
     * @param pos
     */
    public void toggle(boolean onOff, int pos){
        if(toggleState==null){
            toggleState=0;
        }
        if(onOff==true){
            if(toggleIsOn(pos)){
                //do nothing, already on
            }
            else{
                //we want it on, and it is currently off
                toggleState+=2^pos;
            }
        }
        else{
            if(toggleIsOn(pos)){
                //It's on, and we want it off
                toggleState-=2^pos;
            }
            else{
                //it's off and we want it off -- do nothing
            }            
        }
    }
    
    public boolean toggleIsOn(int pos){
        if(toggleState==null || toggleState < (2^pos)) return false;
        //divide toggle state
        int multiple=toggleState/(2^pos);
                //if the switch is on, multiple will be an odd number, otherwise it will be even.
        return multiple%2==1;
    }