最近在看Integer源码,发现了一个方法使用了位运算,尤其是为运算的右侧为负值,所以小小的进一步研究了一下
public static int rotateLeft(int i, int distance) {
return (i << distance) | (i >>> -distance);
}
在这个方法里面发现了一个位运算 i >>> -distance, 如果distance为正整数,那么-distance就是负数,而此时位运算是如何执行的:
在这个方法上面有一段这样的注释:
- Note also that rotation by any multiple of 32 is a no-op, so all but the last five bits of the rotation distance can be ignored, even if the distance is negative: {@code rotateLeft(val, distance) == rotateLeft(val, distance & 0x1F)}.
- 意思是说:按任意32的倍数旋转是无操作(没有改变的),因此即使距离为负,也可以忽略旋转距离的最后五位以外的所有位:{@ code rotateLeft(val,distance)== rotateLeft( val,distance&0x1F)}。更直接的说就是 i >>> -distance = i >>> -distance & 0x1f
我在IDE上做了一个测试如下:
/**
* 0111 1111 1111 1111 1111 1111 1111 1111 Integer.MAX_VALUE
* 0000 0000 0000 0000 0000 0000 0000 0011 Integer.MAX_VALUE >>> -3
* 0000 0000 0000 0000 0000 0000 0000 0011 Integer.MAX_VALUE >>> -35
* 0000 0000 0000 0000 0000 0000 0000 0011 Integer.MAX_VALUE >>> -67
* 1111 1111 1111 1111 1111 1111 1111 1101 -3
* 0000 0000 0000 0000 0000 0000 0001 1111 0x1f
* 0000 0000 0000 0000 0000 0000 0001 1101 -3 & 0x1f 29
*/
@Test
public void testInteger() {
Integer a = Integer.MAX_VALUE;
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(a >>> -3));
System.out.println(Integer.toBinaryString(a >>> -35));
System.out.println(Integer.toBinaryString(a >>> -67));
System.out.println(Integer.toBinaryString(-3));
}
所以得到的结论是 i >>> -distance = i >>> -distance & 0x1f