Bitwise Operators in Java

  • Last Updated: September 20, 2023
  • By: javahandson
  • Series
img

Bitwise Operators in Java

Bitwise operators in Java work on the individual bits of a number. They let you combine, flip, and shift bits directly. This guide explains each one in plain English, with truth tables and runnable examples.

1. Introduction

Most of the time, you work with whole numbers in Java. You add them, compare them, and print them. You never think about the bits inside.

But every number is really a row of bits, each a zero or a one. Bitwise operators let you reach in and work with those bits directly. They combine bits, flip them, or slide them left and right.

Many developers skip these operators, since they feel rare and low-level. Yet they power flags, masks, and fast math under the hood. Even if you rarely write them, you will read them, so the rules are worth knowing.

1.1 What This Article Covers

We start with bits themselves, then meet each operator. Here is the plan:

  • A quick refresher on bits and binary numbers
  • The six bitwise operators and what each one does
  • AND, OR, and XOR, each with a truth table and an example
  • The NOT operator, and why its answer looks negative
  • The shift operators that slide bits left and right
  • Common mistakes, a real-world use, and interview questions

You need only a basic grasp of numbers to follow along. We explain the binary as we go.

2. What Are Bitwise Operators?

A bitwise operator works on the bits of a number, one bit at a time. It does not treat the number as a single whole. Instead, it looks at each bit on its own.

To use them, you picture a number in binary. Then the operator applies a simple rule to each bit. The rows of bits line up, and the rule runs down the columns.

2.1 A Quick Look at Bits

A bit is a single zero or one. A number is just a row of these bits. For example, the number 6 in binary is 110.

Each position stands for a power of two. Reading 110 from the right, you get 0, then 2, then 4. Add the ones together, and 4 plus 2 gives 6.

Java stores an int using 32 bits. In the examples below, we show only the last few bits to keep things short. The idea holds the same for the full width.

2.2 The Six Bitwise Operators

Java gives you six bitwise operators. This table lists them with their jobs:

Operator Name What It Does
& Bitwise AND Gives 1 only when both bits are 1
| Bitwise OR Gives 1 when either bit is 1
^ Bitwise XOR Gives 1 when the two bits differ
~ Bitwise NOT Flips every bit to its opposite
<< Shift left Slides all bits to the left
>> Shift right Slides all bits to the right

The first four combine or flip bits. The last two slide bits sideways. We will meet each one in its own section.

3. The Bitwise AND Operator

The AND operator uses the ampersand symbol, &. It works on two numbers. For each pair of bits, it gives 1 only when both bits are 1.

Think of it as a strict gate. Both inputs must be on to let a 1 through. If either bit is 0, the result is 0.

3.1 The Truth Table

This table shows the AND rule for every pair of bits:

a b a & b
0 0 0
0 1 0
1 0 0
1 1 1

Only the last row gives a 1. Every other pairing gives a 0. That single 1 sums up the whole operator.

3.2 Working Out 7 AND 6

Let us apply AND to 7 and 6. First, write both in binary, then compare each column:

  7 = 1 1 1
  6 = 1 1 0
-----------
7 & 6 = 1 1 0  = 6

Line up the bits and run AND down each column. The first two columns have two 1s, so they give 1. A 0 sits in the last column, so it gives 0. That leaves 110, which is 6.

3.3 A Handy Use of AND

AND gives us a quick even-or-odd test. The last bit of any number decides this. An odd number ends in 1, and an even number ends in 0.

So we AND the number with 1. This keeps only the last bit and drops the rest. A result of 1 means odd, and 0 means even:

int number = 7;

if ((number & 1) == 1) {
    System.out.println(number + " is odd");
} else {
    System.out.println(number + " is even");
}

// Output:
// 7 is odd

This shows the real power of AND. You can mask off every bit except the ones you care about.

4. The Bitwise OR Operator

The OR operator uses a single pipe symbol, |. It also works on two numbers. For each pair of bits, it gives 1 when either bit is 1.

Picture a relaxed gate this time. Just one input needs to be on. The result is 0 only when both bits are 0.

4.1 The Truth Table

This table shows the OR rule for every pair of bits:

a b a | b
0 0 0
0 1 1
1 0 1
1 1 1

Only the first row gives a 0. Every other pairing gives a 1. So OR is the mirror image of AND in a way.

4.2 Working Out 7 OR 6

Now apply OR to the same two numbers. Write them in binary and compare each column:

  7 = 1 1 1
  6 = 1 1 0
