How for given unsigned integer x
find the smallest n, that 2 ^ n
≥ x
in O(1)? in other words I want to find the index of higher set bit in binary format of x
(plus 1 if x
is not power of 2) in O(1) (not depended on size of integer and size of byte).

- 10,810
- 14
- 61
- 111
-
Tagged as homework, as it does sound like that. If that's wrong, please remove tag. – Tony The Lion May 11 '11 at 09:51
-
3In constant time? I doubt that is possible!! – Tony The Lion May 11 '11 at 09:52
-
@Tony The Tiger: not necessarily homework: could as well be an interview question. Should be precised anyway tought. – ereOn May 11 '11 at 09:53
-
1Similar: http://stackoverflow.com/questions/53161/find-the-highest-order-bit-in-c (but not constant time) – Rup May 11 '11 at 09:54
-
@Tony no this is not homework and not interview question. I just want write such code. – Mihran Hovsepyan May 11 '11 at 09:56
-
Do you mean an arbitrary long integer `x` a bigint, or a c++ `unsigned int`? – Ishtar May 11 '11 at 10:16
-
@lshtar I mean c++ unsigned int. – Mihran Hovsepyan May 11 '11 at 10:29
-
1possible duplicate of [What is the fastest algorithm to return the power of a number which is a power of 2?](http://stackoverflow.com/questions/5692444/what-is-the-fastest-algorithm-to-return-the-power-of-a-number-which-is-a-power-of) – fredoverflow May 11 '11 at 11:30
-
@Fred: This one's also got the O(1) requirement. Not a dupe, I'd say. – sbi May 11 '11 at 11:55
-
@Mihran: If the number you need this for is a compile-time constant, you can do that using template meta programming. You can't get faster run-time execution than that. – sbi May 11 '11 at 11:56
-
@sbi unfortunately I need to calculate that n at runtime. But I've already solved this problem redesigning my class a bit. – Mihran Hovsepyan May 12 '11 at 10:04
11 Answers
If you have no memory constraints, then you can use a lookup table (one entry for each possible value of x
) to achieve O(1) time.
If you want a practical solution, most processors will have some kind of "find highest bit set" opcode. On x86, for instance, it's BSR
. Most compilers will have a mechanism to write raw assembler.

- 267,707
- 33
- 569
- 680
-
no memory constraints... that says it all, isn't that a fairly theoretical thing, as there will always be memory constraints? – Tony The Lion May 11 '11 at 09:55
-
2@Tony: If this is a computer science problem, rather than a practical problem, then we often ignore little details such as "memory constraints"! – Oliver Charlesworth May 11 '11 at 09:55
-
Sometimes in CS there are memory constraints: a Turing machine must have access to an infinite tape. That's a constraint right there. :P – R. Martinho Fernandes May 11 '11 at 11:39
Ok, since so far nobody has posted a compile-time solution, here's mine. The precondition is that your input value is a compile-time constant. If you have that, it's all done at compile-time.
#include <iostream>
#include <iomanip>
// This should really come from a template meta lib, no need to reinvent it here,
// but I wanted this to compile as is.
namespace templ_meta {
// A run-of-the-mill compile-time if.
template<bool Cond, typename T, typename E> struct if_;
template< typename T, typename E> struct if_<true , T, E> {typedef T result_t;};
template< typename T, typename E> struct if_<false, T, E> {typedef E result_t;};
// This so we can use a compile-time if tailored for types, rather than integers.
template<int I>
struct int2type {
static const int result = I;
};
}
// This does the actual work.
template< int I, unsigned int Idx = 0>
struct index_of_high_bit {
static const unsigned int result =
templ_meta::if_< I==0
, templ_meta::int2type<Idx>
, index_of_high_bit<(I>>1),Idx+1>
>::result_t::result;
};
// just some testing
namespace {
template< int I >
void test()
{
const unsigned int result = index_of_high_bit<I>::result;
std::cout << std::setfill('0')
<< std::hex << std::setw(2) << std::uppercase << I << ": "
<< std::dec << std::setw(2) << result
<< '\n';
}
}
int main()
{
test<0>();
test<1>();
test<2>();
test<3>();
test<4>();
test<5>();
test<7>();
test<8>();
test<9>();
test<14>();
test<15>();
test<16>();
test<42>();
return 0;
}
'twas fun to do that.

- 219,715
- 46
- 258
- 445
-
1Wasn't my downvote, but this isn't O(1). I bet it was fun, but it doesn't answer the question. – Fred Nurk May 12 '11 at 09:44
-
@Fred: What do you mean? Compiling with VC, release settings, the line `const unsigned int result = index_of_high_bit::result;` expands to no code at all. That seems as constant a complexity as it can get. – sbi May 12 '11 at 09:49
-
1"Evaluated at compile-time" is not the same thing as O(1), and that's not even getting into assuming the input is available as a compile-time constant is a big stretch, when the question doesn't state that. – Fred Nurk May 12 '11 at 09:53
-
@Fred: Well, the answer says that this solution requires compile-time constants right on the package, so it's not like you caught me out implicitly assuming something that isn't given. We don't know whether the input is known at compile-time, so it _might_ be, which makes this assumption one worth exploring into. Under that assumption, the program compiled from this code will require zero time to find the highest bit in a given `int`, and _zero time is constant time_, which is what O(1) is all about. – sbi May 12 '11 at 09:58
-
1Doing the work for a given problem beforehand (for a particular set of inputs, as opposed to generating a generic lookup table), saving the result, and then saying "I can find it in zero time" is misleading, to say the least. – Fred Nurk May 12 '11 at 10:09
-
@Fred: Most people, when in search of an O(1) solution, search for a solutions that gives constant _run-time_. Taking into account compile time is like taking into account the time it takes to create the lookup table for Oli's solution: Yes, that takes time, but usually this is of academic interest. – sbi May 12 '11 at 10:16
-
1@sbi: Oli's solution requires a general lookup table that can be reused for any input. Your solution requires pre-computing the answer knowing the exact input in advance. These are not the same thing. – Fred Nurk May 12 '11 at 10:18
-
@Fred: You're knocking down a strawman. Nobody said they are the same. Oli's solution requires you to _pre-compute all answers_ instead of just the ones you need. Why would that be less cheating? – sbi May 12 '11 at 10:25
-
You compared Oli's solution to yours; it is not a strawman when *you* introduce it. – Fred Nurk May 12 '11 at 10:27
-
@Fred: Does comparing shared attributes of two entities imply they are the same? What's happened to your logic module today? – sbi May 12 '11 at 10:40
-
1@sbi As it is possible to implement "Turing Machine" via template metaprogramming, so theoritically we can solve each problem compile time. You have done it for this problem. Thank you! But actually I might to calculate `n` runtime :) – Mihran Hovsepyan May 14 '11 at 14:18
In <cmath>
there are logarithm functions that will perform this computation for you.
ceil(log(x) / log(2));

