简单的我们知道左移一位表示乘以2,像1<<2=4。但是左移个几百位呢?1<<100=??
一个int占32位,一个long才占64位,左移几百位真要乘这么多2的话,肯定是存不下的。比如以下代码:
System.out.println("1 << 100 = " + (1 << 100));
System.out.println("1L << 100 = " + (1L << 100));
按照我们的猜测的话,左移高位可能会被舍弃,所以只要左移超过最大的位数结果应该是0,但是上述代码的结果为:
1 << 100 = 16 1L << 100 = 68719476736
我们看到,100位已经超过int和long的最大位数了,但是左移的结果并不是0。根据结果我们能猜的出来,虚拟机在做移位操作的时候对移位位数根据当前数据类型做了取余操作。也就是如果是int类型变量左移,会把需要左移的位数和32取余,long类型变量则会根据64位取余:
1 << n == 1 << (n % 32)
1L << n == 1 << (n % 64)
我们看一下以下代码:
System.out.println("1 << (100 % 32) = " + (1 << (100 % 32)));
System.out.println("1 << 100 = " + (1 << 100));
System.out.println("1L << 100 = " + (1L << 100));
System.out.println("1L << (100 % 64) = " + (1L << (100 % 64)));
输出为:
1 << (100 % 32) = 16
1 << 100 = 16
1L << 100 = 68719476736
1L << (100 % 64) = 68719476736
注:特别要注意,像byte类型的变量在做移位等操作的时候会将其转换为int,所以在操作的时候需要注意。感兴趣的同学可以试验一下。