前言 开始之前,先回顾一下二进制原码、反码和补码之间的转换及计算机怎么处理二进制的。 二进制的最高位是符号位:0代表正数,1代表负数; 正数的原码,反码,补码都一样(三
前言
开始之前,先回顾一下二进制原码、反码和补码之间的转换及计算机怎么处理二进制的。
- 二进制的最高位是符号位:0代表正数,1代表负数;
- 正数的原码,反码,补码都一样(三码合一);
- 负数的反码=它的原码符号不变,其他位取反;
- 负数的补码=它的反码+1(负数的反码=负数的补码-1);
- 0的反码、补码都是0;
- Java没有无符号数;
- 在计算机底层运算的时候,都是以补码的方式来运算的;
- 当我们看运算结果的时候,看的是它的原码。
位运算符
运算推算
public class BitOperator02 {public static void main(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
public static void main(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
public static void main(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
public static void main(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,相当于-1*2 *2
public static void main(String[] args) {
System.out.println(1>>>2);//0
}
}
- 逻辑右移(无符号右移)>>>:低位溢出,高位补0(无<<<符号)
- 1的补码:00000000 00000000 00000000 00000001
- 1>>>2的补码即原码:00000000 00000000 00000000 00000000--溢出01
- 结果为0
public static void main(String[] args) {
System.out.println(-1>>>2);//1073741823
}
}
- -1的补码:11111111 11111111 11111111 11111111
- -1>>>2的补码(即原码):00111111 11111111 11111111 11111111--溢出11(变正数了,三码合一,这个即是原码)
- 结果为1073741823
结语
特别需要注意的是:逻辑右移也就是无符号右移的时候,因为是使用0来补高位的,所以始终会是正数,根据三码合一原则,就可以知道变化后的补码即是原码。