Bitwise Operators in C++

·

Understanding bitwise operators in C++ is essential for developers working on performance-critical applications, embedded systems, or competitive programming. These operators allow direct manipulation of data at the binary level, enabling efficient computation and compact code. In this guide, we’ll explore all six bitwise operators available in C++, how they work, and practical use cases with clear examples.

👉 Discover powerful programming techniques that boost your coding efficiency—explore more now.

What Are Bitwise Operators?

In C++, bitwise operators perform operations on integer values at the bit level. Instead of treating integers as whole numbers, these operators interpret them as sequences of binary digits (bits). This low-level control makes bitwise operations extremely fast and useful in scenarios where memory and speed are crucial.

C++ supports six primary bitwise operators:

Each of these plays a unique role in manipulating bits for tasks like flag management, data compression, encryption, and hardware interaction.

1. Bitwise AND Operator (&)

The bitwise AND operator compares each bit of two integers. The resulting bit is set to 1 only if both corresponding bits are 1; otherwise, it’s 0.

This operator is commonly used to check if specific bits are set, such as verifying permissions or status flags.

Example: Using & Operator

Let’s compute 7 & 4:

  111  (7 in binary)
& 100  (4 in binary)
-----
  100  (result = 4)

Only the third bit from the right is 1 in both numbers, so the result is 4.

👉 Master low-level programming skills that give you an edge—learn how today.

2. Bitwise OR Operator (|)

The bitwise OR operator sets the resulting bit to 1 if at least one of the corresponding bits is 1. It’s often used to set specific bits in a register or flag variable.

Example: Using | Operator

Compute 7 | 4:

  111  (7)
| 100  (4)
-----
  111  (result = 7)

Since at least one bit is 1 in each position, the output remains 7.

3. Bitwise XOR Operator (^)

The bitwise XOR (exclusive OR) operator returns 1 when the corresponding bits are different and 0 when they are the same. This property makes XOR ideal for toggling bits, finding unique elements, or simple encryption.

Example: Using ^ Operator

Compute 7 ^ 4:

  111
^ 100
-----
  011  (result = 3)

Bits differ in the first and second positions, giving us 3.

Practical Use Case: Swapping Without a Temporary Variable

int a = 5, b = 3;
a = a ^ b;
b = a ^ b;
a = a ^ b;
// Now a = 3, b = 5

XOR’s self-inverting nature allows clean swaps without extra memory.

4. Bitwise NOT Operator (~)

The bitwise NOT operator is unary—it operates on a single operand. It flips every bit: 0 becomes 1, and 1 becomes 0.

Be cautious: due to two's complement representation, ~n equals -(n + 1) for signed integers.

Example: Using ~ Operator

Apply NOT to 4:

~ 100  (4 in binary)
= 011  (which is 3 in unsigned context)

However, in a signed integer context:

int b = 4;
std::cout << ~b; // Output: -5

Because ~4 = -5 under two's complement arithmetic.

5. Left Shift Operator (<<)

The left shift operator moves all bits to the left by a specified number of positions, filling vacated bits with zeros. Each left shift effectively multiplies the number by 2^n, where n is the number of shifts.

Example: Using << Operator

Shift 5 left by 2 positions:

5 << 2
=> 101 << 2
=> 10100 (binary) = 20 (decimal)

This is equivalent to 5 * 2² = 5 * 4 = 20.

Left shifting is faster than multiplication by powers of two and is widely used in performance-sensitive code.

6. Right Shift Operator (>>)

The right shift operator moves bits to the right by a given number of positions. For unsigned types, vacant positions are filled with zeros. For signed types, the sign bit is preserved (arithmetic shift).

Each right shift divides the number by 2^n, discarding remainder.

Example: Using >> Operator

Shift 16 right by 2 positions:

16 >> 2
=> 10000 >> 2
=> 00100 (binary) = 4 (decimal)

Same as 16 / 2² = 16 / 4 = 4.

This operation is faster than division and commonly used in fixed-point arithmetic or optimization routines.

Complete Code Example

Here’s a full C++ program demonstrating all bitwise operators:

#include <iostream>
using namespace std;

int main() {
    int a = 7, b = 4;

    cout << "AND: " << (a & b) << endl;         // Output: 4
    cout << "OR: " << (a | b) << endl;          // Output: 7
    cout << "XOR: " << (a ^ b) << endl;         // Output: 3
    cout << "NOT b: " << (~b) << endl;          // Output: -5
    cout << "Left Shift: " << (a << 2) << endl; // Output: 28 (7*4)
    cout << "Right Shift: " << (b >> 1) << endl;// Output: 2 (4/2)

    return 0;
}

Output:

AND: 4
OR: 7
XOR: 3
NOT b: -5
Left Shift: 28
Right Shift: 2

Note: The left shift uses a << 2 (7 << 2 = 28), not 5 << 2, aligning with variable usage.

Frequently Asked Questions (FAQs)

Q: What are the main uses of bitwise operators in real-world programming?
A: They're widely used in embedded systems, cryptography, compression algorithms, graphics programming, and optimizing mathematical computations.

Q: Can bitwise operators be applied to floating-point numbers?
A: No. Bitwise operators work only on integral types like int, char, short, etc. Floating-point numbers must be accessed via type punning or unions, which can be unsafe.

Q: Is left shift always equivalent to multiplication by two?
A: Yes, for non-negative numbers within range. However, shifting beyond the bit width causes undefined behavior, and signed negative values may not behave predictably.

Q: How does right shift handle negative numbers?
A: In most compilers, right shift on signed negative integers performs an arithmetic shift, preserving the sign bit. This ensures -8 >> 1 results in -4, not a large positive number.

Q: Why use XOR to toggle a bit?
A: Because XOR has the property that (x ^ y) ^ y = x. Toggling twice returns the original value—perfect for switches or flags.

Q: Are bitwise operations faster than arithmetic ones?
A: Generally yes—especially on older or resource-constrained hardware. Modern compilers often optimize multiplication/division by powers of two into shifts automatically.


👉 Unlock advanced programming strategies that make your code faster and smarter—click here to dive deeper.