1、位运算-左移、右移
1.1、左移"<<"
1.1.1、 int、long类型
对于int类型来说,其二进制位为32位,所以每32位取一次模。我们来看下面的代码
public static void Test1(){
//
//00000000 00000000 00000000 00000001 1的三码
//00000000 00000000 00000000 00001 左移3位之后
System.out.println("int类型左移3位:"+(1<<35));
System.out.println("int类型左移3位:"+(1<<3));
System.out.println("int类型左移3位:"+(-1<<35));
System.out.println("int类型左移3位:"+(-1<<3));
}
你会发现,1<<35的值与1<<3的值相等,就是因为它在移到第32位的时候进行了取模(可以把它理解为一次循环,超过int的最大进制位,那么就重新回到0),所以它最后的结果其实就相当于左移了(35-32)位。
同理,long类型为64位数据类型,所以是每64位进行一次取模。
1.1.2、byte、short类型
对于byte、short这类较小的类型,上面的使用并不适合它们,原则上,在java语言中,像byte、short这种小数据类型是属于"二等公民",他们拥有的权利要小于int、long这些"一等公民",在java虚拟机中的指令集中,也就没有给它们分配相对应的指令,故而,我们在使用它们的时候,java虚拟机会默认将它们转换int类型,
根据上面的分析,我们来进行代码测试
byte b = 1;
System.out.println("byte类型左移3位:"+(b<<3));
System.out.println("byte类型左移11位:"+(b<<11));
//上下对比
System.out.println("byte类型左移3位:"+(b<<3));
System.out.println("byte类型左移超过8位转变位int类型,故左移35和int相同:"+(b<<35));
System.out.println("-------------------------------------------");
short s = 2;
System.out.println("short类型左移3位"+(s<<3));
System.out.println("short类型左移19位"+(s<<19));
//上下对比
System.out.println("short类型左移3位"+(s<<3));
System.out.println("short类型左移35位"+(s<<35));
通过运行结果,你会发现,short和byte在实际的运算过程中已经转变成了32位的int类型。故而,对于byte和short这类较小的类型,我们需要按照int的位数来进行运算。
1.2、右移">>"
对于上面的数据类型问题这里不再过多赘述,这里我们只分析右移的特性。
我们来看下面一段代码:
//正数
System.out.println("int类型右移4位:"+(1>>4));
System.out.println("int类型右移4位:"+(2>>4));
System.out.println("int类型右移4位:"+(3>>4));
System.out.println("int类型右移4位:"+(4>>4));
System.out.println("int类型右移4位:"+(10>>4));
System.out.println("int类型右移4位:"+(15>>4));
//负数
System.out.println("int类型右移3位:"+(-2>>3));
System.out.println("int类型右移3位:"+(-3>>3));
通过运行可以发现,他们的值都是一样的,对此,我们可以推论出:当一个数去进行右移运算,那么,如果这个数在右移位数所能表示的数的范围中,那么这个数右移的结果一定为0(正数)或-1(负数)





