Bit Shift and Bitwise are operators that make binary calculations perfectly straightforward.

Some years ago, I had to refactor some logic using bit shift operations. That made me think that most developers had never seen or even understand what are bit shift and bitwise operations.

These operators provide a great must-know solution for specific problems, like network calculations (IP & netmask); privileges processing based in bit fields; communication involving checksums, parity, flow control (e.g.: serial communication); compression; encryption, etc.

The performance is another important point. Instead of implementing more complex algorithms, binary processing can be done with the minimum effort, since bitwise and bit shift are primitive operations directly supported by processors.

The operators are:

Two’s Complement

To understand what are binary operations, it’s necessary to understand how signed integer numbers are represented in binary notation. My previous post, Two’s Complement, describes it.

~ Bitwise Complement

Bitwise Complement ~ is the operator to binary invert the bit pattern of a value.

Let A be an int with value 18:

All bits were inverted, thus turning 0 to 1 and 1 to 0. Because of the Two’s Complement architecture, every ~X will be -X-1.

& Bitwise AND

Bitwise AND & is the operator to execute binary conjunction.

Let A be a short with value 18, and B be a short with value 4216;

Binary conjunction turns two 1 into 1, and anything else into 0. In the above example, the only coincident bit in A and B was the 5th bit (from right to left), what makes the result value be 16.

^ Bitwise Exclusive OR

Bitwise Exclusive OR ^ is the operator to execute binary exclusive disjunctions, also known as XOR.

Using the same previous example, let A be a short with value 18, and B be a short with value 4216;

Binary exclusive disjunction turns one, and only one, 1 into 1, and anything else into 0. In the above example, the result value was 4202.

| Bitwise Inclusive OR

Bitwise Inclusive OR | is the operator to execute binary inclusive disjunctions, also known as simply OR.

Using the same previous example, let A be a short with value 18, and B be a short with value 4216;

Binary inclusive disjunction turns two 0 into 0 and anything else into 1. In the above example, the result value was 4218.

<< Signed Left Shift

Signed Left Shift << is the operator to shift bits to the left.

Let A be a short with value 25.

The operation above shifted 2 positions to the left, making the result value be 100.

It’s important to understand what happens in the most significant bit. To understand it, let’s take another example.

Let B be a short with value 8192.

That is, simple shifts. No special behavior happens during the shift to the left.

>> Signed Right Shift

Signed Right Shift >> is the operator to shift bits to the right, keeping the signal.

Let A be a short with value 25.

The operation above shifted the bits 2 positions to the right, making the result value 12.

To figure out what happens in the most significant bit, let’s also take other examples.

Let B be a short with value 16384.

Let C be a short with value -32768.

Thus, we conclude that Signed Right Shift keeps the signal. In other words, it shifts a bit at the leftmost position with the same value as the signal.

>>> Unsigned Right Shift

Unsigned Right Shift >>> is the operator to shift bits to the right, not considering the signal.

The behavior is the same as the Signed Right Shift, with only an exception: the bit added to the left is ALWAYS zero. Let’s take the last example of Signed Right Shift:

Let C be a short with value -32768.

It results in always producing a positive value, which is half the absolute value of C.

Shift Peculiarities

Shifts in binary representations are shortcuts to calculate multiplications and divisions by 2, ONLY IF it does not modify the most significant bit.

When shifting A to the left in one position, if the most significant bit is not modified, the result will be 2A. When shifting A to the right in one position, if the most significant bit is not modified, the result will be A/2.

Tags: java  core 
comments powered by Disqus