Bitwise Compound Assignment Operators: &=, ^=, |=
Bitwise compound assignment operators for the bitwise operators are defined in Table 2.33. Type conversions for these operators, when applied to integral operands, are the same as for other compound assignment operators: An implicit narrowing conversion is performed on assignment when the destination data type is either byte, short, or char. These operators can also be applied to boolean operands to perform logical compound assignments (p. 79).
Table 2.33 Bitwise Compound Assignment Operators
Expression | Given T is the integral type of b, the expression is evaluated as: |
b &= a | b = (T) ((b) & (a)) |
b ^= a | b = (T) ((b) ^ (a)) |
b |= a | b = (T) ((b) | (a)) |
Examples of Bitwise Compound Assignment
int v0 = -42;
char v1 = ‘)’; // 41
byte v2 = 13;
v0 &= 15; // 1…1101 0110 & 0…0000 1111 => 0…0000 0110 (= 6)
v1 |= v2; // (1) 0…0010 1001 | 0…0000 1101 => 0…0010 1101 (= 45, ‘-‘)
At (1) in these examples, both the char value in v1 and the byte value in v2 are first promoted to int. The result is implicitly narrowed to the destination type char on assignment.
2.17 Shift Operators: <<, >>, >>>
The binary shift operators return a new value formed by shifting bits either left or right a specified number of times in a given integral value. The number of shifts (also called the shift distance) is given by the right-hand operand, and the value that is to be shifted is given by the left-hand operand. Note that unary numeric promotion is applied to each operand individually. The value returned has the promoted type of the left-hand operand. Also, the value of the left-hand operand is not affected by applying the shift operator.
The shift distance is calculated by AND-ing the value of the right-hand operand with a mask value of 0x1f (31) if the left-hand operand has the promoted type int, or using a mask value of 0x3f (63) if the left-hand operand has the promoted type long. This effectively means masking the five lower bits of the right-hand operand in the case of an int left-hand operand, and masking the six lower bits of the right-hand operand in the case of a long left-hand operand. Thus the shift distance is always in the range 0 to 31 when the promoted type of the left-hand operand is int (which has size 32 bits), and in the range 0 to 63 when the promoted type of the left-hand operand is long (which has size 64 bits).
Given that v contains the value whose bits are to be shifted and n specifies the number of bits to shift, the bitwise operators are defined in Table 2.34. It is implied that the value n in Table 2.34 is subject to the shift distance calculation outlined above, and that the shift operations are always performed on the value of the left-hand operand represented in two’s complement.
Table 2.34 Shift Operators
Shift left | v << n | Shift all bits in v left n times, filling with 0 from the right. |
Shift right with sign bit | v >> n | Shift all bits in v right n times, filling with the sign bit from the left. |
Shift right with zero fill | v >>> n | Shift all bits in v right n times, filling with 0 from the left. |
Since char, byte, and short operands are promoted to int, the result of applying these bitwise operators is always either an int or a long value. Care must be taken in employing a cast to narrow the resulting value, as this can result in a loss of information as the upper bits are discarded during conversion.
Note that regardless of the promotion of the values in the operands or determination of the shift distance, the operands v and n are not affected by these three shift operators. However, the shift compound assignment operators, discussed in this section, can change the value of the left-hand operand v.
Bit values shifted out (falling off) from bit 0 or the most significant bit are lost. Since bits can be shifted both left and right, a positive value when shifted can result in a negative value, and vice versa.