In a computer program, bitwise operators are operators for manipulating bit patterns in expressions. Bitwise AND, OR, exclusive OR (XOR), NOT, right shift and left shift are common operations. Most computer programming languages include all six of these operators. They are often used for setting, clearing or flipping individual bits in programs which control computer hardware. Bitwise operators are also frequently used in data encryption and compression algorithms.
The common bitwise operators are usually represented symbolically in programming languages like C, C++ and Java. They are used in expressions just as arithmetic operators like plus or minus signs would be. The bitwise operator AND is represented with the ampersand &, OR with the pipe | and XOR with the caret ^. NOT, also known as the complement operator, is indicated with a tilde ~.
The right shift operator uses a double-caret pointing to the right >>. In contrast, left shift is indicated by a left-pointing double-caret <<. Java includes another right shift operation, shown with a right-pointing triple-caret >>>.
Bitwise operators apply a logical operation to each pair of bits in their operands. NOT, right shift and left shift have only one true operand; the second value in shift operations is the bit count. To better understand how bitwise operators work, an individual can visualize their operands as binary numerals. For example, the complement operator flips each bit of its single operand to the opposite state. A one becomes a zero and a zero becomes a one. The complement of the 8-bit binary value 00110101 is 11001010.
The AND operator has two operands. Bit by bit, a logical AND operation is performed using one corresponding bit from each operand. The outcome of each bit operation is placed in that bit position of the overall result. For example, the AND operator will process bit 7 of one operand with bit 7 of the other operand. The outcome will be stored in bit 7 of the overall result.
In an AND operation, both operand bits must be ones in order for the result to be one, otherwise the result is zero. For example, if the 8-bit binary values of the operands are 00110101 and 11110000, the result will be 00110000. A common use of the AND operator is to zero out particular bits in the result. This is done by placing zeroes in those bit positions in one of the operands.
In an OR operation, both operand bits must be zeroes in order for the result to be zero; otherwise, the result is one. A common use of the OR operator is to set certain bits of the result to ones. This is done by placing ones in those bit positions in one of the operands. For the XOR operation, the result is zero if both operand bits are zero or if both operand bits are one—otherwise, the result is one.
Left shift and right shift move the bits in the operand left or right by the specified number of bit positions. A logical right shift moves a zero into the leftmost bit as part of the shift. An arithmetic right shift copies the leftmost bit—the sign bit—before the shift into the same position after the shift. The original bit is also shifted right along with the rest. Either type of left shift moves a zero into the rightmost bit.
When an operand is right-shifted, the rightmost bit before the shift is simply thrown away. Similarly, the leftmost bit before a left shift is disposed of. It does not wrap around to the other end of the operand.
Bitwise shift operations are language- and implementation-dependent. For example, in C and C++, >> and << perform logical shifts if the operand is an unsigned integer. If the operand is a signed integer, it is likely that an arithmetic shift will be done instead. In Java, all operands are considered signed, and arithmetic shifts are always performed with >> and <<. The >>> operator is used for a logical right shift, but it is still possible to accidentally do an arithmetic right shift instead without careful typecasting.
Complications can also arise when operands have different bit lengths or when some are signed and some are unsigned. Bitwise operators and numeric constants in the middle of a complex expression may not be evaluated as anticipated. Care must be taken to specify the size and signed/unsigned nature of each quantity in the expression. This can be done with careful typecasting or interim assignments to specific variable types in program code.