- 144,682
- 38
- 256
- 465
-
1don't think that this will be faster, than just run on the bits of the integer. – Mihran Hovsepyan May 11 '11 at 09:58
Some math to transform the expression:
int n = ceil(log(x)/log(2));
This is obviously O(1).

- 127,556
- 20
- 111
- 121
-
3
-
-
2@Martin - depends on what you consider as atomic operations in which you measure your algorithm's complexity. It is common to use very basic operations (e.g. arithmetics and memory access) so that the complexity analysis would be independent from a particular hardware. But even if you take all your processor's instruction set as basic ops, still `log(x)` requires computation which is not `O(1)`. The fact that it is written as one library function call does not make it atomic. – davka May 11 '11 at 12:14
-
Are the number of instructions for log() dependent on the sizeof x? (apparently not the value of x). – Martin York May 11 '11 at 12:48
-
-
Then its O(1). Unless you are trying to trick me and its really O(n^2) – Martin York May 11 '11 at 17:26
It's a question about finding the highest bit set (as lshtar and Oli Charlesworth pointed out). Bit Twiddling Hacks gives a solution which takes about 7 operations for 32 Bit Integers and about 9 operations for 64 Bit Integers.

- 7,464
- 6
- 51
- 108
You can use precalculated tables.
If your number is in [0,255] interval, simple table look up will work.
If it's bigger, then you may split it by bytes and check them from high to low.

