https://zhuanlan.zhihu.com/p/30108890
移位操作符格式:
value << 4
value左移4位
左移位数大于等于32位操作时,会先求余(%)后再进行左移操作。也就是说左移32位相当于不进行移位操作,左移40位相当于左移8位(40%32=8)。当long类型进行左移操作时,long类型在二进制中的体现是64位的,因此求余操作的基数也变成了64,也就是说左移64位相当于没有移位,左移72位相当于左移8位(72%64=8)
综上所述:左移 << 其实很简单,也就是说丢弃左边指定位数,右边补0。
value >> 4
value右移4位
和左移一样,int类型移位大于等于32位时,long类型大于等于64位时,会先做求余处理再位移处理,byte,short移位前会先转换为int类型(32位)再进行移位。
综上所述:右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上符号位。
value>>>4
value无符号右移4位
无符号右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上0。
对变量做移位运算并将结果赋值给变量 >>>=, <<=
int i = 1;
i >>>= 1; // 1右移1位,并将移位结果复制给i.
int j = 1;
j >>>1; // 1右移1位,j还是1
int i = 1;
// System.out.println(Integer.toBinaryString(i)); // 0B1
int n = 1;
// System.out.println(Integer.toBinaryString(i >>> 16)); // 0B0
int i1 = i >>> 16;
System.out.println("i1 = " + i1);//i1 = 0
if (i1 == 0) {
// 变量i 并没有变成 i>>>16的结果; i还是1
System.out.println("i1=0 " + Integer.toBinaryString(i)); //i1=0 1
n += 16;
i <<= 16;
}
Integer.numberOfLeadingZeros方法
numberOfLeadingZeros(1);// 看看1有多少0
// 算出32位中, 第一个位是1的, 之前的一共有多少个0
public static int numberOfLeadingZeros(int i) {
// HD, Figure 5-6
if (i == 0)
return 32;
int n = 1;
// 以高16位和低16位作为分界线
// 如果高16位不为全为0, 则对高16位的, 之后再将高16位,以高8位, 低8位作为分界线, 在以高4位, 低4位作为分界线, 再以高2位, 低2位作为分界线, 最后还剩1位。
// 如果高16位全为0, 则对低16位的,之后再将高16位,以高8位, 低8位作为分界线, 在以高4位, 低4位作为分界线, 再以高2位, 低2位作为分界线, 最后还剩1位。
if (i >>> 16 == 0) // 从变量i中读取出1, 对1做无符号右移16位, 变量i仍然是1
{
n += 16;
i <<= 16; // 1左移16位, 然后将结果赋值给i
}
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}