5

What is the most efficient way to find out how many bits are needed to represent some random int number? For example number 30,000 is represented binary with

111010100110000

So it needs 15 bits

Marka
  • 377
  • 1
  • 4
  • 17
  • Just convert to binary and could the length? – psubsee2003 Sep 10 '12 at 10:12
  • 1
    Divide number by 2 until result will less than 1.0 – opewix Sep 10 '12 at 10:13
  • 2
    @JesseJames might as well divide it by 2 until it is less than 1 (without the decimal point) so 0 - no reason to involve floating point when you're just shifting bits.. – harold Sep 10 '12 at 10:15
  • I believe that @JesseJames' method is much less expensive than counting log because I don't need exact decimal number which I then have to round. – Marka Sep 10 '12 at 10:22
  • IMO, every one asking a bit manipulation question should read first [bit twiddling hacks by sean aron anderson](http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog) – aka.nice Sep 10 '12 at 18:59

3 Answers3

10

You may try:

Math.Floor(Math.Log(30000, 2)) + 1

or

(int) Math.Log(30000, 2) + 1
petro.sidlovskyy
  • 5,075
  • 1
  • 25
  • 29
  • The `(int)` cast version of this answer has the best performance of all answers to this question. Just check for the edge case of zero beforehand. – Special Sauce Jan 29 '17 at 06:00
7
int v = 30000; // 32-bit word to find the log base 2 of
int r = 0; // r will be lg(v)

while ( (v >>= 1) != 0) // unroll for more speed...
{
  r++;
}

For more advanced methods, see here http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious

Note that this computes the index of the leftmost set bit (14 for 30000). If you want the number of bits, just add 1.

Henrik
  • 23,186
  • 6
  • 42
  • 92
  • This could be it. I will try it and compare it with other solutions. Thanks – Marka Sep 10 '12 at 10:23
  • I will not use negative numbers. Although, I could first compare chunks of 8bits. If its zero I would use another chunk. That should impact the performance. – Marka Sep 10 '12 at 10:34
3

Try log(number)/log(2). Then round it up to the next whole number.

Daniel Lidström
  • 9,930
  • 1
  • 27
  • 35