按位运算符

时间:2016-12-01 07:33:15

标签: java bit-manipulation

由于某种原因,以下两个按位运算提供了不同的结果,但它们应该提供相同的结果似乎是直观的,因为使用的掩码应该是相同的。我在这里错过了什么?为什么使用这两个面具的结果会有所不同?

public class BitShiftTest {

    private long bitString = -8784238533840732024L ;
    private final int MAX_BITS_POSITION = 63 ;

    public static void main(String[] args) {
        BitShiftTest bst = new BitShiftTest() ;
        System.out.printf("Before applying mask: %s\n", Long.toBinaryString(bst.bitString));
        System.out.printf("Using Mask 1: %s\n", Long.toBinaryString(bst.clearBitMask(60)));
        System.out.printf("Using Mask 2: %s\n", Long.toBinaryString(bst.clearBitMaskAlternative(60)));
    }

    public long clearBitMask(int position) {
        return bitString & ~(1 << position) ;
    }

    public long clearBitMaskAlternative(int position) {
        return bitString & (0x8000000000000000L >>> MAX_BITS_POSITION - position) ;
    }
}

产生的结果是

Before applying mask: 1000011000011000000111011001100000101000001000000000000010001000
Using Mask 1: 1000011000011000000111011001100000101000001000000000000010001000
Using Mask 2: 0

2 个答案:

答案 0 :(得分:0)

您假设~(1<<position)0x8000000000000000L >>> MAX_BITS_POSITION - position相等,但这不是真的。

基本上,您在替代案例中错过了~ - 否则看起来您只是想提取一位,而不仅仅是清除它。它应该是:

~(0x8000000000000000L >>> MAX_BITS_POSITION - position)

但是,正如@RolandIllig 1 << position所指出的那样,实际上是在int算术中完成的。您在输出中没有看到这一点,因为在您屏蔽的长时间内都没有设置第60位或第28位。 1L << position解决了这个问题。

答案 1 :(得分:0)

1 << 63属于int类型,因此等于Integer.MIN_VALUE,因为1移出了数字。 (在其他语言中,结果将是未定义的,因为您移位的位数多于int的位数。

要解决此问题,请使用1L << 63long