What is (x & 1) and (x >>= 1)?

Learn what is (x & 1) and (x >>= 1)? with practical examples, diagrams, and best practices. Covers c++, bit-manipulation, bitwise-operators development techniques with visual explanations.

Understanding Bitwise Operations: x & 1 and x >>= 1

Hero image for What is (x & 1) and (x >>= 1)?

Explore the fundamental bitwise operators & (AND) and >>= (right shift assignment) in C++. Learn how they are used for efficient bit manipulation, such as checking parity and performing division by powers of two.

Bitwise operations are a powerful and often misunderstood aspect of low-level programming. They allow direct manipulation of individual bits within an integer, offering highly efficient ways to perform certain tasks that might otherwise require more complex arithmetic or conditional logic. This article delves into two common bitwise expressions: x & 1 and x >>= 1, explaining their purpose, how they work, and practical applications.

The Bitwise AND Operator: x & 1

The bitwise AND operator (&) compares corresponding bits of two operands. If both bits are 1, the resulting bit is 1; otherwise, it's 0. When you perform x & 1, you are essentially checking the least significant bit (LSB) of x. The number 1 in binary is ...0001. Therefore, x & 1 will result in 1 if the LSB of x is 1 (meaning x is odd), and 0 if the LSB of x is 0 (meaning x is even).

flowchart LR
    subgraph x & 1
        A["Input x (e.g., 5)"] --> B{Binary: 101}
        C["Input 1"] --> D{Binary: 001}
        B -- "Bitwise AND (&)" --> E["Result: 001"]
        D -- "Bitwise AND (&)" --> E
        E --> F["Decimal: 1"]
    end
    subgraph x & 1
        G["Input x (e.g., 4)"] --> H{Binary: 100}
        I["Input 1"] --> J{Binary: 001}
        H -- "Bitwise AND (&)" --> K["Result: 000"]
        J -- "Bitwise AND (&)" --> K
        K --> L["Decimal: 0"]
    end

Flowchart illustrating x & 1 for odd and even numbers.

#include <iostream>

int main() {
    int num1 = 5; // Binary: ...0101
    int num2 = 4; // Binary: ...0100

    std::cout << num1 << " & 1 = " << (num1 & 1) << std::endl; // Output: 1
    std::cout << num2 << " & 1 = " << (num2 & 1) << std::endl; // Output: 0

    if ((num1 & 1) == 1) {
        std::cout << num1 << " is odd." << std::endl;
    } else {
        std::cout << num1 << " is even." << std::endl;
    }

    return 0;
}

C++ example demonstrating x & 1 to check for odd/even numbers.

The Right Shift Assignment Operator: x >>= 1

The right shift operator (>>) shifts the bits of its left operand to the right by the number of positions specified by its right operand. The >>= operator is a compound assignment operator, meaning x >>= 1 is equivalent to x = x >> 1. When you right-shift an integer by one position, you are effectively dividing it by 2. For unsigned integers, zeros are shifted in from the left. For signed integers, the behavior of the most significant bit (sign bit) depends on the implementation (arithmetic shift vs. logical shift), but for positive numbers, it generally behaves like an unsigned shift, filling with zeros. For negative numbers, it typically preserves the sign bit (arithmetic shift), filling with ones.

flowchart LR
    A["Input x (e.g., 10)"] --> B{"Binary: 1010"}
    B -- "Right Shift by 1 (>>= 1)" --> C{"Shifted: 0101"}
    C --> D["Decimal: 5"]

    E["Input x (e.g., 7)"] --> F{"Binary: 0111"}
    F -- "Right Shift by 1 (>>= 1)" --> G{"Shifted: 0011"}
    G --> H["Decimal: 3"]

    style A fill:#f9f,stroke:#333,stroke-width:2px
    style E fill:#f9f,stroke:#333,stroke-width:2px

Visualizing the x >>= 1 operation.

#include <iostream>

int main() {
    int num = 10; // Binary: ...1010
    std::cout << "Initial num: " << num << std::endl; // Output: 10

    num >>= 1; // num becomes 5 (Binary: ...0101)
    std::cout << "num after >>= 1: " << num << std::endl; // Output: 5

    num >>= 1; // num becomes 2 (Binary: ...0010)
    std::cout << "num after another >>= 1: " << num << std::endl; // Output: 2

    unsigned int u_num = 15; // Binary: ...1111
    std::cout << "\nInitial unsigned num: " << u_num << std::endl; // Output: 15
    u_num >>= 1; // u_num becomes 7 (Binary: ...0111)
    std::cout << "unsigned num after >>= 1: " << u_num << std::endl; // Output: 7

    return 0;
}

C++ example demonstrating x >>= 1 for integer division.

Combining x & 1 and x >>= 1 for Iterative Bit Processing

These two operators are frequently used together in algorithms that process an integer bit by bit, often from the least significant bit upwards. A classic example is counting the number of set bits (1s) in an integer or converting a decimal number to its binary representation.

#include <iostream>

int main() {
    int num = 13; // Binary: 1101
    int set_bits_count = 0;

    std::cout << "Processing number: " << num << std::endl;

    while (num > 0) {
        // Check if the LSB is 1
        if ((num & 1) == 1) {
            set_bits_count++;
            std::cout << "  LSB is 1. Count: " << set_bits_count << std::endl;
        } else {
            std::cout << "  LSB is 0." << std::endl;
        }
        // Shift right to process the next bit
        num >>= 1;
        std::cout << "  Number after shift: " << num << std::endl;
    }

    std::cout << "Total set bits: " << set_bits_count << std::endl; // Output: 3

    return 0;
}

C++ example counting set bits using x & 1 and x >>= 1.

In this loop, num & 1 extracts the value of the current LSB, and num >>= 1 discards that LSB and brings the next bit into the LSB position for the next iteration. This process continues until num becomes 0, meaning all bits have been processed.