Increment a number by 1 by manipulating the bits


Bit manipulation applies logical operations on a bit stream using bitwise operators like AND(&), OR(|), NOT(~), XOR(^), Left Shift(<<) and Right Shift(>>) to get a required result. Using bitwise operators is beneficial as we can manipulate individual bits and they are faster than other operators.

Problem Statement

Given a number. Increment or add the number by 1 using bitwise operators only. (Don’t use arithmetic operators like ‘+’ , ‘-’, ‘*’ or’/’ )

Approach 1: Using One’s Complement / NOT Operator

Bitwise complement / One’s complement is implemented using the NOT(~) Operator.

For a number n, a bitwise complement of n i.e. ~n = -(n+1). Thus, we can get n+1 by only taking the value of ~n and ignoring the sign. This can be done using the abs() function that returns the variable's value and neglects the sign.

Pseudocode

procedure inc (num)
   num = |~n| // | | represents the abs() function
end procedure

Example

In the following program, we calculate the increment of a number by 1 by using the bitwise complement operator and absolute function.

#include <bits/stdc++.h>
using namespace std;
// Function for finding the increment of input by 1
int inc(int num){

   // using the abs() function to get the value obtained by applying the ~ operator
   num = abs(~num);
   return num;
}
int main(){
   int input = 7;
   cout << input << " + 1 using bit manipulation = " << inc(input);
   return 0;
}

Output

7 + 1 using bit manipulation = 8

Time Complexity − O(1) as no loop is implemented.

Space Complexity − O(1) as no extra space is used.

Approach 2

Take the example of some binary additions as follows,


As a conclusion from the above examples, it can be seen that the binary digits on the left side of the first unset bit from the right of the number remain the same on binary addition of 1. But the first unset bit from the right is set and all the bits on the right side are toggled i.e. set bits are unset and unset bits are set (0’s converted to 1’s and 1’s converted to 0’s).

Thus, we can break our problem into two basic parts,

  • Set the first unset bit from the right.

  • Toggle all the bits on the right side.

Recursive Approach Pseudocode

procedure inc (num)
   if num & 1 == 0
      ans = num | 1
   else
      ans = inc (num >> 1) << 1
   end if
end procedure

Example

In the following program, we are using recursion to increment a number by 1 based on the idea explained above.

#include <bits/stdc++.h>
using namespace std;
// Function for finding the increment of input
int inc(int num){

   // check if the LSB is set or not. If it is unset, it enters if otherwise, it goes to else
   if ((num & 1) == 0) {
   
      // LSB is set
      return num | 1;
   }
   else {
   
      // The number is right shifted and the function is called again
      // After obtaining the return number from called function, the number is left shifted
      return inc(num >> 1) << 1;
   }
}
int main(){
   int input = 14;
   cout << input << " + 1 using bit manipulation = " << inc(input);
   return 0;
}

Output

14 + 1 using bit manipulation = 15

Time Complexity − O(k) where k is the position of first unset bit from right.

Space Complexity − O(k) due to the recursive stack space.

Iterative Approach Pseudocode

procedure inc (num)
   m = 1
   while num & m
      num = num & (~m)
      m = m << 1
   end while
   num = num | m
end procedure

Example

In the following program, we use a mask number that is changed in every iteration till we get the unset bit from the right-hand side. Upon discovering it, the unset bit is set and all the other bits on the right side are toggled.

#include <bits/stdc++.h>
using namespace std;
// Function for finding the increment of input
int inc(int num){

   // declare a mask with value 1 which is used to find the first unset bit from right side
   int m = 1;
   
   // checks if LSB is set. If set enter the loop and repeat till we get to the unset bit
   while (num & m) {
      num &= ~m;
      
      // mask is changed at every iteration to set the unset bit and toggle bits when the loop ends
      m <<= 1;
   }
   
   // mask used to set the unset bit and toggle all the bits on the right-hand side
   num |= m;
   return num;
}
int main(){
   int input = 14;
   cout << input << " + 1 using bit manipulation = " << inc(input);
   return 0;
}

Output

14 + 1 using bit manipulation = 15

Time Complexity − O(k) where k is the position of first unset bit from right.

Space Complexity − O(1)

Approach 3

In this approach, we approach to reduce the time complexity by reducing the time to find the first unset bit. In this approach, we will first find the first unset bit from the right, set it and toggle all the bits on the right.

Pseudocode

procedure inc (num)
   pos = log2 (num & ~num)
   add = 1 << pos
   num = num | add
   if pos != 0
      toggle = (1 << pos) - 1
      num = num ^ toggle
   end if
   ans = num
end procedure

Example

In the following program, Log2() operation is used to find the unset bit, left shift and OR fro setting the bit and left shift and XOR for toggling bits.

#include <bits/stdc++.h>
using namespace std;
// Function for finding the increment of input
int inc(int num){

   // finds the position of the first unset bit from right
   int pos = log2(num & ~num);
   
   // the following 2 operations combined set the unset bit
   int add = 1 << pos;
   num |= add;
   
   // Toggling bits only for the numbers where the first unset bit was not the LSB
   if (pos != 0){
   
      // Using left shift and XOR operations to toggle bits
      int toggle = (1 << pos) - 1;
      num ^= toggle;
   }
   return num;
}

int main(){
   int input = 14;
   cout << input << " + 1 using bit manipulation = " << inc(input);
   return 0;
}

Output

14 + 1 using bit manipulation = 15

Time Complexity − O(1)

Space Complexity − O(1)

Conclusion

In conclusion, for incrementing a number by 1, we can either use one’s complement concept or by analyzing the nature of bits on the addition of 1 we can follow the above approaches to get the desired result.

Updated on: 28-Sep-2023

180 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements