Count of numbers having only one unset bit in a range [L,R]

Given two integers L and R, the task is to count the numbers having only one unset bit in the range [L, R].

Examples:

Input: L = 4, R = 9
Output: 2
Explanation:
The binary representation of all numbers in the range [4, 9] are 
4 = (100)2 
5 = (101)2 
6 = (110)2 
7 = (111)2 
8 = (1000)2 
9 = (1001)2 
Out of all the above numbers, only 5 and 6 have exactly one unset bit.
Therefore, the required count is 2.

Input: L = 10, R = 13
Output: 2
Explanation:
The binary representations of all numbers in the range [10, 13] 
10 = (1010)2 
11 = (1011)2 
12 = (1100)2 
13 = (1101)2 
Out of all the above numbers, only 11 and 13 have exactly one unset bit. 
Therefore, the required count is 2.

Naive Approach: The simplest approach is to check every number in the range [L, R] whether it has exactly one unset bit or not. For every such number, increment the count. After traversing the entire range, print the value of count.



Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to count numbers in the range
// [l, r] having exactly one unset bit
int count_numbers(int L, int R)
{
    // Stores the required count
    int ans = 0;
 
    // Iterate over the range
    for (int n = L; n <= R; n++) {
 
        // Calculate number of bits
        int no_of_bits = log2(n) + 1;
 
        // Calculate number of set bits
        int no_of_set_bits
            = __builtin_popcount(n);
 
        // If count of unset bits is 1
        if (no_of_bits
                - no_of_set_bits
            == 1) {
 
            // Increment answer
            ans++;
        }
    }
 
    // Return the answer
    return ans;
}
 
