skip to content

Bitwise & Shift Operators

Bitwise and, or, xor and complement, plus the three shifts — and the fact that >>> exists because Java has no unsigned integer types. Interviewers also probe the shift-distance masking rule, which is why x << 32 does nothing to an int.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What do Java's bitwise operators &, |, ^, and ~ do, and how do they differ from the logical operators && and ||?

level: juniorimportance: must knowfreq 62%

answer

  1. & both, | either, ^ differ, ~ flip
  2. ~x == -x-1 (two's complement)
  3. &&/|| short-circuit, & / | always evaluate
  4. bitwise on ints, logical on booleans
  5. precedence trap: (x & 1) == 0

basics

~20 s

&, |, ^ compare two numbers bit by bit (AND, OR, XOR); ~ flips every bit. They work on whole numbers. && and || work on true/false, only look at the second value if needed, and give back true or false.

solid answer

~40 s

The bitwise operators act on the individual binary digits of integer types. & sets a result bit when both input bits are 1; | when either is 1; ^ (XOR) when exactly one is 1; ~ is unary and inverts every bit. They return an integer. The logical &&/|| operate on booleans, return a boolean, and short-circuit: && stops if the left side is false, || stops if the left side is true, so the right operand may never run. Note & and | also work on two booleans as non-short-circuiting logical operators (both sides always evaluated), which matters when the right side has side effects or you want to avoid branching. Use bitwise ops for flags, masks, and low-level math; use logical ops for control flow.

code

java · 10 lines
java
int a = 0b0101; // 5
int b = 0b0110; // 6
System.out.println(a & b); // 4  (both bits set)
System.out.println(a | b); // 7  (either bit set)
System.out.println(a ^ b); // 3  (bits that differ)
System.out.println(~a);    // -6 (~x == -x-1)

// precedence trap: parenthesize
boolean even = (a & 1) == 0; // correct
// boolean wrong = a & 1 == 0; // would not compile as intended

go deeper

for a junior

Knows & is AND, | is OR, ^ is XOR, ~ is NOT, and can compute a small example on paper.

for a middle

Distinguishes bitwise from logical && / ||, explains short-circuiting, and knows the precedence pitfall.

for a senior

Explains two's complement so ~x = -x-1, the int promotion of byte/short/char, and when non-short-circuiting & / | on booleans is the right choice.

for a principal

Can reason about these in performance-sensitive or branch-free code, API flag-design tradeoffs, and teaches the precedence/promotion gotchas to the team.

## What is a bit and a binary number Computers store integers in **binary**: a sequence of 0s and 1s called **bits**. A Java `int` is 32 bits wide; a `long` is 64 bits. The value 5 is `...0000 0101`, because 5 = 4 + 1 = 2^2 + 2^0. ## Bitwise operators act on each bit position independently A **bitwise operator** takes two numbers, lines up their bits column by column, and produces an output bit for each column. - **AND (`&`)** — output bit is 1 only when *both* input bits are 1. `5 & 6` = `0101 & 0110` = `0100` = 4. - **OR (`|`)** — output bit is 1 when *at least one* input bit is 1. `5 | 6` = `0101 | 0110` = `0111` = 7. - **XOR (`^`, exclusive-or)** — output bit is 1 when the two input bits *differ*. `5 ^ 6` = `0101 ^ 0110` = `0011` = 3. - **NOT (`~`)** — the only *unary* one (one operand). It flips every bit. Because Java uses **two's complement** (the standard way to represent negative numbers), `~x` always equals `-x - 1`. So `~5` = -6. The result type is `int` (or `long` if either operand is `long`); operands narrower than `int` (`byte`, `short`, `char`) are promoted to `int` first. ## Logical operators &&, || are different `&&` and `||` operate on **booleans** (`true`/`false`) and return a boolean. Their defining feature is **short-circuiting**: `a && b` does not evaluate `b` if `a` is already `false` (the answer must be false); `a || b` does not evaluate `b` if `a` is `true`. This lets you write safe guards like `if (s != null && s.length() > 0)` — the length call never runs on a null. ## The overlap: & and | on booleans Confusingly, `&` and `|` *also* accept two booleans. There they act as **non-short-circuiting** logical AND/OR: both sides are *always* evaluated. You'd choose them only when you specifically want the side effect of the right operand to always run, or to avoid a branch. `^` on two booleans means 'exactly one is true'. ## When to use which - Bitwise (`& | ^ ~`) on integers: flag sets, bit masks, hashing, parsing binary formats, fast arithmetic. - Logical (`&& ||`) on booleans: ordinary control flow and null/bounds guards. ## Common pitfall: operator precedence `&`, `^`, `|` have **lower** precedence than the comparison operators `==`, `<`, etc. So `x & 1 == 0` parses as `x & (1 == 0)` — a type error or wrong result. Always parenthesize: `(x & 1) == 0`.

  • Why does x & 1 == 0 not test whether x is even?
    Because == binds tighter than &, so it parses as x & (1 == 0), a boolean compared/anded against an int — a compile error (or wrong logic). You must write (x & 1) == 0.
  • How can XOR swap two ints without a temp variable?
    a ^= b; b ^= a; a ^= b; — each step XORs in the other value; after three steps the values are swapped. It's a curiosity, not recommended over a temp in real code.

saying these in an interview costs you the question

  • Saying & and && are interchangeable
  • Thinking ~ returns the absolute value or just negates the sign bit
  • Claiming ^ is exponentiation (it's XOR; Java has no power operator)
  • Forgetting that & / | on booleans do NOT short-circuit

context

open as a page

Explain Java's three shift operators <<, >>, and >>> and how they differ.

level: middleimportance: must knowfreq 58%

basics

~20 s

<< moves bits left (filling zeros on the right), multiplying by powers of two. >> moves bits right keeping the sign (negatives stay negative). >>> moves bits right but always fills zeros on the left, ignoring the sign.

open as a page

How do you use bitwise operators to implement a set of boolean flags packed into a single int, and what operations set, clear, toggle, and test a flag?

level: middleimportance: should knowfreq 48%

basics

~20 s

Give each flag its own bit (1, 2, 4, 8...). Use | to turn a flag on, & with the mask to test it, &~ to turn it off, and ^ to flip it. One int can hold up to 32 flags.

open as a page

In Java, what does an expression like 1 << 33 evaluate to, and why? Explain shift-distance modulo behavior.

level: seniorimportance: should knowfreq 40%

basics

~20 s

The shift amount is reduced using a remainder. For int it's the amount mod 32, for long it's mod 64. So 1 << 33 is the same as 1 << 1 = 2, not 0.

open as a page

What surprising results arise from integer promotion and sign extension when applying bitwise and shift operators to byte, short, and char, and how do you handle them safely?

level: seniorimportance: should knowfreq 35%

basics

~20 s

byte, short, and char are widened to int before any bitwise or shift operation. A negative byte gets its high bits filled with 1s (sign extension), so masking with & 0xFF is often needed to get the value you expect.

open as a page