15

I have the following:

int num=Integer.parseInt(lineArray[0]);
byte numBit= num & 0xFF;

Is there any very simple way to convert numBit to a bit array? Or even better, is there a way to bypass the byte conversion of the int and go straigh from num to a bit array?

Thanks

moesef
  • 4,641
  • 16
  • 51
  • 68
  • 2
    I guess this will for in your case too... [Stackoverflow - Bitset to and from Integer Long][1] [1]: http://stackoverflow.com/questions/2473597/bitset-to-and-from-integer-long – Pr0gr4mm3r Aug 05 '12 at 22:05
  • 1
    Do you mean `boolean[]` or `BitSet`? – dacwe Aug 05 '12 at 22:06

5 Answers5

14

If you want a BitSet, try:

final byte b = ...;
final BitSet set = BitSet.valueOf(new byte[] { b });

If you want a boolean[],

static boolean[] bits(byte b) {
  int n = 8;
  final boolean[] set = new boolean[n];
  while (--n >= 0) {
    set[n] = (b & 0x80) != 0;
    b <<= 1;
  }
  return set;
}

or, equivalently,

static boolean[] bits(final byte b) {
  return new boolean[] {
    (b &    1) != 0,
    (b &    2) != 0,
    (b &    4) != 0,
    (b &    8) != 0,
    (b & 0x10) != 0,
    (b & 0x20) != 0,
    (b & 0x40) != 0,
    (b & 0x80) != 0
  };
}
obataku
  • 29,212
  • 3
  • 44
  • 57
  • I came across this answer and wanted to note that the `BitSet.valueOf()` methods are only in Java 7 and later. The question didn't specify a Java version, but if you are in Java 6, you should be able to take one of the approaches to create a boolean[] to populate a BitSet object. – Thomas Owens Jan 23 '15 at 16:06
  • 1
    Shouldn't it be `set[n] = (b & 0x80) != 0;` in your 2nd snippet? And you need to post-increment in your while loop: `while (n-- > 0)`. Otherwise you're skipping bit 0. – Jaykob Nov 03 '15 at 13:05
5

Java 7 has BitSet.valueOf(long[]) and BitSet.toLongArray()

int n = 12345;
BitSet bs = BitSet.valueOf(new long[]{n});
Grigory Kislin
  • 16,647
  • 10
  • 125
  • 197
1

You could do:

char[] bits = Integer.toBinaryString(num).toCharArray(); to get the underlying bit string as a char[]

E.g.

public BitSet getBitSet(int num){
    char[] bits = Integer.toBinaryString(num).toCharArray();  
    BitSet bitSet = new BitSet(bits.length);  
    for(int i = 0; i < bits.length; i++){  
        if(bits[i] == '1'){
            bitSet.set(i, true);
        }
        else{
            bitSet.set(i, false);
        }                
    }
    return bitSet;
}  

You could create boolean [] array also this way.

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • 1
    You're doing double work here -- `toBinaryString()` iterates over the bits too. You'd be better of with looping while `i < Integer.SIZE` and a direct bit test `0 < (num & 1 << i)`. Not to mention that bits in a fresh `BitSet` are pre-set to `false`. Simply put, your code is both verbose and inefficient. – charlie Jul 04 '16 at 10:28
0

I came about this thread because Android added the BitSet.valueOf()as late as in API 19. I used oldrinb's 2nd snippet of the accepted answer but had to modify it because it had some errors. Additionally I modified it to return a BitSet, but it shouldn't be a problem to change it to boolean[]. See my comment to his reply.

This is the modification that now runs successfully:

public static BitSet toBitSet(byte b) {
    int n = 8;
    final BitSet set = new BitSet(n);
    while (n-- > 0) {
        boolean isSet = (b & 0x80) != 0;
        set.set(n, isSet);
        b <<= 1;
    }
    return set;
}
Jaykob
  • 323
  • 2
  • 10
0

Just an excercise in using streams (J8+):

// J7+
BitSet bitSet(final long... nums) {
    return BitSet.valueOf(nums);
}

// J8+
final IntStream bitsSet = bitSet(num).stream();

// vice-versa
BitSet bitSet(final IntStream bitsSet) {
    return bitsSet.collect(BitSet::new, BitSet::set, BitSet::or);
}

// without BitSet
IntStream bitsSet(final long... nums) {
    return IntStream.range(0, nums.length)
            .flatMap(n -> IntStream.range(0, Long.SIZE - 1)
                    .filter(i -> 0 != (nums[n] & 1L << i))
                    .map(i -> i + n * Long.SIZE));
}
charlie
  • 1,478
  • 10
  • 20