I am using a java.util.BitSet
to store a dense vector of bits.
I want to implement an operation that shifts the bits right by 1, analogous to >
In order to achieve better performance you can extend java.util.BitSet implementation and avoid unnecessary array copying. Here is implementation (I've basically reused Jeff Piersol implementation):
package first.specific.structure;
import java.lang.reflect.Field;
import java.util.BitSet;
public class BitSetMut extends BitSet {
private long[] words;
private static Field wordsField;
static {
try {
wordsField = BitSet.class.getDeclaredField("words");
wordsField.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new IllegalStateException(e);
}
}
public BitSetMut(final int regLength) {
super(regLength);
try {
words = (long[]) wordsField.get(this);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public void shiftRight(int n) {
if (n < 0)
throw new IllegalArgumentException("'n' must be >= 0");
if (n >= 64)
throw new IllegalArgumentException("'n' must be < 64");
if (words.length > 0) {
ensureCapacity(n);
// Do the shift
for (int i = words.length - 1; i > 0; i--) {
words[i] <<= n; // Shift current word
words[i] |= words[i - 1] >>> (64 - n); // Do the carry
}
words[0] <<= n; // shift [0] separately, since no carry
// recalculateWordInUse() is unnecessary
}
}
private void ensureCapacity(final int n) {
if (words[words.length - 1] >>> n > 0) {
long[] tmp = new long[words.length + 3];
System.arraycopy(words, 0, tmp, 0, words.length);
words = tmp;
try {
wordsField.set(this, tmp);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
}
}