Depending on the types of programs you write, the bitwise operators are either very important or completely unimportant to you. If you write typical business applications, you will find little need to employ these operators. However, if you develop engineering applications that interface with hardware systems or binary files, the opposite is likely true. When you need a bitwise operator, it is rarely the case that you can substitute any other operation to easily reproduce the same results. However, most of the work you do probably won't put you in this position in the first place. Bitwise operators work at the fundamental level of how values are stored in a computer. This is probably remedial, but, for completeness, it should be covered here. Computers store everything using values stored as sequences of on and off, known as bits, which are most often translated to the binary digits 1 and 0. For example, 32 of these 1s and 0s are required to store a variable of type int. Most of the time, you will manage the value held by an int variable using assignment statements and the various unary and arithmetic operators. Bitwise operators give you the additional option of manipulating the bits used to store a variable directly. Consider a simple example using bytes. A byte comprises 8 bits of memory. Each of the 8 bits can have the value of 0 or 1, and the value of the whole quantity is determined by using base-2 arithmetic, meaning that the rightmost bit represents a value of 0 or 1; the next bit represents the value of 0 or 2; the next represents the value 0 or 4; and so on. The overall value represented by a sequence of bits is just the sum of these individual values. Table 5.3 shows the binary representation of several numbers as an example. Table 5.3. Some Base-10 Values and Their Base-2 Equivalents
To find the base-10, or decimal, value of a number in Table 5.3, you add the numbers at the top of each column that contains a 1 for a given row. These columns represent the bits that are set in the number's base-2, or binary, representation. For instance, the first row shows that the binary number 00010001 is equivalent to 16+1 = 17
Now that you've seen examples of bit representations, the results of applying the bitwise operators are more intuitive. The bitwise operators perform the logical operations of AND, OR, Exclusive OR (sometimes called XOR), and Complement (or NOT) on each bit in turn . The operators are
The &, , and ^ operators are binary operators and ~ is a unary operator. To determine the result of applying a bitwise operator, it is necessary to view each of the operands in its base-2 representation (a sequence of 1s and 0s). For each bit position in the operands, a bitwise operator sets the corresponding bit in the result based on what is known as the operator's truth table. Each of the operators has a different truth table as shown in the following:
The operands of the bitwise operators can be any integer type. Booleans can also be operands to each of the bitwise operators with the exception of the complement operator. When you apply &, , or ^ to two booleans, the result is the same as that given in the preceding truth table if you substitute a value of true for each 1 and false for each 0. If integer operands are used, each operand is promoted to at least an int and the result is an int. If one operand is a long, the other is promoted to a long if necessary, and the result is returned as a long. These rules are true for any of the operators applied to integers. If a boolean operand is used, both operands must be boolean and the result is a boolean. Table 5.4 shows the results of applying each of the bitwise operators to two arbitrary values. First, you see the binary representations of the two decimal numbers 11309 and 798, and then the resulting bit sequences after the various operators are applied. Table 5.4. Bitwise Operation Examples
Similar to the arithmetic assignment operators, the bitwise operators are also supported as shorthand assignment operators. You can use &=, =, or ^= to perform a bitwise operation and assign the result back to the left operand. |