-----------
7 | 6 = 1 1 1  = 7

Run OR down each column. Every column has at least one 1, so each result is 1. The answer 111 is 7, which shows how OR gathers up every bit that is switched on.

5. AND and OR in One Program

Let us see both operators in real Java code. This program computes 7 AND 6, then 7 OR 6:

package com.java.handson.operators;

public class BitwiseAndOr {
    public static void main(String[] args) {

        int a = 7;
        int b = 6;

        int andResult = a & b;
        System.out.println("7 & 6 = " + andResult);

        int orResult = a | b;
        System.out.println("7 | 6 = " + orResult);
    }
}

// Output:
// 7 & 6 = 6
// 7 | 6 = 7

5.1 Reading the Output

The AND line prints 6, just as our column math showed. Both numbers share the top two bits, so those survive. The bottom bit differs, so it drops to 0.

The OR line prints 7 for the same reason in reverse. Every column had at least one 1, so the result fills all three bits.

6. The Bitwise XOR Operator

XOR stands for exclusive OR. It uses the caret symbol, ^. For each pair of bits, it gives 1 only when the two bits differ.

Think of it as a difference detector. Same bits give 0, and different bits give 1. This makes XOR great for spotting changes.

6.1 The Truth Table

This table shows the XOR rule for every pair of bits:

a b a ^ b
0 0 0
0 1 1
1 0 1
1 1 0

The two matching rows give 0. The two mismatched rows give 1. So XOR asks a simple question: are these bits different?

6.2 Working Out 7 XOR 6

Apply XOR to 7 and 6. Compare each column and mark where the bits differ:

  7 = 1 1 1
  6 = 1 1 0
-----------
7 ^ 6 = 0 0 1  = 1

The first two columns match, so they give 0. A difference in the last column gives 1. That leaves 001, which is just 1.

int a = 7;
int b = 6;

System.out.println("7 ^ 6 = " + (a ^ b)); // Output: 7 ^ 6 = 1

7. The Bitwise NOT Operator

The NOT operator uses the tilde symbol, ~. It works on just one number, so it is a unary operator. It flips every bit to its opposite.

Each 1 becomes a 0, and each 0 becomes a 1. This sounds simple, yet the answer can surprise you. The reason is the sign bit.

7.1 Flipping Every Bit

Take the number 6 and flip its bits. Using 8 bits for clarity, here is the result:

    6 = 0 0 0 0 0 1 1 0
   ~6 = 1 1 1 1 1 0 0 1

Every 0 turned into a 1, and every 1 turned into a 0. You might expect a plain positive number. Instead, Java prints negative seven.

7.2 Why the Answer Is Negative

The leftmost bit is the sign bit. When it is 1, the number is negative. After the flip, that bit became 1, so the answer went negative.

Java reads negative numbers with two’s complement. The leftmost bit carries a negative weight, and the rest add on top. Here is the sum for our flipped bits:

1 1 1 1 1 0 0 1
= -128 + 64 + 32 + 16 + 8 + 0 + 0 + 1
= -7

So ~6 comes out as -7. A handy shortcut also works: ~n always equals -n - 1. Try it, and the same answer of -7 appears.

int b = 6;

System.out.println("~6 = " + (~b)); // Output: ~6 = -7

8. The Shift Operators

The shift operators slide bits sideways. One number gives the bits, and a second number says how far to move them. Java has three shift operators in all.

Shifting is a fast way to multiply or divide by powers of two. A left shift doubles the value each step, and a right shift halves it.

8.1 Shift Left

The left shift, <<, moves every bit to the left. Empty spots on the right fill with zeros. Let us shift 6 left by two places:

     6 = 0 0 0 0 0 1 1 0
6 << 2 = 0 0 0 1 1 0 0 0  = 24

The two 1 bits slid two places to the left, and two fresh zeros filled the right side. The new pattern is 24, which is 6 times 4. Each left shift by one doubles the number.

8.2 Shift Right

The right shift, >>, moves every bit to the right. Bits that fall off the right edge are lost. Let us shift 24 back to the right by two:

     24 = 0 0 0 1 1 0 0 0
24 >> 2 = 0 0 0 0 0 1 1 0  = 6

The bits slid two places to the right, and we land back on 6. That fits, since a right shift by two divides by four. A left shift and a right shift by the same amount undo each other for positive numbers.

int a = 6;

int left = a << 2;
System.out.println("6 << 2 = " + left);  // Output: 6 << 2 = 24

