BitSet to and from integer/long

JavaBit ManipulationBitset

Java Problem Overview


If I have an integer that I'd like to perform bit manipulation on, how can I load it into a java.util.BitSet? How can I convert it back to an int or long? I'm not so concerned about the size of the BitSet -- it will always be 32 or 64 bits long. I'd just like to use the set(), clear(), nextSetBit(), and nextClearBit() methods rather than bitwise operators, but I can't find an easy way to initialize a bit set with a numeric type.

Java Solutions


Solution 1 - Java

The following code creates a bit set from a long value and vice versa:

public class Bits {

  public static BitSet convert(long value) {
    BitSet bits = new BitSet();
    int index = 0;
    while (value != 0L) {
      if (value % 2L != 0) {
        bits.set(index);
      }
      ++index;
      value = value >>> 1;
    }
    return bits;
  }

  public static long convert(BitSet bits) {
    long value = 0L;
    for (int i = 0; i < bits.length(); ++i) {
      value += bits.get(i) ? (1L << i) : 0L;
    }
    return value;
  }
}

EDITED: Now both directions, @leftbrain: of cause, you are right

Solution 2 - Java

Add to finnw answer: there are also BitSet.valueOf(long[]) and BitSet.toLongArray(). So:

int n = 12345;
BitSet bs = BitSet.valueOf(new long[]{n});
long l = bs.toLongArray()[0];

Solution 3 - Java

Java 7 has BitSet.valueOf(byte[]) and BitSet.toByteArray()

If you are stuck with Java 6 or earlier, you can use BigInteger if it is not likely to be a performance bottleneck - it has getLowestSetBit, setBit and clearBit methods (the last two will create a new BigInteger instead of modifying in-place.)

Solution 4 - Java

To get a long back from a small BitSet in a 'streamy' way:

long l = bitSet.stream()
        .takeWhile(i -> i < Long.SIZE)
        .mapToLong(i -> 1L << i)
        .reduce(0, (a, b) -> a | b);

Vice-versa:

BitSet bitSet = IntStream.range(0, Long.SIZE - 1)
        .filter(i -> 0 != (l & 1L << i))
        .collect(BitSet::new, BitSet::set, BitSet::or);

N.B.: Using BitSet::valueOf and BitSet::toLongArray is of course easier.

Solution 5 - Java

Pretty much straight from the documentation of nextSetBit

value=0;
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
 value += (1 << i)
 }

Solution 6 - Java

Isn't the public void set(int bit) method what your looking for?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionataylorView Question on Stackoverflow
Solution 1 - JavaArne BurmeisterView Answer on Stackoverflow
Solution 2 - JavaGrigory KislinView Answer on Stackoverflow
Solution 3 - JavafinnwView Answer on Stackoverflow
Solution 4 - JavacharlieView Answer on Stackoverflow
Solution 5 - Javauser3799584View Answer on Stackoverflow
Solution 6 - JavakukudasView Answer on Stackoverflow