Brought to you by EarthWeb
ITKnowledge Logo Login Graphic Click NOW to join Planet IT!
Click NOW to join Planet IT!
ITKnowledge
Find:
 
EXPERT SEARCH ----- nav

EarthWeb Direct

EarthWeb sites: other sites

Previous Table of Contents Next


Bit-Level Operators

The 13 bit-level operators are among the more obscure in Java. They nonetheless have their uses. The bitwise operators operate on a number or boolean at the bit level, generally by comparing the bits in two quantities and returning a result that depends on the bits in each. The single exception is ~, the NOT, or complement, operator. It takes a single argument and inverts all its bits. The bitshift operators take two operands: the number to be shifted and the number of places to shift it. Except for ~, these operators have “operate and assign” equivalents as well. Table 2-5 lists all the bit-level operators in Java.

Table 2-5 The bitwise operators

Operator Meaning

& AND
| OR
^ Exclusive OR
~ NOT (complement)
<< Shift bits left
>> Shift bits right
>>> Shift bits right without sign extension
&= AND and assign
|= OR and assign
^= Exclusive OR and assign
<<= Shift bits left and assign
>>= Shift bits right and assign
>>>= Shift bits right without sign extension and assign

Some terminology

We’ll need some shorthand to discuss these operators. First, given a value with n bits, the rightmost, least-significant bit is bit 0. The second-rightmost bit is bit one, and so on, up to the leftmost and most significant bit, which is bit n-1. For example, the byte value 37, 00010101 in binary, would have bits shown in Figure 2-4.


Figure 2-4  Bit positions in a byte.

Next, when I write that a bit is “set,” or “on,” that means the bit is 1. When I write that a bit is “not set,” “unset,” or “off,” that means the bit is 0. You’ll also hear these states referred to as “true” and “false” in other books, but I avoid that terminology here to avoid confusion with the boolean literals.

Finally, note that a lot of the examples in this book will be with bytes, simply because it’s easier to follow what’s going on when you only have to keep track of eight bits. However, just as Java performs arithmetic only on int and larger data types, and promotes the operands as necessary, so too will it promote the operands of a bitwise operator and return an int or larger result. For example, even if b1 and b2 are bytes, b1 & b2 is an int; both b1 and b2 are promoted to ints before the bitwise and is performed.

Bitwise operators

The bitwise operators — &, |, and ^ — combine two numbers according to their bit patterns. The bitwise not operator ~ inverts a single number’s bit pattern.

The & operator

The & operator is the bitwise AND operator. It takes two numeric arguments, compares their bits, and sets the bits in the result that are set in both of the arguments. For example, let b1 be a byte with value 78 and b2 be a byte with the value -23. In binary, 78 is 01001110 and -23 is 11101001. Lay these values on top of each other as shown in Figure 2-5. The result, shown in the bottom row, is 01001100, that is, 76.


Figure 2-5  78 & -23.

The bits that are equal to one in both 78 and -23 are equal to one in the result. All other bits are zero.

As mentioned earlier, Java actually performs this calculation using 32-bit ints. Because the high-order three bytes of a positive int are just full of zeroes, the real result of 78 & -23 must be 0000000000000000000000000-1001000. If either argument of & has a zero bit in a particular position, that bit must be 0 in the result, regardless of the value of the bit in the second argument. Therefore, 0 & anything is always 0.

The & operator can also be used with two booleans: true & true is true, true & false is false, and false & false is false. At the level of the virtual machine, the boolean value true is the int 00000001 and false is the int 00000000. Thus, true & true is the same as 00000001 & 00000001 equals 00000001 or true. Conversely, false & false is 00000000 & 00000000 equals 00000000 or false. And finally, true & false is 00000001 & 00000000 equals 00000000 or false.

This is often used to avoid short-circuiting expression evaluation. Suppose isConditionOne() and isConditionTwo() are methods that return booleans and have some side effect such as printing output on System.out. Now suppose you write this statement:

     if ( isConditionOne() && isConditionTwo() ) doSomething();

If isConditionOne() returns false, then isConditionTwo() is never called. Because isConditionOne() is known to be false, Java knows the result will be false, regardless of the value of isConditionTwo(). This can be a problem when isConditionTwo() has side effects, and you need it to be called regardless of condition one. To force isConditionTwo() to be called, use the bitwise & instead. That is

     if ( isConditionOne() & isConditionTwo() ) doSomething();

The truth value of ( isConditionOne() & isConditionTwo() ) is the same as the truth value of ( isConditionOne() && isConditionTwo() ), but now both methods will be called.


Previous Table of Contents Next
HomeAbout UsSearchSubscribeAdvertising InfoContact UsFAQs
Use of this site is subject to certain Terms & Conditions.
Copyright (c) 1996-1999 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.