clankill3r
clankill3r

Reputation: 9543

The Inverse of a bit-shift to the left in the format 1 << n

Let's say I have the following bit masks:

1 << 1, // 2
1 << 2, // 4 
1 << 3, // 8 
1 << 4, // 16 
1 << 5, // 32 
1 << 6  // 64

I would like to get the 'inverse'.

This does the job:

void foo(int n) {
  int c = 1;
  while (n/2 >= 2) {
    n /= 2;  
    c++;;
  }
  println(c);
}

For example, 1 << 4 resulted in 16. If I run foo(16) it prints 4. However, I feel like it could be done a lot simpler, but I can't figure out how.

Is it possible?

Upvotes: 5

Views: 467

Answers (3)

talex
talex

Reputation: 20455

Slightly faster and not depend on value itself.

UPDATED version

private static int foo2(int value) {
    int result = 0;

    int mask = 0xFFFF;
    int shift = 1<<4;
    for (int j = 0; j < 5; j++) {
        result <<= 1;
        if ((value & mask) == 0) {
            result |= 1;
            value >>>= shift;
        }
        shift >>>= 1;
        mask >>= shift;
    }
    return result;
}

Upvotes: 1

OldCurmudgeon
OldCurmudgeon

Reputation: 65811

BigInteger has many useful methods - including getLowestSetBit(). It probably does it as fast as it can possibly be done.

public void test() {
    System.out.println(BigInteger.valueOf(16).getLowestSetBit());
}

Upvotes: 2

Adam
Adam

Reputation: 2440

void foo(int n)
{
    println( (Math.log(n) / Math.log(2))); 
    //cast to int with (int) to take off decimal place
}

Returns the "inverse" bitshift as you are calling it, the base 2 logarithm.

Upvotes: 1

Related Questions