Find two numbers from their sum and XOR

Given the sum and xor of two numbers X and Y s.t. sum and xor \in [0, 2^{64}-1], we need to find the numbers minimizing the value of X.

Examples :

Input : S = 17
        X = 13
Output : a = 2
         b = 15

Input : S = 1870807699 
        X = 259801747
Output : a = 805502976
         b = 1065304723

Input : S = 1639
        X = 1176
Output : No such numbers exist

Variables Used:
X ==> XOR of two numbers
S ==> Sum of two numbers
X[i] ==> Value of i-th bit in X
S[i] ==> Value of i-th bit in S

A simple solution is to generate all possible pairs with given XOR. To generate all pairs, we can follow below rules.

  1. If X[i] is 1, then both a[i] and b[i] should be different, we have two cases.
  2. If X[i] is 0, then both a[i] and b[i] should be same. we have two cases.
  3. So we generate 2^n possible pairs where n is number of bits in X. Then for every pair, we check if its sum is S or not.

    An efficient solution is based on below fact.

    S = X + 2*A
    where A = a AND b

    We can verify above fact using the sum process. In sum, whenever we see both bits 1 (i.e., AND is 1), we make resultant bit 0 and add 1 as carry, which means every bit in AND is left shifted by 1 OR value of AND is multiplied by 2 and added.

    So we can find A = (S – X)/2.

    Once we find A, we can find all bits of ‘a’ and ‘b’ using below rules.

    1. If X[i] = 0 and A[i] = 0, then a[i] = b[i] = 0. Only one possibility for this bit.
    2. If X[i] = 0 and A[i] = 1, then a[i] = b[i] = 1. Only one possibility for this bit.
    3. If X[i] = 1 and A[i] = 0, then (a[i] = 1 and b[i] = 0) or (a[i] = 0 and b[i] = 1), we can pick any of the two.
    4. If X[i] = 1 and A[i] = 1, result not possible (Note X[i] = 1 means different bits)

    Let the summation be S and XOR be X.

    Below is the implementation of above approach:

    C++

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // CPP program to find two numbers with
    // given Sum and XOR such that value of
    // first number is minimum.
    #include <iostream>
    using namespace std;
      
    // Function that takes in the sum and XOR
    // of two numbers and generates the two 
    // numbers such that the value of X is
    // minimized
    void compute(unsigned long int S, 
                unsigned long int X)
    {
        unsigned long int A = (S - X)/2;
      
        int a = 0, b = 0;
      
        // Traverse through all bits
        for (int i=0; i<8*sizeof(S); i++)
        {
            unsigned long int Xi = (X & (1 << i));
            unsigned long int Ai = (A & (1 << i));
            if (Xi == 0 && Ai == 0)
            {
                // Let us leave bits as 0.
            }
            else if (Xi == 0 && Ai > 0)
            {
                a = ((1 << i) | a); 
                b = ((1 << i) | b); 
            }
            else if (Xi > 0 && Ai == 0)
            {
                a = ((1 << i) | a); 
      
                // We leave i-th bit of b as 0.
            }
            else // (Xi == 1 && Ai == 1)
            {
                cout << "Not Possible";
                return;
            }
        }
      
        cout << "a = " << a << endl << "b = " << b;
    }
      
    // Driver function
    int main()
    {
        unsigned long int S = 17, X = 13;
        compute(S, X);
        return 0;
    }

    chevron_right

    
    

    Java

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // Java program to find two numbers with 
    // given Sum and XOR such that value of 
    // first number is minimum. 
    class GFG {
      
    // Function that takes in the sum and XOR 
    // of two numbers and generates the two 
    // numbers such that the value of X is 
    // minimized 
    static void compute(long S, long  X) 
        long A = (S - X)/2
        int a = 0, b = 0
            final int LONG_FIELD_SIZE     = 8;
      
        // Traverse through all bits 
        for (int i=0; i<8*LONG_FIELD_SIZE; i++) 
        
            long Xi = (X & (1 << i)); 
            long Ai = (A & (1 << i)); 
            if (Xi == 0 && Ai == 0
            
                // Let us leave bits as 0. 
            
            else if (Xi == 0 && Ai > 0
            
                a = ((1 << i) | a); 
                b = ((1 << i) | b); 
            
            else if (Xi > 0 && Ai == 0
            
                a = ((1 << i) | a); 
      
                // We leave i-th bit of b as 0. 
            
            else // (Xi == 1 && Ai == 1) 
            
                System.out.println("Not Possible"); 
                return
            
        
      
        System.out.println("a = " + a +"\nb = " + b); 
      
    // Driver function 
        public static void main(String[] args) {
            long S = 17, X = 13
        compute(S, X); 
      
        }
    }
    // This code is contributed by RAJPUT-JI

    chevron_right

    
    

    Python3

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    # Python program to find two numbers with
    # given Sum and XOR such that value of
    # first number is minimum.
      
      
    # Function that takes in the sum and XOR
    # of two numbers and generates the two 
    # numbers such that the value of X is
    # minimized
    def compute(S, X):
        A = (S - X)//2
        a = 0
        b = 0
      
        # Traverse through all bits
        for i in range(64):
            Xi = (X & (1 << i))
            Ai = (A & (1 << i))
            if (Xi == 0 and Ai == 0):
                # Let us leave bits as 0.
                pass
                  
            elif (Xi == 0 and Ai > 0):
                a = ((1 << i) | a) 
                b = ((1 << i) | b) 
              
            elif (Xi > 0 and Ai == 0):
                a = ((1 << i) | a) 
                # We leave i-th bit of b as 0.
      
            else: # (Xi == 1 and Ai == 1)
                print("Not Possible")
                return
      
        print("a = ",a)
        print("b =", b)
      
      
    # Driver function
    S = 17
    X = 13
    compute(S, X)
      
    # This code is contributed by ankush_953

    chevron_right

    
    

    C#

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C# program to find two numbers with 
    // given Sum and XOR such that value of 
    // first number is minimum. 
    using System;
      
    public class GFG {
      
    // Function that takes in the sum and XOR 
    // of two numbers and generates the two 
    // numbers such that the value of X is 
    // minimized 
    static void compute(long S, long  X) 
        long A = (S - X)/2; 
        int a = 0, b = 0; 
       
      
        // Traverse through all bits 
        for (int i=0; i<8*sizeof(long); i++) 
        
            long Xi = (X & (1 << i)); 
            long Ai = (A & (1 << i)); 
            if (Xi == 0 && Ai == 0) 
            
                // Let us leave bits as 0. 
            
            else if (Xi == 0 && Ai > 0) 
            
                a = ((1 << i) | a); 
                b = ((1 << i) | b); 
            
            else if (Xi > 0 && Ai == 0) 
            
                a = ((1 << i) | a); 
      
                // We leave i-th bit of b as 0. 
            
            else // (Xi == 1 && Ai == 1) 
            
                Console.WriteLine("Not Possible"); 
                return
            
        
      
        Console.WriteLine("a = " + a +"\nb = " + b); 
      
    // Driver function 
        public static void Main() {
            long S = 17, X = 13; 
            compute(S, X); 
        }
    }
    // This code is contributed by RAJPUT-JI

    chevron_right

    
    


    Output

    a = 15
    b = 2
    

    Time complexity of the above approach O(b) where b is number of bits in S.



    My Personal Notes arrow_drop_up

    Waba Laba Dub Dub

    If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

    Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.