lettura simple

Bitwise Operators in Java

In this lesson, we'll explore bitwise operators in Java, a fascinating concept that lets you work directly with bits, the fundamental units of digital data.

What are they for? When you use bitwise operators, you're manipulating the individual bits that make up a number, rather than working with the entire number at once. After all, 'bitwise' means 'bit by bit'. For example, the integer 5 in binary consists of 4 bits: `0101`. This might seem complex at first, but don't worry—things will become much clearer as we go through some examples.

You might be wondering, what exactly are bits?

Think of bits as a series of switches, where each switch can be either on or off: on is represented by 1, off by 0. These switches are the bits in a binary number.

Bitwise operators allow you to "toggle" these switches.

The main bitwise operators in Java are:

Operator Description Example
& Bitwise AND a & b
| Bitwise OR a | b
^ Bitwise XOR a ^ b
~ Bitwise NOT ~a
<< Left Shift a << 2
>> Right Shift a >> 2
>>> Unsigned Right Shift a >>> 2
<<= Left Shift with assignment a <<= 2
>>= Right Shift with assignment a >>= 2

Now, let’s go over each operator and see how they work through practical examples.

AND Operator (`&`)

The AND operator compares the bits of two numbers and returns 1 only if both corresponding bits are 1. Otherwise, it returns 0.

Here’s an example:

int a = 5; // In binary: 0101
int b = 3; // In binary: 0011
int result = a & b; // Bitwise AND

How does it work?

  • The number 5 in binary is: `0101`
  • The number 3 in binary is: `0011`

When you compare the corresponding bits, you get `0001`, which in decimal is 1.

example AND operator

So, `a & b` returns 1.

1

OR Operator (`|`)

The OR operator returns 1 if at least one of the two bits is 1, and returns 0 only if both bits are 0.

int a = 5; // In binary: 0101
int b = 3; // In binary: 0011
int result = a | b; // Bitwise OR

Here’s how it works:

  • 5 in binary is: `0101`
  • 3 in binary is: `0011`

When you compare the bits, you get `0111`, which is 7 in decimal.

example OR operator

So, the result is 7.

7

XOR Operator (`^`)

The XOR operator returns 1 if the corresponding bits are different. If both bits are the same, it returns 0.

int a = 5; // In binary: 0101
int b = 3; // In binary: 0011
int result = a ^ b; // Bitwise XOR

Here’s what happens:

  • 5 in binary is: `0101`
  • 3 in binary is: `0011`

When you compare the bits, you place a 1 if the bits are different. If they are the same, you write 0. This gives you `0110`, which in decimal is 6.

example XOR operator

So, the result is 6.

6

NOT Operator (`~`)

The NOT operator inverts all the bits: 1s become 0s, and 0s become 1s.

int a = 5; // In binary: 0101
int result = ~a;  // Bitwise NOT

The number 5 in binary is: `0101`

Inverting all the bits gives you `1010`.

example NOT

In Java, this result is treated as a negative number due to the signed number representation (Two's Complement), which makes the result -6.

-6

Explanation: Typically, numbers are stored as 32-bit or 64-bit values in binary. For instance, the number 5 in 32-bit format looks like this:

00000000 00000000 00000000 00000101

When you apply the NOT (`~`) operator in Java, all the bits are flipped. Inverting all the bits of the number 5 gives:

11111111 11111111 11111111 11111010

In Java, when the most significant bit is 1, the number is interpreted as negative (this is a feature of Two's Complement). To get the decimal value, you flip the bits again, then add 1, while keeping the negative sign.

00000000 00000000 00000000 00000110

The result is 6, so the final value is -6.

Left Shift (`<<`)

The left shift operator shifts all bits to the left by a specified number of positions, filling the new bits on the right with 0s.

int a = 5; // In binary: 0101
int result = a << 1;   // Shift left by 1 position

The number 5 in binary is: `0101`.

Shifting the bits to the left by one position gives you: `1010`, which is 10 in decimal.

example left shift

10

Every time you perform a left shift, it's like multiplying the number by 2.

You can also shift by more than one position. For example, `a<<2` shifts the bits left by two positions.

Right Shift (`>>`)

The right shift operator does the opposite: it shifts the bits to the right by a specified number of positions, filling the new bits on the left with the sign bit (0 for positive numbers, 1 for negative numbers).

int a = 5; // In binary: 0101
int result = a >> 1;   // Shift right by 1 position

The number 5 in binary is: `0101`

Since 5 is positive, the empty spaces on the left are filled with 0s, while the bits on the right are discarded.

example right shift

Shifting the bits right by one position gives you `0010`, which is 2 in decimal.

2

Unsigned Right Shift (`>>>`)

This operator shifts the bits to the right by a specified number of positions, filling the new bits on the left with 0s.

Unlike the regular right shift, here the new bits are always filled with 0s, regardless of the number's sign.

int a = 5; // In binary: 0101
int result = a >>> 1;   // Unsigned right shift by 1 position

Again, the number 5 in binary is `0101` and shifting to the right by one position gives `0010`, which is 2 in decimal.

example unsigned right shift

2

Right shift with assignment (`>>=`)

The `>>=` operator combines a right shift (`>>`) with assignment, meaning it shifts the bits to the right and assigns the result directly to the same variable. It works just like `>>`, but with the added step of storing the result in the original variable.

int a = 5; // In binary: 0101
a >>= 1;   // Shifts the bits right by 1 position and assigns the result to 'a'

Here, the bits are shifted one position to the right, and the result is stored back in the variable 'a'.

2

This operator is handy when you want to shift bits and assign the result to the same variable without needing a separate one.

Left shift with assignment (`<<=`)

The `<<=` operator combines a left shift (`<<`) with assignment. It functions similarly to `>>=`, but shifts the bits in the opposite direction.

int a = 5; // In binary: 0101
a <<= 1;   // Shifts the bits left by 1 position and assigns the result to 'a'

In this case, the bits are shifted one position to the left, with the result directly assigned back to the variable 'a'.

2

Why Use Bitwise Operators?

These operators are often used when working with data at a low level, such as in embedded systems or situations where speed is critical. Manipulating bits directly is extremely efficient.

For instance, if you need to check a specific bit in a number, bitwise operators are much faster than performing arithmetic operations.

Imagine you want to check whether a number is odd or even. Instead of using the modulus operator `%`, a quicker method is to check the least significant bit (the rightmost one) with a bitwise AND.

boolean isOdd = (a & 1) != 0;

If the least significant bit is 1, the number is odd!

In conclusion, bitwise operators might seem complex at first, but they are incredibly useful in many practical applications.

I hope this lesson has given you a clearer understanding. Next time you code in Java, you might think of numbers as a series of tiny switches you can flip on and off!




Report a mistake or post a question




FacebookTwitterLinkedinLinkedin