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