int right = left >> 2;
System.out.println("24 >> 2 = " + right); // Output: 24 >> 2 = 6

8.3 The Unsigned Right Shift

Java adds a third shift, the unsigned right shift, >>>. The plain >> keeps the sign bit as it shifts. The >>> always brings in zeros from the left.

For a positive number, both give the same answer. The difference shows only with negative numbers, where >>> fills the top with zeros and turns the result positive.

int n = -8;

System.out.println("-8 >> 1  = " + (n >> 1));   // Output: -8 >> 1  = -4
System.out.println("-8 >>> 1 = " + (n >>> 1));  // Output: -8 >>> 1 = 2147483644

9. Common Mistakes and Pitfalls

Bitwise code trips up beginners in a few spots. Watch out for these three.

9.1 Mixing Up & With Logical AND

A single & is bitwise AND, but a double && is logical AND. They look alike, yet they behave very differently. One works on bits, and the other on boolean conditions.

The logical form also short-circuits, while the bitwise form does not. So mixing them up can change how your code runs. Pick the one that matches your intent.

9.2 Forgetting the Sign Bit

The NOT operator and the right shift both care about the sign bit. Flip the top bit, and a positive number turns negative. This surprises people who expect a plain flip.

Keep the sign bit in mind whenever you flip or shift. If you want zeros from the left, reach for >>>. That small choice avoids a confusing negative result.

9.3 Overshifting a Number

Shifting too far can wipe out your bits. Push them past the edge, and they fall away for good. An int holds only 32 bits, so a big shift leaves little behind.

Java also wraps the shift amount for an int. It uses only the low 5 bits of the count, so a shift by 32 acts like a shift by 0. Keep shift counts small and sensible.

10. A Practical Walkthrough

Let us tie the ideas into one real example. We will use bits to store a set of permissions in a single number.

10.1 Permission Flags

Each permission gets its own bit. We use OR to switch a permission on, and AND to test one:

package com.java.handson.operators;

public class Permissions {
    public static void main(String[] args) {

        int READ = 1;   // 001
        int WRITE = 2;  // 010
        int EXEC = 4;   // 100

        // turn on READ and WRITE with OR
        int access = READ | WRITE;
        System.out.println("Access value : " + access);

        // test each permission with AND
        System.out.println("Can read?  " + ((access & READ) != 0));
        System.out.println("Can write? " + ((access & WRITE) != 0));
        System.out.println("Can exec?  " + ((access & EXEC) != 0));
    }
}

// Output:
// Access value : 3
// Can read?  true
// Can write? true
// Can exec?  false

10.2 Reading the Result

The OR step joins READ and WRITE into one value. Their bits, 001 and 010, combine into 011, which is 3. So a single number now holds two settings.

Each test uses AND with one flag. When the shared bit is on, the result is not zero, so the check reads true. The EXEC bit was never set, so its test reads false. One int can hold up to 32 such flags, which is why they show up in file systems and game engines.

11. Interview Questions

Q: What are bitwise operators in Java?

A: They are operators that work on the individual bits of a number. Java has six: AND, OR, XOR, NOT, shift left, and shift right. Each one combines, flips, or slides bits.

Q: What is the difference between & and && in Java?

A: A single & is the bitwise AND, which works on bits. A double && is the logical AND, which works on boolean conditions and short-circuits. Use & for bits and && for true-or-false tests.

Q: Why does ~6 give -7 in Java?

A: The NOT operator flips every bit, including the sign bit. That makes the number negative under two’s complement. A quick rule is that ~n always equals -n – 1, so ~6 is -7.

Q: What does the left shift operator do?

A: It slides all the bits to the left and fills the right with zeros. Each shift by one doubles the number. So a left shift is a fast way to multiply by a power of two.

Q: What is the difference between >> and >>>?

A: The signed right shift, >>, keeps the sign bit as it shifts. The unsigned right shift, >>>, always brings in zeros from the left. They match for positive numbers but differ for negative ones.

12. Conclusion

Let us wrap up what we covered. Bitwise operators in Java work on the bits inside a number. The six of them are AND, OR, XOR, NOT, shift left, and shift right.

We saw how AND, OR, and XOR combine two numbers bit by bit. Then NOT flipped every bit, and we learned why that turns a value negative. We also watched the shifts double and halve a number by sliding bits.

These operators feel low-level, but the rules are simple. Draw the bits in columns, apply the rule, and read the answer. With a little practice, bit-level code stops looking scary and starts looking neat.

Further Reading

Leave a Comment