The JavaTM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search Feedback Form

Trail: Learning the Java Language
Lesson: Language Basics

## Shift and Logical Operators

> A shift operator allows you to perform bit manipulation on data. This table summarizes the shift operators available in the Java programming language.

> Operator | Use | Operation
> `>>` | `op1 >> op2` | shift bits of `op1` right by distance `op2`
> `<<` | `op1 << op2` | shift bits of `op1` left by distance `op2`
> `>>>` | `op1 >>> op2` | shift bits of `op1` right by distance `op2` (unsigned)

> Each shift operator shifts the bits of the left-hand operand over by the number of positions indicated by the right-hand operand. The shift occurs in the direction indicated by the operator itself. For example, the following statement shifts the bits of the integer 13 to the right by one position:

> >     13 >> 1;

> The binary representation of the number 13 is 1101. The result of the shift operation is 1101 shifted to the right by one position--110 or 6 in decimal. Note that the bit farthest to the right falls off the end into the bit bucket.

> The Java programming language also provides these four operators that perform logical functions on their operands:

> Operator | Use | Operation
> `&` | `op1 & op2` | bitwise `and`
> `|` | `op1 | op2` | bitwise `or`
> `^` | `op1 ^ op2` | bitwise `xor`
> `~` | `~op2` | bitwise complement

> The `&` operation performs the logical "and" function on each parallel pair of bits in each operand. The "and" function sets the resulting bit to 1 if both operands are 1, as shown in this table:

> `op1` | `op2` | Result
> 0 | 0 | 0
> 0 | 1 | 0
> 1 | 0 | 0
> 1 | 1 | 1

> Suppose you were to "and" the values 12 and 13:

> >     12 & 13

> The result of this operation is 12. Why? Well, the binary representation of 12 is 1100, and the binary representation of 13 is 1101. The "and" function sets the resulting bit to 1 if both operand bits are 1, otherwise, the resulting bit is 0. So, if you line up the two operands and perform the "and" function, you can see that the two high-order bits (the two bits farthest to the left of each number) of each operand are 1. Thus the resulting bit in the result is also 1. The low-order bits evaluate to 0 because either one or both bits in the operands are 0:

> >         1101
> >       & 1100
> >       ------
> >         1100

> The `|` operator performs the inclusive or operation and `^` performs the exclusive or operation. Inclusive or means that if either of the two bits are 1 then the result is 1. The following table shows the results of your inclusive or operations:

> `op1` | `op2` | Result
> 0 | 0 | 0
> 0 | 1 | 1
> 1 | 0 | 1
> 1 | 1 | 1

> Exclusive or means that if the two operand bits are different the result is 1, otherwise the result is 0. The following table shows the results of your exclusive or operation.

> `op1` | `op2` | Result
> 0 | 0 | 0
> 0 | 1 | 1
> 1 | 0 | 1
> 1 | 1 | 0

> And finally, the complement operator inverts the value of each bit of the operand: if the operand bit is 1 the result is 0 and if the operand bit is 0 the result is 1.

> Among other things, bitwise manipulations are useful for managing sets of boolean flags. Suppose for example, that you had several boolean flags in your program that indicated the state of various components in your program: is it visible, is it draggable, and so on. Rather than define a separate boolean variable to hold each flag, you could define a single variable, `flags`, for all of them. Each bit within `flags` would represent the current state of one of the flags. You would then use bit manipulations to set and get each flag.

> First, set up constants that indicated the various flags for your program. These flags should each be a different power of two to ensure that the "on" bit doesn't overlap with another flag. Define a variable, `flags`, whose bits would be set according to the current state of each flag. The following code sample initializes `flags` to 0 which means that all flags are false (none of the bits are set).

> >     static final int VISIBLE = 1;
> >     static final int DRAGGABLE = 2;
> >     static final int SELECTABLE = 4;
> >     static final int EDITABLE = 8;

> >     int flags = 0;

> To set the "visible" flag when something became visible you would use this statement:

> >     flags = flags | VISIBLE;

> To test for visibility, you could then write:

> >     if ((flags & VISIBLE) == VISIBLE) {
> >         ...
> >     }

> Here's the complete program, `BitwiseDemo`, that includes this code.

> >     public class BitwiseDemo {

> >         static final int VISIBLE = 1;
> >         static final int DRAGGABLE = 2;
> >         static final int SELECTABLE = 4;
> >         static final int EDITABLE = 8;

> >         public static void main(String[] args)
> >         {
> >             int flags = 0;

> >             flags = flags | VISIBLE;
> >             flags = flags | DRAGGABLE;

> >             if ((flags & VISIBLE) == VISIBLE) {
> >                 if ((flags & DRAGGABLE) == DRAGGABLE) {
> >                      System.out.println("Flags are Visible and Draggable.");
> >                 }
> >             }

> >             flags = flags | EDITABLE;

> >             if ((flags & EDITABLE) == EDITABLE) {
> >     	    System.out.println("Flags are now also Editable.");
> >             }
> >         }
> >     }

> Here's the output from this program:

> >     Flags are Visible and Draggable.
> >     Flags are now also Editable.

| Start of Tutorial > Start of Trail > Start of Lesson | Search Feedback Form