5

How do I get the position, rather than the value, of the highest one bit in integer? I know I can get the value like this:

// Prints 8; in 1101, the highest bit is the one denoting 8
int f = 13;
System.out.println("Highest: " + Integer.highestOneBit(f));

However, I'd like to get position of the highest one bit - in this case, it would be 4 (since 1000 in binary == 8, the highest one bit is the fourth one).

manabreak
  • 5,415
  • 7
  • 39
  • 96

3 Answers3

3

Just combine it with numberOfTrailingZeros:

int pos = Integer.numberOfTrailingZeros(Integer.highestOneBit(f))
xs0
  • 2,990
  • 17
  • 25
  • This is exactly what I was looking for, thanks! – manabreak Dec 11 '17 at 13:36
  • Well, you said you were expecting "4", however this answer gives "3". – Yassine Badache Dec 11 '17 at 13:39
  • Meh, the offset is not that important. – manabreak Dec 11 '17 at 15:02
  • 32 - Integer.numberOfLeadingZeros(f) works better. If f = 0, then it yields 0 as well, instead of 32 like in the solution. – Kellen McClain Sep 25 '18 at 13:26
  • @KellenMcClain but isn't it somewhat awkward to have the same result for both f=0 and f=1? – xs0 Sep 26 '18 at 10:28
  • @xs0 Ah, it actually outputs 0 for f = 0 and 1 for f = 1, 2 for f = 2, etc. So it's 1+ the index. Do 31 - Integer.numberOfLeadingZeros(f) for the actual index, which outputs -1 for f = 0, kinda like how String#indexOf outputs -1 when it doesn't find the character. Anyway, what I wrote before was what I needed; it was the number of bits to shift if I wanted to "push" a number between 0 and f into the least significant bits of another number x. (I was given f + 1, ie, the number of numbers.) – Kellen McClain Oct 31 '18 at 21:11
2

Well, we can do this mathematically.

We basically want to get 4 from 8, 3 from 4, 2 from 2, 1 from 1, etc.

That is basically doing a log2 on the number and adding 1 to it. There is no log2 function in the java.lang.Math class, but as you may know:

logx(y) = log10(y) / log10(x)

so we can just do this!

(Math.log10(Integer.highestOneBit(f)) / Math.log10(2)) + 1
Sweeper
  • 213,210
  • 22
  • 193
  • 313
-2

You may want to convert your Integer to a String using Integer.toBinaryString, then returning its length.

For instance:

String binaryString = Integer.toBinaryString(13);
System.out.println(binaryString.length()); <== gives 4

Since there won't be any leading zeros.

Yassine Badache
  • 1,810
  • 1
  • 19
  • 38
  • What's wrong with this answer ? – Yassine Badache Dec 11 '17 at 13:37
  • At least it gives the correct answer. The downvotes are pretty inefficient, too. – Yassine Badache Dec 11 '17 at 13:40
  • Yes, but why do unnecessary conversions between data types and waster computation time and memory when you achieve the same thing with twiddlin' some bits? – manabreak Dec 11 '17 at 13:40
  • Well, I don't know your use case, but if you need to convert one data from Integer to String, I really think the JVM won't mind considering the near-nonexistent time AND memory. Once again, only an answer, which at least gives the right result. – Yassine Badache Dec 11 '17 at 13:42