框架乱飞的年代,时常还得往框架源码里看,对内在原理没点理解,人家就会认为你不太行。平时开发你可能没咋用过位移运算,但往源码里一看,就时常能看到它。我也是看着看着,突然仔细一琢磨,又不由得发现自己基础知识不扎实,得,又得给自己补一课。
类型
算术移位:不改变符号位的移位操作
逻辑移位:不考虑符号位,所有的位数都要进行移位
java里有三种移位运算符<<,>>,>>>,照上面的定义所说,那<<,>>属于算术移位,>>>属于逻辑移位。
规则
>>右移,当符号位是1,高位补1,反之则补0,低位丢弃。
>>>无符号右移,高位补0,低位丢弃。
<<左移,低位补0,高位丢弃
所有计算都是先转为补码,移动n位就相当于,移动n%32位或n%64位
移位运算有两种,一种是int类型的,一种是long类型的,像byte、char、short数据都会转成int类型再计算
以上规则是我个人的一点小总结,我现在有点疑问的是,所谓的算术移位(<<和>>)的时候,符号位究竟要不要变?下面我们用例子来说话。
代码:
//000000000 00000000 00000000 00000010 //2的原码和补码
//100000000 00000000 00000000 00000010 //-2的原码
//111111111 11111111 11111111 11111110 //-2的补码
// 右移
System.out.println(2>>1);
System.out.println(2>>31);
System.out.println(2>>32);
System.out.println(-2>>1);
System.out.println(-2>>31);
System.out.println(-2>>32);
System.out.println("*********************************************************************");
// 无符号右移
System.out.println(2>>>1);
System.out.println(2>>>31);
System.out.println(2>>>32);
System.out.println(-2>>>1);
System.out.println(-2>>>31);
System.out.println(-2>>>32);
System.out.println("*********************************************************************");
// 左移
System.out.println(2<<1);
System.out.println(2<<31);
System.out.println(2<<32);
System.out.println(-2<<1);
System.out.println(-2<<31);
System.out.println(-2<<32);
>>右移
>>>无符号右移
<<左移
由此可见,左移、右移、无符号右移,符号位都是会移动的,也就是会变的。所以<<,>>算是逻辑移位了?还专门去找了尚硅谷的韩顺平老师的视频中相关视频看了下,他说的<<,>>是算术位移,符号位不变,但是我自己代码验证结果是符号位是会移动的,这?
算了,我也不纠结这个了,我只记着上面总结出来的规则来进行计算,能得到正确的结果就行了。看文章的朋友如有见解还请评论区透露一二,大家研究一下 ┗( ▔, ▔ )┛