Shifting a Java BitSet

后端 未结 8 1593
太阳男子
太阳男子 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:46

    These functions mimic the << and >>> operators, respectively.

    /**
     * Shifts a BitSet n digits to the left. For example, 0b0110101 with n=2 becomes 0b10101.
     *
     * @param bits
     * @param n the shift distance.
     * @return
     */
    public static BitSet shiftLeft(BitSet bits, int n) {
        if (n < 0)
            throw new IllegalArgumentException("'n' must be >= 0");
        if (n >= 64)
            throw new IllegalArgumentException("'n' must be < 64");
    
        long[] words = bits.toLongArray();
    
        // Do the shift
        for (int i = 0; i < words.length - 1; i++) {
            words[i] >>>= n; // Shift current word
            words[i] |= words[i + 1] << (64 - n); // Do the carry
        }
        words[words.length - 1] >>>= n; // shift [words.length-1] separately, since no carry
    
        return BitSet.valueOf(words);
    }
    
    /**
     * Shifts a BitSet n digits to the right. For example, 0b0110101 with n=2 becomes 0b000110101.
     *
     * @param bits
     * @param n the shift distance.
     * @return
     */
    public static BitSet shiftRight(BitSet bits, int n) {
        if (n < 0)
            throw new IllegalArgumentException("'n' must be >= 0");
        if (n >= 64)
            throw new IllegalArgumentException("'n' must be < 64");
    
        long[] words = bits.toLongArray();
    
        // Expand array if there will be carry bits
        if (words[words.length - 1] >>> (64 - n) > 0) {
            long[] tmp = new long[words.length + 1];
            System.arraycopy(words, 0, tmp, 0, words.length);
            words = tmp;
        }
    
        // 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
    
        return BitSet.valueOf(words);
    }
    

提交回复
热议问题