Search code examples
cbit-manipulationxor

bitwise operator XOR


Trying to understand the XOR importance, I found this code:

Given a set of numbers where all elements occur even number of times except one number, find the odd occurring number

But I can't visualize it. How does the XOR bitwise operator roll out the odd element?

// Function to return the only odd occurring element
int findOdd(int arr[], int n) {
    int res = 0, i;
    for (i = 0; i < n; i++)
        res ^= arr[i];
    return res;
}

int main(void) {
    int arr[] = { 12, 12, 14, 90, 14, 14, 14 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printf("The odd occurring element is %d\n", findOdd(arr, n));
    return 0;
}

Output: The odd occurring element is 90


Solution

  • The way I read it you are really asking two questions:

    1. What is the importance of XOR?
    2. How does XOR help find the odd occurrence of a number in a series?

    In order to understand question (2), one must understand question (1). Understanding question (1) requires an adequate introduction to the XOR logic and the properties it has.

    What is the importance of XOR?


    Definition: The output of an XOR operation is TRUE if and only if the number of TRUE inputs are odd. Commonly referred to as "one or the other, but not both"

    This is captured by the following truth table: XOR Truth Table

    Using the truth table it is trivial to derive the following properties:

    • A ^ 0 = A                           (The output follows the variable input)
    • A ^ 1 = A'                          (The output is the negation of the variable input)
    • A ^ A = 0                           (The output is always zero since both inputs are equal)
    • (A ^ B) ^ C = A ^ (B ^ C) (Associative Property)
    • A ^ B = B ^ A                    (Communative Property)

    Now on to the importance of XOR, i.e., how these properties allow folks to make useful things. The first computing layer to note is the hardware layer. XOR gates are physical devices that have utility in many fundamental logic circuits, that fundamental utility being "odd occurrence detection". Some notable applications:

    • Half-Adders: The truth table for a half-adders SUM output is identical to the XOR gate. (Throw an AND gate in for the carry bit). Same thing for the Full-Adder, using XOR gates for the fundamental summation with some additional supporting gates.
    • Inverters: Using one input as a control and the other as the "input", the xor gate can be used to invert the input signal. The control bit can be used to pass the input through as well, acting as a buffer. In software, you use these circuits to toggle bits/bytes from one state to the other. Val = Val ^ 1 (Recall the second property above).
    • Comparators: The output of an XOR gate is 1 when the inputs are different, 0 when they are the same. This is the driving logic for the half-adder.

    In addition to these circuits we can, at a hardware level, use XOR to check byte parity for Error Detection and Correction (EDAC) operations, swap register values (without a temp variable!), and recover corrupted/lost data from hard drives in a RAID system.

    However, software junkies don't care about these circuits, they want to live in the land of abstractions that provide an easy way to use this hardware in a human intuitive way. Let there be code.


    How does XOR help find the odd occurrence of a number in a series?

    Even though the first comment to your question indicates the poster didn't understand your question, they inadvertently answered the question correctly, but I will explain further.

    Let's break down what your findOdd() function is actually doing. The for loop is literally performing the following calculation:

    Result = 0 ^ 12 ^ 12 ^ 14 ^ 90 ^ 14 ^ 14 ^ 14

    Recall that XOR is communative, so after a little re-ordering the calculation becomes:

    Result = 0 ^ 12 ^ 12 ^ 14 ^ 14 ^ 14 ^ 14 ^ 90

    Using the property A ^ A = 0 and associativity, the XOR of 12 and 12 drops to 0 as does the XOR of the 14's, leaving:

    Result = 0 ^ 0 ^ 0 ^ 0 ^ 90 = 0 ^ 90 = 90

    In effect, the XOR forces even occurrences to become zero and A ^ 0 = A. Hope this verbose description of XOR was helpful in visualizing what is happening under the hood.