Calculate floor of Log2n without using built-in function
Problem
Given a positive integer n, compute floor(log2(n)) (the exponent of the highest power of two not exceeding n) without using a language built-in log2 function.
Examples
Example 1
Input: n = 32
Output: 5 # because 2^5 = 32
Example 2
Input: n = 64
Output: 6 # because 2^6 = 64
Example 3
Input: n = 20
Output: 4 # because 2^4 = 16 <= 20 < 32
Solution
Method 1 — Repeated division (or right shift)
Intuition
floor(log2(n)) is the number of times we can divide n by 2 (or shift right) before it becomes less than 1. Each division by 2 reduces the exponent by 1.
Approach
- If
n <= 0the problem is undefined for non-positive integers (handle as error or return -INF depending on your API). - Initialize
ans = 0. - While
n > 1:n = n / 2(orn >>= 1for integer types)ans++
- Return
ans.
Edge cases:
n == 1->floor(log2(1)) = 0.- Large values should fit in the integer types you choose; use 64-bit if needed.
Code
C++
class Solution {
public:
int floorLog2(int n) {
if (n <= 0) return -1; // undefined for non-positive input
int ans = 0;
while (n > 1) {
n >>= 1;
++ans;
}
return ans;
}
};
Go
package main
func floorLog2(n int) int {
if n <= 0 {
return -1 // undefined for non-positive
}
ans := 0
for n > 1 {
n >>= 1
ans++
}
return ans
}
Java
class Solution {
public int floorLog2(int n) {
if (n <= 0) return -1; // undefined
int ans = 0;
while (n > 1) {
n >>= 1;
ans++;
}
return ans;
}
}
Python
class Solution:
def floorLog2(self, n: int) -> int:
if n <= 0:
return -1
ans = 0
while n > 1:
n >>= 1
ans += 1
return ans
Complexity
- ⏰ Time complexity:
O(log n)because we divide/shiftnuntil it becomes 1 (aboutlog2(n)iterations). - 🧺 Space complexity:
O(1)extra space.
Method 2 — Find highest set bit using exponential + binary search (faster for extremely large ranges)
Intuition
If you repeatedly double a power-of-two value until it exceeds n, you can locate a bracket [2^k, 2^{k+1}) containing n. A small binary search between those exponents finds k = floor(log2(n)) in O(log k) steps. This is useful when bit-length operations are not available but you want fewer comparisons than repeated division in some contexts.
Approach
- If
n <= 0return error indicator. - Start with
p = 1,k = 0. - While
p << 1 <= n:p <<= 1,k++. - Return
k.
(This is effectively the same as Method 1 implemented with a power-of-two variable; it runs in O(log n) but uses a different loop variable.)
Code
C++
class Solution {
public:
int floorLog2(int n) {
if (n <= 0) return -1;
int p = 1;
int k = 0;
while ((p << 1) <= n) {
p <<= 1;
++k;
}
return k;
}
};
Go
package main
func floorLog2(n int) int {
if n <= 0 { return -1 }
p := 1
k := 0
for (p << 1) <= n {
p <<= 1
k++
}
return k
}
Java
class Solution {
public int floorLog2(int n) {
if (n <= 0) return -1;
int p = 1;
int k = 0;
while ((p << 1) <= n) {
p <<= 1;
k++;
}
return k;
}
}
Python
class Solution:
def floorLog2(self, n: int) -> int:
if n <= 0:
return -1
p = 1
k = 0
while (p << 1) <= n:
p <<= 1
k += 1
return k
Complexity
- ⏰ Time complexity:
O(log n)iterations in the worst case. - 🧺 Space complexity:
O(1)extra space.