Chapter 20: Bitwise Operators

Part 1: What Are Bits and Why Should You Care?

Before we talk about the operators, we need to understand what they operate on: bits.

bit is the most basic unit of information in computing. It can only have one of two values: 0 or 1. This corresponds to “off/on,” “false/true,” or “low voltage/high voltage” in a circuit.

Everything you see on your computer—text, images, videos, programs—is ultimately represented as a long sequence of bits. Numbers are represented in binary (base-2), using only 0s and 1s.

For example, the decimal number 13 is represented in binary as 1101.

  • 1 (in the 8’s place) = 8

  • 1 (in the 4’s place) = 4

  • 0 (in the 2’s place) = 0

  • 1 (in the 1’s place) = 1

  • Total: 8 + 4 + 0 + 1 = 13

Bitwise operators allow us to directly manipulate these individual bits. Why would we want to do that?

  1. Performance: Bitwise operations are extremely fast because they map directly to CPU instructions.

  2. Memory Efficiency: You can pack multiple true/false flags into a single number (each flag is one bit), saving immense amounts of memory.

  3. Systems Programming: When working with hardware, device drivers, network protocols, or file permissions, you often need to read or set individual bits.

  4. Graphics and Cryptography: Many algorithms in these fields rely on bitwise manipulations.

Part 2: Meet the Family: The Bitwise Operators

Let’s introduce the six primary bitwise operators. We’ll use Python for our examples, as its integer type is unbounded and perfect for demonstration. The symbols are the same in many languages like C, C++, Java, and JavaScript.

Operator Name Description
& AND Performs a logical AND on each pair of corresponding bits. Result bit is 1 only if both bits are 1.
| OR Performs a logical OR on each pair of corresponding bits. Result bit is 1 if at least one bit is 1.
^ XOR (exclusive OR) Performs a logical exclusive OR. Result bit is 1 if the bits are different.
~ NOT (complement) Flips all the bits. 0 becomes 1, 1 becomes 0. (Be careful with signed integers!)
<< Left Shift Shifts all bits to the left by a specified number of positions. Zeros are shifted in on the right.
>> Right Shift Shifts all bits to the right by a specified number of positions. The behavior for the leftmost bits depends on the language/signedness.

Part 3: Detailed Exploration with Examples

Let’s explore each operator with concrete binary representations. We’ll use relatively small numbers so we can easily visualize the bits. In a real computer, integers are typically 32 or 64 bits, but the principle is the same.

We’ll use two numbers for our examples:

  • a = 13 (binary 1101)

  • b = 7 (binary 0111)

To make them the same length, we can think of them as 4-bit numbers.

1. Bitwise AND (&)

The AND operator compares each bit. The result bit is 1 only if both corresponding bits are 1. Otherwise, it’s 0.

Think of it as the strict gatekeeper: both inputs must be 1 for the output to be 1.

python

Let’s do the bit-by-bit calculation:

Bit Position 8’s place (2³) 4’s place (2²) 2’s place (2¹) 1’s place (2⁰)
a (13) 1 1 0 1
b (7) 0 1 1 1
a & b 0 1 0 1

The result binary is 0101, which is decimal 5.

Output:

text

Common Use: Masking. You can use AND to check if a specific bit is set. For example, to check if the 2’s place bit (value 4) is set in a, you’d do a & 4. If the result is non-zero, the bit is set.

2. Bitwise OR (|)

The OR operator compares each bit. The result bit is 1 if at least one of the corresponding bits is 1. It’s only 0 if both bits are 0.

Think of it as the generous gatekeeper: any input of 1 results in an output of 1.

python

Bit-by-bit calculation:

Bit Position 8’s place 4’s place 2’s place 1’s place
a (13) 1 1 0 1
b (7) 0 1 1 1
a | b 1 1 1 1

The result binary is 1111, which is decimal 15.

Output:

text

Common Use: Setting bits. You can use OR to turn specific bits on. For example, to set the 2’s place bit in a number, you’d do number | 4.

3. Bitwise XOR (^) – Exclusive OR

The XOR operator is the “different” detector. The result bit is 1 if the corresponding bits are different (one is 0 and the other is 1). It’s 0 if they are the same (both 0 or both 1).

This is a very powerful operator with many clever applications.

python

Bit-by-bit calculation:

