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 >>>
on ints.
Is there a library function that shifts BitSet
s?
If not, is there a better way than the below?
public static void logicalRightShift(BitSet bs) { for (int i = 0; (i = bs.nextSetBit(i)) >= 0;) { // i is the first bit in a run of set bits. // Set any bit to the left of the run. if (i != 0) { bs.set(i - 1); } // Now i is the index of the bit after the end of the run. i = bs.nextClearBit(i); // nextClearBit never returns -1. // Clear the last bit of the run. bs.clear(i - 1); // 0000111100000... // a b // i starts off the loop at a, and ends the loop at b. // The mutations change the run to // 0001111000000... } }
The BitSet class creates a special type of array that holds bit values. The BitSet array can increase in size as needed. This makes it similar to a vector of bits. This is a legacy class but it has been completely re-engineered in Java 2, version 1.4.
As for other differences, obviously the API is different. BitSet provides a number of bitwise operations that you may need to use. A boolean array is an array. The one that works best for you will depend on your specific application requirements.
Creates a bit set whose initial size is large enough to explicitly represent bits with indices in the range 0 through nbits-1 . All bits are initially false .
A BitSet is a very efficient for a set of non-negative integers within a (not too large) range. Much more efficient than arrays and hash maps. An EnumSet is implemented the same way as a BitSet .
That should do the trick:
BitSet shifted = bs.get(1, bs.length());
It will give you a bitset equal to the orginial one, but without the lower-most bit.
EDIT:
To generalize this to n
bits,
BitSet shifted = bs.get(n, Math.max(n, bs.length()));
An alternative which is probably more efficient would be to work with the underlying long[].
Use bitset.toLongArray()
to get the underlying data. Shift those longs accordingly, then create a new BitSet via BitSet.valueOf(long[])
You'll have to be very careful shifting the underlying longs, as you will have to take the low order bit and shift it into the high order bit on the next long in the array.
This should let you use the bit shift operations native on your processor to move 64 bits at a time, as opposed to iterating through each one separately.
EDIT: Based on Louis Wasserman's comment. This is only available in Java 1.7 API. Didn't realize that when I wrote it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With