Shifting a Java BitSet

后端 未结 8 1568
太阳男子
太阳男子 2020-12-31 00:11

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 >

8条回答
  •  失恋的感觉
    2020-12-31 00:43

    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);
                }
            }
        }
    }
    

提交回复
热议问题