前言
开始之前,先回顾一下二进制原码、反码和补码之间的转换及计算机怎么处理二进制的。
二进制的最高位是符号位:0代表正数,1代表负数;
正数的原码,反码,补码都一样(三码合一);
负数的反码=它的原码符号不变,其他位取反;
负数的补码=它的反码+1(负数的反码=负数的补码-1);
0的反码、补码都是0;
Java没有无符号数;
在计算机底层运算的时候,都是以补码的方式来运算的;
当我们看运算结果的时候,看的是它的原码。
位运算符
按位与&:两位全为1,结果为1,否则为0;
按位或|:两位至少一个为1,则为1,否则为0;
按位异或^:两位不同,则为1,相同为0;
按位取反~:0->1,1->0;
算术右移>>:低位溢出,符号位不变,并用符号位补溢出的高位;
算术左移<<:符号位不变,低位补0;
逻辑右移(无符号右移)>>>:低位溢出,高位补0。(注意没有<<<)
运算推算
publicclassBitOperator02{publicstaticvoidmain(String[]args){System.out.println(1>>2);//0}}
1>>2,1算术右移:低位溢出,符号位不变,并用符号位补溢出的高位(注意:计算机操作的始终是补码)
正数的三码合一,1的补码:00000000 00000000 00000000 00000001
1>>2的原码: 00000000 00000000 00000000 00000000--溢出01
结果为0,其实相当于把1/2/2,商就是结果0
publicclassBitOperator02{publicstaticvoidmain(String[]args){System.out.println(-1>>2);//-1}}
-1的原码:10000000 00000000 00000000 00000001
-1的反码:11111111 11111111 11111111 11111110
-1的补码:11111111 11111111 11111111 11111111
用符号位即1补溢出的高位,-1>>2的补码: 11111111 11111111 11111111 11111111--溢出11
-1>>2的反码: 11111111 11111111 11111111 11111110
-1>>2的原码: 10000000 00000000 00000000 00000001
结果为-1
publicclassBitOperator02{publicstaticvoidmain(String[]args){System.out.println(1<<2);//4}}
1<<2 1算术左移:符号位不变,低位补0
1的原码:00000000 00000000 00000000 00000001
1<<2: 00000000 00000000 00000000 00000100
结果为4,相当于122
publicclassBitOperator02{publicstaticvoidmain(String[]args){System.out.println(-1<<2);//-4}}
-1的补码:11111111 11111111 11111111 11111111
算术左移:符号位不变,低位补0
-1<<2的补码:11111111 11111111 11111111 11111100
-1<<2的反码:11111111 11111111 11111111 11111011
-1<<2的原码:10000000 00000000 00000000 00000100
结果为-4,相当于-12 2
publicclassBitOperator02{publicstaticvoidmain(String[]args){System.out.println(1>>>2);//0}}
逻辑右移(无符号右移)>>>:低位溢出,高位补0(无<<<符号)
1的补码:00000000 00000000 00000000 00000001
1>>>2的补码即原码:00000000 00000000 00000000 00000000--溢出01
结果为0
publicclassBitOperator02{publicstaticvoidmain(String[]args){System.out.println(-1>>>2);//1073741823}}
-1的补码:11111111 11111111 11111111 11111111
-1>>>2的补码(即原码):00111111 11111111 11111111 11111111--溢出11(变正数了,三码合一,这个即是原码)
结果为1073741823
结语
特别需要注意的是:逻辑右移也就是无符号右移的时候,因为是使用0来补高位的,所以始终会是正数,根据三码合一原则,就可以知道变化后的补码即是原码。