- 6,297
- 1
- 23
- 19
-
3This runs in *O(log N)* time, where *N* is the maximum size of `x`. – Oliver Charlesworth May 11 '11 at 09:56
Perhaps this link will help.
Warning : the code is not exactly straightforward and seems rather unmaintainable.
uint64_t v; // Input value to find position with rank r.
unsigned int r; // Input: bit's desired rank [1-64].
unsigned int s; // Output: Resulting position of bit with rank r [1-64]
uint64_t a, b, c, d; // Intermediate temporaries for bit count.
unsigned int t; // Bit count temporary.
// Do a normal parallel bit count for a 64-bit integer,
// but store all intermediate steps.
// a = (v & 0x5555...) + ((v >> 1) & 0x5555...);
a = v - ((v >> 1) & ~0UL/3);
// b = (a & 0x3333...) + ((a >> 2) & 0x3333...);
b = (a & ~0UL/5) + ((a >> 2) & ~0UL/5);
// c = (b & 0x0f0f...) + ((b >> 4) & 0x0f0f...);
c = (b + (b >> 4)) & ~0UL/0x11;
// d = (c & 0x00ff...) + ((c >> 8) & 0x00ff...);
d = (c + (c >> 8)) & ~0UL/0x101;
t = (d >> 32) + (d >> 48);
// Now do branchless select!
s = 64;
// if (r > t) {s -= 32; r -= t;}
s -= ((t - r) & 256) >> 3; r -= (t & ((t - r) >> 8));
t = (d >> (s - 16)) & 0xff;
// if (r > t) {s -= 16; r -= t;}
s -= ((t - r) & 256) >> 4; r -= (t & ((t - r) >> 8));
t = (c >> (s - 8)) & 0xf;
// if (r > t) {s -= 8; r -= t;}
s -= ((t - r) & 256) >> 5; r -= (t & ((t - r) >> 8));
t = (b >> (s - 4)) & 0x7;
// if (r > t) {s -= 4; r -= t;}
s -= ((t - r) & 256) >> 6; r -= (t & ((t - r) >> 8));
t = (a >> (s - 2)) & 0x3;
// if (r > t) {s -= 2; r -= t;}
s -= ((t - r) & 256) >> 7; r -= (t & ((t - r) >> 8));
t = (v >> (s - 1)) & 0x1;
// if (r > t) s--;
s -= ((t - r) & 256) >> 8;
s = 65 - s;

- 53,676
- 39
- 161
- 238
As has been mentioned, the length of the binary representation of x + 1 is the n you're looking for (unless x is in itself a power of two, meaning 10.....0 in a binary representation). I seriously doubt there exists a true solution in O(1), unless you consider translations to binary representation to be O(1).

- 5,338
- 5
- 33
- 55
-
we don't need to "tranlate" to binary representation. It is already stored in memory in binary format. – Mihran Hovsepyan May 11 '11 at 10:13
-
@Mihran Hovsepyan Of course it is, but how do you get the length of its binary representation in O(1)? Maybe there's some sort of binary operators trick here to find the last (leftmost) '1'... Regardless, if you can assume you know its binary representation, then as mention, it's the length + 1 (or the length itself, if x = 2^k for some natural k) – Gal May 11 '11 at 10:15
-
I can get num of bits in `unsigned int` in O(1) but not num of bits of binary representation of integer x. – Mihran Hovsepyan May 11 '11 at 10:31
-
aye, forgot about 2's complement representation :) well then, if the number is negative or is 0, the required n equals 0 (or minus infinity, depends on the requirements from n). if the number is positive, just cast it into a unsigned int. – Gal May 11 '11 at 10:33
For a 32 bit int, the following pseudocode will be O(1).
highestBit(x)
bit = 1
highest = 0
for i 1 to 32
if x & bit == 1
highest = i
bit = bit * 2
return highest + 1
It doesn't matter how big x is, it always checks all 32 bits. Thus constant time.
If the input can be any integer size, say the input is n digits long. Then any solution reading the input, will read n digits and must be at least O(n). Unless someone comes up solution without reading the input, it is impossible to find a O(1) solution.

