tags:

views:

203

answers:

5

I am calculating the int equivalent of a given set of bits and storing that in memory. From there, I would like to determine all 1 value bits from the original bitmask. Example:

33 --> [1,6]
97 --> [1,6,7]

Ideas for an implementation in Java?

+1  A: 

I can show you C# implementation, Java should be very similar.

int value = 33;
int index = 1;

while (value > 0)
{
   if ((value % 2) == 1)
      Console.WriteLine(index);

   index++;
   value /= 2;
}
František Žiačik
Replace `Console.WriteLine` with `System.out.println` and voila :-)
Péter Török
+1  A: 

If you want to get an array like that you'll likely need to loop the number of bits you want to check & the integer with a bit shifted 1 for each step.

Something like (pseudo):

Init array
mask = 1
for (0 to BitCount):
  if Integer & mask
    array[] = pos
  mask << 1
Matt S
+1  A: 

A bit-crunching variation would be something like:

int[] getBits(int value) {
  int bitValue = 1;
  int index = 1;
  int[] bits = new int[33];

  while (value >= bitValue)
  {
    bits[index++] = (value & bitValue);
    bitValue << 1; // or: bitValue *= 2;
  }
  return bits;
}

Note that since the bits are indexed from 1 as you requested, bits[0] is left unused.

Péter Török
+3  A: 

On BitSet

Use java.util.BitSet to store, well, a set of bits.

Here's how you can convert from an int to a BitSet, based on which bits in the int is set:

static BitSet fromInt(int num) {
    BitSet bs = new BitSet();
    for (int k = 0; k < Integer.SIZE; k++) {
        if (((num >> k) & 1) == 1) {
            bs.set(k);
        }
    }
    return bs;
}

So now you can do the following:

System.out.println(fromInt(33)); // prints "{0, 5}"
System.out.println(fromInt(97)); // prints "{0, 5, 6}"

And just for completeness, here's the reverse transformation:

static int toInt(BitSet bs) {
    int num = 0;
    for (int k = -1; (k = bs.nextSetBit(k + 1)) != -1; ) {
        num |= (1 << k);
    }
    return num;
}

So composing both together, we always get back the original number:

System.out.println(toInt(fromInt(33))); // prints "33"
System.out.println(toInt(fromInt(97))); // prints "97"

On 0-based indexing

Note that this uses 0-based indexing, which is the more commonly used indexing for bits (and most everything else in Java). This is also more correct. In the following, ^ denotes exponentiation:

33 = 2^0 + 2^5 = 1 + 32          97 = 2^0 + 2^5 + 2^6 = 1 + 32 + 64
33 -> {0, 5}                     97 -> {0, 5, 6}

If you insist on using 1-based indexing, however, you can use bs.set(k+1); and (1 << (k-1)) in the above snippets. I would advise strongly against this recommendation, however.

Related questions

polygenelubricants
+2  A: 

For bit fiddling, java.lang.Integer has some very helpful static methods. Try this code as a starting base for your problem:

public int[] extractBitNumbers(int value) {
    // determine how many ones are in value
    int bitCount = Integer.bitCount(value);
    // allocate storage
    int[] oneBits = new int[bitCount];
    int putIndex = 0;
    // loop until no more bits are set
    while (value != 0) {
        // find the number of the lowest set bit
        int bitNo = Integer.numberOfTrailingZeros(value);
        // store the bit number in array
        oneBits[putIndex++] = bitNo+1; 
        // clear the bit we just processed from the value
        value &= ~(1 << bitNo);      
    }
    return oneBits;
}
Durandal