Turn off the rightmost set bit
Given an integer n, turn remove turn off the rightmost set bit in it.
Input: 12
Output: 8
Explanation : Binary representation of 12 is 00...01100. If we turn of the rightmost set bit, we get 00...01000 which is binary representation of 8Input: 7
Output: 6
Explanation : Binary representation for 7 is 00...00111 and for 6, it is 00...00110Input: 0
Output: 0
Explanation : There is no rightmost set bit
Table of Content
Naive Approach
- A simple is to find the position of the rightmost set bit in the number by a bitwise right shift operation to check for the first occurrence of 1.
- Then, flip the bit in this position. Flipping can be done by applying XOR of the given number and the number with the bit in this position set.
0 ^ 1 = 1 1 ^ 1 = 0 Xor with 1 flips the bit. - Setting only a given bit can be done by taking 2 to the power of position to set a particular bit.
Below is the implementation of the above approach.
// Cpp program to unset the rightmost
// set bit using Naive approach
#include <bits/stdc++.h>
using namespace std;
// Unsets the rightmost set bit
// of n and returns the result
int unsetLSB(int n) {
if (n == 0)
return 0;
// Find the rightmost set bit
int pos = 0;
while (((n >> pos) & 1) == 0) {
pos++;
}
// Unset the rightmost set bit
n = n ^ (1 << pos);
return n;
}
int main() {
int n = 12;
cout << unsetLSB(n);
return 0;
}
// C program to unset the rightmost
// set bit using Naive approach
#include <stdio.h>
// Unsets the rightmost set bit
// of n and returns the result
int unsetLSB(int n) {
if (n == 0)
return 0;
// Find the rightmost set bit
int pos = 0;
while ( ((n >> pos) & 1) == 0 ) {
pos++;
}
// Unset the rightmost set bit
n = n ^ (1 << pos);
return n;
}
// Driver code
int main() {
int n = 12;
printf("%d", unsetLSB(n));
return 0;
}
// Java program to unset the rightmost
// set bit using Naive approach
class GfG {
// Unsets the rightmost set bit
// of n and returns the result
static int unsetLSB(int n) {
if (n == 0)
return 0;
// Find the rightmost set bit
int pos = 0;
while (((n >> pos) & 1) == 0) {
pos++;
}
// Unset the rightmost set bit
n = n ^ (1 << pos);
return n;
}
public static void main(String[] args) {
int n = 12;
System.out.print(unsetLSB(n));
}
}
# Python program to unset the rightmost
# set bit using Naive approach
# Unsets the rightmost set bit
# of n and returns the result
def unsetLSB(n):
if n == 0:
return 0
# Find the rightmost set bit
pos = 0
while ((n >> pos) & 1) == 0:
pos += 1
# Unset the rightmost set bit
n = n ^ (1 << pos)
return n
n = 12
print(unsetLSB(n))
// C# program to unset the rightmost
// set bit using Naive approach
using System;
class GfG {
// Unsets the rightmost set bit
// of n and returns the result
static int unsetLSB(int n) {
if (n == 0)
return 0;
// Find the rightmost set bit
int pos = 0;
while (((n >> pos) & 1) == 0)
{
pos++;
}
// Unset the rightmost set bit
n = n ^ (1 << pos);
return n;
}
static void Main(string[] args) {
int n = 12;
Console.Write(unsetLSB(n));
}
}
// JavaScript program to unset the rightmost
// set bit using Naive approach
// Unsets the rightmost set bit
// of n and returns the result
function unsetLSB(n) {
if (n === 0)
return 0;
// Find the rightmost set bit
let pos = 0;
while (((n >> pos) & 1) === 0) {
pos++;
}
// Unset the rightmost set bit
n = n ^ (1 << pos);
return n;
}
let n = 12;
console.log(unsetLSB(n));
Output
8
Time Complexity: O(Position of the Rightmost Set Bit)
Auxiliary Space: O(1)
Expected Approach 1 - Subtracting by One
We mainly need keep all other bits as it is and turn off the last set bit. Below are the main two we use.
1) Compute (n-1) : When we subtract a number by 1, all bits after the rightmost set bit (including it) are toggled. For example :
10 in binary is 00001010 and 9 in binary is 00001001
8 in binary is 00001000 and 7 in binary is 00000111
2) Do Bitwise AND of n and (n-1) : If we do bitwise and of n and n-1, the result bits before the rightmost set bit remain as it (because these bits were not changed in -1) is and the bits after it also remain as it is (because these bits were 0 in n and became 1 in n-1). The only bit that changes is the rightmost set bit (It was 1 in n and became 0 in n-1).
So we get the required result after n & (n - 1)
For example, bitwise and of 10 and 9 gives us 8 ( 00001000 ) and bitwsie and of 8 and 7 gives us 0 (00000000)
This idea is used in Brian Kernighan’s Algorithm for efficiently computing count of set bits.
// Cpp program to unset the rightmost
// set bit using Subtracting by One
#include <bits/stdc++.h>
using namespace std;
// unsets the rightmost set bit
// of n and returns the result
int unsetLSB(int n) {
return (n & (n - 1));
}
int main() {
int n = 12;
cout << unsetLSB(n);
return 0;
}
// C program to unset the rightmost
// set bit using Subtracting by One
#include <stdio.h>
// unsets the rightmost set bit
// of n and returns the result
int unsetLSB(int n)
{
return n & (n - 1);
}
// Driver code
int main()
{
int n = 12;
printf("%d", unsetLSB(n));
return 0;
}
// Java program to unset the rightmost
// set bit using Subtracting by One
class GfG {
// unsets the rightmost set bit
// of n and returns the result
static int unsetLSB(int n) {
return n & (n - 1);
}
public static void main(String[] args) {
int n = 12;
System.out.print(unsetLSB(n));
}
}
# Python program to unset the rightmost
# set bit using Subtracting by One
# unsets the rightmost set bit
# of n and returns the result
def unsetLSB(n):
return n & (n - 1)
# Driver code
n = 12
print(unsetLSB(n))
// C# program to unset the rightmost
// set bit using Subtracting by One
using System;
class GfG
{
// unsets the rightmost set bit
// of n and returns the result
static int unsetLSB(int n)
{
return n & (n - 1);
}
static void Main(string[] args)
{
int n = 12;
Console.Write(unsetLSB(n));
}
}
// JavaScript program to unset the rightmost
// set bit using Subtracting by One
// unsets the rightmost set bit
// of n and returns the result
function unsetLSB(n) {
return n & (n - 1);
}
// Driver code
let n = 12;
console.log(unsetLSB(n));
Output
6
Time Complexity: O(1)
Auxiliary Space: O(1)
Expected Approach 2 - Using 2's Complement
The LSB of a number can be obtained using (n & (-n)), therefore the number with the rightmost set bit of n switched off is equal to n - (n & (-n)). When we make a number negative, we get two's complement of the number (this is machine dependent, but most of the machines use 2's complement only). Please refer Unset the rightmost set bit using 2s complement for details