Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shifting a Java BitSet

Tags:

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 BitSets?

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...   } } 
like image 480
Mike Samuel Avatar asked Jan 25 '12 18:01

Mike Samuel


People also ask

How does BitSet work in Java?

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.

What is the difference between a regular array and a BitSet in Java?

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.

How does a BitSet work?

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 .

Why do we use BitSet?

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 .


2 Answers

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())); 
like image 64
Philipp Wendler Avatar answered Oct 06 '22 01:10

Philipp Wendler


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.

like image 24
rfeak Avatar answered Oct 06 '22 00:10

rfeak