- 11,542
- 1
- 25
- 31
-
@lshtar this is not O(1). Read the question carefully `O(1) (not depended on size of integer and size of byte)` – Mihran Hovsepyan May 11 '11 at 10:33
-
@Mihran - That's the confusing part, you don't want it to depend on the size of the integer, but, you also mean a integer smaller or equal to a `unsigned int`. The pseudo code really does not depend on the size of the integer, assuming it is at most 32 bits. If I do `highestBit(1)` or `highestBit(MAX_INT)` running time is the same. – Ishtar May 11 '11 at 10:38
-
3this is an interesting way to achieve O(1) algorithms - always run in the worst case number of steps :) – davka May 11 '11 at 11:12
-
1@Oli Charlesworth: Actually it is. But I could not be bothered arguing about. That's we I deleted my comment. But my comment was based actually based on it not being dependent on the value of X. But then I reread the question and it was based on the sizeof(x). Technically its an abuse of O() notation as it its not really designed for this. Techncially big O() is used to measure how an algorithm changes in relation to the amount of data. Here the amount of data is always fixed sizeof(n) is constant. – Martin York May 11 '11 at 17:30
After some search in internet I found this 2 versions for 32 bit unsigned integer number. I have tested them and they work. It is clear for me why second one works, but still now I'm thinking about first one...
1.
unsigned int RoundUpToNextPowOf2(unsigned int v)
{
unsigned int r = 1;
if (v > 1)
{
float f = (float)v;
unsigned int const t = 1U << ((*(unsigned int *)&f >> 23) - 0x7f);
r = t << (t < v);
}
return r;
}
2.
unsigned int RoundUpToNextPowOf2(unsigned int v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
edit: First one in clear as well.

- 10,810
- 14
- 61
- 111
-
I don't exactly understand how this works, but clearly it does not fulfill your requirement of `not depended on size of integer and size of byte` – davka May 11 '11 at 11:10
-
@davka Actually this will help me because it is possible to write same algo for 64 bit integer and call the one is needed after checking size of integer. – Mihran Hovsepyan May 11 '11 at 11:12
-
still you need to assume upper limit on x which is not `not depended on size of integer` any more – davka May 11 '11 at 11:16
-
-
-
@James can you point, for what value it gives different result? – Mihran Hovsepyan May 11 '11 at 17:40
-
@Mihran Most of them. The function calculates 2^n, the value wanted is n. For the rest, see the comments in my response: using `float`, 2^31-1 and 2^31 will have the same value in the `float`. – James Kanze May 12 '11 at 08:43
An interesting question. What do you mean by not depending on the size of int or the number of bits in a byte? To encounter a different number of bits in a byte, you'll have to use a different machine, with a different set of machine instructions, which may or may not affect the answer.
Anyway, based sort of vaguely on the first solution proposed by Mihran, I get:
int
topBit( unsigned x )
{
int r = 1;
if ( x > 1 ) {
if ( frexp( static_cast<double>( x ), &r ) != 0.5 ) {
++ r;
}
}
return r - 1;
}
This works within the constraint that the input value must be exactly
representable in a double
; if the input is unsigned long long
, this
might not be the case, and on some of the more exotic platforms, it
might not even be the case for unsigned
.
The only other constant time (with respect to the number of bits) I can think of is:
int
topBit( unsigned x )
{
return x == 0 ? 0.0 : ceil( log2( static_cast<double>( x ) ) );
}
, which has the same constraint with regards to x
being exactly
representable in a double
, and may also suffer from rounding errors
inherent in the floating point operations (although if log2
is
implemented correctly, I don't think that this should be the case). If
your compiler doesn't support log2
(a C++11 feature, but also present
in C90, so I would expect most compilers to already have implemented
it), then of course, log( x ) / log( 2 )
could be used, but I suspect
that this will increase the risk of a rounding error resulting in
a wrong result.
FWIW, I find the O(1) on the number of bits a bit illogical, for the reasons I specified above: the number of bits is just one of the many "constant factors" which depend on the machine on which you run. Anyway, I came up with the following purely integer solution, which is O(lg 1) for the number of bits, and O(1) for everything else:
template< int k >
struct TopBitImpl
{
static int const k2 = k / 2;
static unsigned const m = ~0U << k2;
int operator()( unsigned x ) const
{
unsigned r = ((x & m) != 0) ? k2 : 0;
return r + TopBitImpl<k2>()(r == 0 ? x : x >> k2);
}
};
template<>
struct TopBitImpl<1>
{
int operator()( unsigned x ) const
{
return 0;
}
};
int
topBit( unsigned x )
{
return TopBitImpl<std::numeric_limits<unsigned>::digits>()(x)
+ (((x & (x - 1)) != 0) ? 1 : 0);
}
A good compiler should be able to inline the recursive calls, resulting in close to optimal code.

- 150,581
- 18
- 184
- 329
-
I find the `x
()(z)` syntax pretty awkward. Making `operator()` a `static` member function would turn that into the IMO more idiomatic `x – sbi May 11 '11 at 17:03::f(z)`. Oh, and making `x` a compile-time constant allows a pure compile-time solution. -
I find the syntax pretty awkward too, but making `operator()` static isn't an option, since the standard requires `operator()` to be non-static. Giving the function a name and making it static would probably be cleaner than what I wrote, but I was too lazy to think of a good name, and there's a long tradition for using `operator()` when you don't have a good name (and sometimes even when you do). – James Kanze May 12 '11 at 08:45