Bit Position 8’s place 4’s place 2’s place 1’s place
a (13) 1 1 0 1
b (7) 0 1 1 1
a ^ b 1 0 1 0

The result binary is 1010, which is decimal 10.

Output:

text

Common Uses:

  • Toggling bits: x ^ mask will flip the bits where the mask has 1s.

  • Swapping values without a temporary variable: a ^= b; b ^= a; a ^= b is a classic (though now mostly a curiosity).

  • Simple encryption: XOR with a key is a basic building block of many ciphers.

4. Bitwise NOT (~) – Complement

The NOT operator is a unary operator (it works on a single number). It simply flips every bit: 0 becomes 1, and 1 becomes 0.

This one requires careful explanation because of how computers represent negative numbers using two’s complement. In Python, integers have unlimited precision, but the principle applies.

python

Output:

text

Wait, why -14? Let’s think in 4 bits for simplicity (though real computers use more).

  • 13 in 4 bits is 1101.

  • ~13 in 4 bits would be 0010 (flip all bits). That’s 2, right? Why does Python say -14?

Because Python integers are signed and have unlimited precision. The ~ operator is defined as ~x == -x - 1. So ~13 is -13 - 1 = -14.

In a language with fixed-width integers (like C), ~13 on an 8-bit integer would be:

  • 13 = 00001101

  • ~13 = 11110010

  • In an unsigned 8-bit integer, 11110010 is 242.

  • In a signed 8-bit integer (using two’s complement), 11110010 is -14.

So, Python’s result is consistent with the two’s complement interpretation. The ~ operator gives you the bitwise complement, which is interpreted as a signed integer.

5. Left Shift (<<)

The left shift operator shifts all the bits of a number to the left by a specified number of positions. Zeros are shifted in from the right. Bits shifted off the left end are discarded (or in Python, they just keep extending the number).

In effect, left shifting by n is the same as multiplying by 2ⁿ (for positive integers, until you run out of bits).

python

Output:

text

Common Use: Fast multiplication by powers of two. CPU bit shifts are much faster than general multiplication.

6. Right Shift (>>)

The right shift operator shifts all the bits to the right by a specified number of positions. For positive numbers, zeros are shifted in from the left.

In effect, right shifting by n is the same as floor division by 2ⁿ (for positive integers).

python

Output:

text

Common Use: Fast division by powers of two. Also used to extract specific bits from a number.

Part 4: Practical, Real-World Examples

Example 1: Using Bit Flags (Permissions System)

This is one of the most common uses of bitwise operators. Imagine a file system with permissions: Read, Write, and Execute. Instead of storing three separate booleans, we can store them as three bits in a single integer.

python

Example 2: Checking if a Number is Even or Odd (The Fast Way)

We already know number % 2 == 0 works. But bitwise is even faster. The least significant bit (the rightmost bit) is 1 for odd numbers and 0 for even numbers.

python

Example 3: Swapping Two Variables Without a Temporary Variable

This is a classic trick using XOR. It’s efficient and fun, though not always recommended for readability.

python

Example 4: Finding the Only Non-Repeating Element in an Array

Given an array where every element appears twice except one, find that single element. XOR is perfect for this because x ^ x = 0.

python

Example 5: Simple Color Manipulation (RGB)

In graphics, colors are often packed into a single integer. For example, a 24-bit RGB color might have 8 bits for Red, 8 for Green, and 8 for Blue.

python

Summary: The Bitwise Operator Philosophy

  • Bitwise operators operate on the individual binary bits of integers.

  • They are the lowest-level data manipulation tools available in high-level languages.

  • & (AND) is a mask. It lets you check or clear specific bits.

  • | (OR) is a setter. It lets you turn specific bits on.

  • ^ (XOR) is a toggler. It lets you flip bits and detect differences.

  • ~ (NOT) is a flipper. It inverts all bits.

  • << (Left Shift) is a fast multiplier by powers of two.

  • >> (Right Shift) is a fast divider (floor division) by powers of two.

  • They are essential for performancememory efficiency, and systems programming.

  • Common applications include: permission systems, flags, color packing, cryptography, network protocols, and graphics.

Mastering bitwise operators is like learning to work with the atoms of your data. It’s a powerful skill that opens up a new level of control and efficiency in your programming, especially when you need to squeeze every last drop of performance out of your code or interact directly with hardware.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *