1. Java provides operators to perform bitwise and bit shift operations on int type.
The operators discussed in the section are less commonly used, the intent is to simply make you aware that these operators exist.
2. Bitwise operators overview:
Operator | Name | Example | Result | Description |
---|---|---|---|---|
a & b | and | 3 & 5 | 1 | 1 if both bits are 1. |
a | b | or | 3 | 5 | 7 | 1 if either bit is 1. |
a ^ b | xor | 3 ^ 5 | 6 | 1 if both bits are different. |
~a | not | ~3 | -4 | Inverts the bits. |
n << p | left shift | 3 <<< 2 | 12 | Shifts the bits of n left p positions. Zero bits are shifted into the low-order positions. |
n >> p | right shift | 5 >> 2 | 1 | Shifts the bits of n right p positions. If n is a 2's complement signed number, the sign bit is shifted into the high-order positions. |
n >>> p | right shift | -4 >>> 28 | 15 | Shifts the bits of n right p positions. Zeros are shifted into the high-order positions. |
3. Examples
1) "AND" example:
@Test
public void andTest() {
int i = 12;
// i = 0000,0000,0000,0000,0000,0000,0000,1100
int j = -3;
// -3 = ~2 -> ~0000,0000,0000,0000,0000,0000,0000,0010 -> 1111,1111,1111,1111,1111,1111,1111,1101
int k = i & j;
// 0000,0000,0000,0000,0000,0000,0000,1100 &
// 1111,1111,1111,1111,1111,1111,1111,1101 ->
// 0000,0000,0000,0000,0000,0000,0000,1100 ->12
assertEquals(12, k);
}
2) "OR" example:
@Test
public void orTest() {
int i = 12;
// i = 0000,0000,0000,0000,0000,0000,0000,1100
int j = -32768;
// -32768 = ~32767 -> ~0000,0000,0000,0000,0111,1111,1111,1111 ->
// 1111,1111,1111,1111,1000,0000,0000,0000
int k = i | j;
// 0000,0000,0000,0000,0000,0000,0000,1100 |
// 1111,1111,1111,1111,1000,0000,0000,0000 ->
// 1111,1111,1111,1111,1000,0000,0000,1100 ->
// -(~1111,1111,1111,1111,1000,0000,0000,1100 + 1) ->
// -( 0000,0000,0000,0000,0111,1111,1111,0100) -> -32756
assertEquals(-32756, k);
}
3) "XOR" example:
@Test
public void xorTest() {
int i = 32756;
// i = 0000,0000,0000,0000,0111,1111,1111,0100
int j = -32768;
// -32768 = ~32767 -> ~0000,0000,0000,0000,0111,1111,1111,1111 ->
// 1111,1111,1111,1111,1000,0000,0000,0000
int k = i ^ j;
// 0000,0000,0000,0000,0111,1111,1111,0100 ^
// 1111,1111,1111,1111,1000,0000,0000,0000 ->
// 1111,1111,1111,1111,1111,1111,1111,0100 ->
// -(~1111,1111,1111,1111,1111,1111,1111,0100 + 1) ->
// -( 0000,0000,0000,0000,0000,0000,0000,1100) -> -12
assertEquals(-12, k);
}
4) "NOT" test
@Test
public void notTest() {
int i = -12;
// ~11 ->
// ~0000,0000,0000,0000,0000,0000,0000,1011 ->
// 1111,1111,1111,1111,1111,1111,1111,0100
int j = ~i;
// ~1111,1111,1111,1111,1111,1111,1111,0100
// 0000,0000,0000,0000,0000,0000,0000,1011
assertEquals(11, j);
i = -32768;
j = ~i;
assertEquals(32767, j);
i = 0XFFFFFFFF;
j = ~i;
assertEquals(0, j);
}
5) "Left Shift" test:
@Test
public void leftShiftTest() {
int i = 12;
// 0000,0000,0000,0000,0000,0000,0000,1100
int j = i << 1;
// 0000,0000,0000,0000,0000,0000,0001,1000
assertEquals(24, j);
i = 0X8000000F;
// 1000,0000,0000,0000,0000,0000,0000,1111
j = i << 1;
// 0000,0000,0000,0000,0000,0000,0001,1110
assertEquals(30, j);
}
6) "Right Shift" test:
@Test
public void rightShiftTest() {
int i, j;
i = 12;
// 0000,0000,0000,0000,0000,0000,0000,1100
j = i >> 1;
// 0000,0000,0000,0000,0000,0000,0000,0110
assertEquals(6, j);
j = i >>> 1;
// 0000,0000,0000,0000,0000,0000,0000,0110
assertEquals(6, j);
i = 0X8000000F;
// 1000,0000,0000,0000,0000,0000,0000,1111
j = i >> 1;
// 1100,0000,0000,0000,0000,0000,0000,0111
assertEquals(0XC0000007, j);
j = i >>> 1;
// 0100,0000,0000,0000,0000,0000,0000,0111
assertEquals(0X40000007, j);
}
4. P.S
1) The size of "int" in java is 32-bit that is 8-byte, thus we can represent that with 8 hex number.
2) The left most bit represents the sign, 0 for positive and 1 for negative.
3) There is no unsigned int/byte data type in java, and we can use "long" if needed.
Reference Links:
1) http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
2) http://www.leepoint.net/notes-java/data/expressions/bitops.html
3) http://stackoverflow.com/questions/9854166/declaring-an-unsigned-int-in-java