I have a bitset with 100000 number of bits. I want to shift it to the right and to the left as efficiently as possible. I guess there is no function in BitSet class to shift bits, so I tried converting them into long array using toLongArray()
but as expected it gives overflow.
A temporary solution which I found was to convert bitset into BigInteger and then shift the BigInteger and then convert BigInteger back to bitset, but that is very slow.
So my questions are:
- Is there any better way to shift a bitset (by shifting I mean both left and right shift)
- When I convert a bitset with number of bits greater than 64, into long array, I get negatives in the array. Why is there a function
toLongArray()
in the first place when BitSet can only represent bits of 1 number. Please correct me if I am wrong.
Following is the code to using BigInteger.
public static BitSet toBitSet(BigInteger val) {
if(val.signum() < 0)
throw new IllegalArgumentException("Negative value: " + val);
return BitSet.valueOf(reverse(val.toByteArray()));
}
static byte[] reverse(byte[] bytes) {
for(int i = 0; i < bytes.length/2; i++) {
byte temp = bytes[i];
bytes[i] = bytes[bytes.length-i-1];
bytes[bytes.length-i-1] = temp;
}
return bytes;
}
public static BigInteger toBigInteger(BitSet val) {
return new BigInteger(1, reverse(val.toByteArray()));
}
public static BitSet shiftLeft(BitSet bits, int n) {
BigInteger temp= toBigInteger(bits);
temp= temp.shiftLeft(n);
return toBitSet(temp);
}
PS: All answers that I found were for number of bits <= 64
List<Boolean>
instead, e.g. aLinkedList<Boolean>
should be the most efficient data structure for shifting as you can do the shift operations by inserting/removing elements inO(1)
. – Robertlong[]
for storing the bits. Hence by callingtoLongArray()
you just get a copy of the internal representation. – Robertlong[]
then I guess it makes sense to get an array filled with -ve values in case of overflow. – Ojasv singh