// Driver Code
int main()
{
    int L = 4, R = 9;
 
    // Function Call
    cout << count_numbers(L, R);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
class GFG{
 
// Function to count numbers in the range
// [l, r] having exactly one unset bit
static int count_numbers(int L,
                         int R)
{
    // Stores the required count
    int ans = 0;
 
    // Iterate over the range
    for (int n = L; n <= R; n++)
    {
        // Calculate number of bits
        int no_of_bits = (int) (Math.log(n) + 1);
 
        // Calculate number of set bits
        int no_of_set_bits = Integer.bitCount(n);
 
        // If count of unset bits is 1
        if (no_of_bits - no_of_set_bits == 1)
        {
            // Increment answer
            ans++;
        }
    }
 
    // Return the answer
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
    int L = 4, R = 9;
 
    // Function Call
    System.out.print(count_numbers(L, R));
}
}
 
// This code is contributed by Rajput-Ji

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
from math import log2
 
# Function to count numbers in the range
# [l, r] having exactly one unset bit
def count_numbers(L, R):
     
    # Stores the required count
    ans = 0
 
    # Iterate over the range
    for n in range(L, R + 1):
 
        # Calculate number of bits
        no_of_bits = int(log2(n) + 1)
 
        # Calculate number of set bits
        no_of_set_bits = bin(n).count('1')
 
        # If count of unset bits is 1
        if (no_of_bits - no_of_set_bits == 1):
 
            # Increment answer
            ans += 1
 
    # Return the answer
    return ans
 
# Driver Code
if __name__ == '__main__':
     
    L = 4
    R = 9
 
    # Function call
    print(count_numbers(L, R))
 
# This code is contributed by mohit kumar 29   

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach
using System;
 
class GFG{
 
// Function to count numbers in the range
// [l, r] having exactly one unset bit
static int count_numbers(int L,
                         int R)
{
     
    // Stores the required count
    int ans = 0;
 
    // Iterate over the range
    for(int n = L; n <= R; n++)
    {
         
        // Calculate number of bits
        int no_of_bits = (int)(Math.Log(n) + 1);
 
        // Calculate number of set bits
        int no_of_set_bits = bitCount(n);
 
        // If count of unset bits is 1
        if (no_of_bits - no_of_set_bits == 1)
        {
             
            // Increment answer
            ans++;
        }
    }
 
    // Return the answer
    return ans;
}
 
static int bitCount(long x)
{
    int setBits = 0;
    while (x != 0)
    {
        x = x & (x - 1);
        setBits++;
    }
    return setBits;
}
 
// Driver Code
public static void Main(String[] args)
{
    int L = 4, R = 9;
 
    // Function call
    Console.Write(count_numbers(L, R));
}
}
 
// This code is contributed by Amit Katiyar

chevron_right


Output: 

2









Time Complexity: O(N*Log R)
Auxiliary Space: O(1)

Efficient Approach: Since the maximum number of bits is at most log R and the number should contain exactly one zero in its binary representation, fix one position in [0, log R] as the unset bit and set all other bits and increment count if the generated number is within the given range. 
Follow the steps below to solve the problem:

  1. Loop over all possible positions of unset bit, say zero_bit, in the range [0, log R]
  2. Set all bits before zero_bit.
  3. Iterate over the range j = zero_bit + 1 to log R and set the bit at position j and increment count if the number formed is within the range [L, R].
  4. Print the count after the above steps.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to count numbers in the range
// [L, R] having exactly one unset bit
int count_numbers(int L, int R)
{
    // Stores the count elements
    // having one zero in binary
    int ans = 0;
 
    // Stores the maximum number of
    // bits needed to represent number
    int LogR = log2(R) + 1;
 
    // Loop over for zero bit position
    for (int zero_bit = 0;
         zero_bit < LogR; zero_bit++) {
 
        // Number having zero_bit as unset
        // and remaining bits set
        int cur = 0;
 
        // Sets all bits before zero_bit
        for (int j = 0; j < zero_bit; j++) {
 
            // Set the bit at position j
            cur |= (1LL << j);
        }
 
        for (int j = zero_bit + 1;
             j < LogR; j++) {
 
            // Set the bit position at j
            cur |= (1LL << j);
 
            // If cur is in the range [L, R],
            // then increment ans
            if (cur >= L && cur <= R) {
                ans++;
            }
        }
    }
 
    // Return ans
    return ans;
}
 
// Driver Code
int main()
{
    long long L = 4, R = 9;
 
    // Function Call
    cout << count_numbers(L, R);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for
// the above approach
import java.util.*;
class GFG{
 
// Function to count numbers in the range
// [L, R] having exactly one unset bit
static int count_numbers(int L, int R)
{
  // Stores the count elements
  // having one zero in binary
  int ans = 0;
 
  // Stores the maximum number of
  // bits needed to represent number
  int LogR = (int) (Math.log(R) + 1);
 
  // Loop over for zero bit position
  for (int zero_bit = 0; zero_bit < LogR;
           zero_bit++)
  {
    // Number having zero_bit as unset
    // and remaining bits set
    int cur = 0;
 
    // Sets all bits before zero_bit
    for (int j = 0; j < zero_bit; j++)
    {
      // Set the bit at position j
      cur |= (1L << j);
    }
 
    for (int j = zero_bit + 1;
             j < LogR; j++)
    {
      // Set the bit position at j
      cur |= (1L << j);
 
      // If cur is in the range [L, R],
      // then increment ans
      if (cur >= L && cur <= R)
      {
        ans++;
      }
    }
  }
 
  // Return ans
  return ans;
}
 
// Driver Code
public static void main(String[] args)
{
  int L = 4, R = 9;
 
  // Function Call
  System.out.print(count_numbers(L, R));
}
}
 
// This code is contributed by shikhasingrajput

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for
# the above approach
import  math
 
# Function to count numbers in the range
# [L, R] having exactly one unset bit
def count_numbers(L, R):
   
    # Stores the count elements
    # having one zero in binary
    ans = 0;
 
    # Stores the maximum number of
    # bits needed to represent number
    LogR = (int)(math.log(R) + 1);
 
    # Loop over for zero bit position
    for zero_bit in range(LogR):
       
        # Number having zero_bit as unset
        # and remaining bits set
        cur = 0;
 
        # Sets all bits before zero_bit
        for j in range(zero_bit):
           
            # Set the bit at position j
            cur |= (1 << j);
 
        for j in range(zero_bit + 1, LogR):
           
            # Set the bit position at j
            cur |= (1 << j);
 
            # If cur is in the range [L, R],
            # then increment ans
            if (cur >= L and cur <= R):
                ans += 1;
 
    # Return ans
    return ans;
 
# Driver Code
if __name__ == '__main__':
    L = 4;
    R = 9;
 
    # Function Call
    print(count_numbers(L, R));
 
# This code is contributed by Rajput-Ji

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for
// the above approach
using System;
 
public class GFG{
 
// Function to count numbers in the range
// [L, R] having exactly one unset bit
static int count_numbers(int L, int R)
{
  // Stores the count elements
  // having one zero in binary
  int ans = 0;
 
  // Stores the maximum number of
  // bits needed to represent number
  int LogR = (int) (Math.Log(R) + 1);
 
  // Loop over for zero bit position
  for (int zero_bit = 0; zero_bit < LogR;
           zero_bit++)
  {
    // Number having zero_bit as unset
    // and remaining bits set
    int cur = 0;
 
    // Sets all bits before zero_bit
    for (int j = 0; j < zero_bit; j++)
    {
      // Set the bit at position j
      cur |= (1 << j);
    }
 
    for (int j = zero_bit + 1;
             j < LogR; j++)
    {
      // Set the bit position at j
      cur |= (1 << j);
 
      // If cur is in the range [L, R],
      // then increment ans
      if (cur >= L && cur <= R)
      {
        ans++;
      }
    }
  }
 
  // Return ans
  return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
  int L = 4, R = 9;
 
  // Function Call
  Console.Write(count_numbers(L, R));
}
}
 
 
 
// This code contributed by shikhasingrajput

chevron_right


Output: 

2









Time Complexity: O((log R)2)
Auxiliary Space: O(1)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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.