位运算
对于有符号的原码、反码、补码而言:
- 二进制的最高位是符号位:0表示正数,1表示负数(0->0,1->-)
- 正数的原码、反码、补码都一样(三码合一)
- 负数的反码 = 它的原码符号位不变,其它位按位取反(0->1,1->0)
- 负数的补码 = 它的反码 + 1;负数的反码 = 它的补码 - 1
- 0的反码、补码都是0
- java 没有无符号数,换言之,java 中的数都是有符号的
- 在计算机运算的时候,都是以补码的方式来运算的(因为补码把正数和负数统一起来了)
- 当我们看运算结果的时候,要看它的原码5
位运算符(一)
-
&、|、^、~
分别是按位与&、按位或|、按位异或^、按位取反~,它们的运算规则如下:
- 按位与& : 两位全为1,结果为1,否则为0
- 按位或| : 两位有一个为1,结果为1,否则为0
- 按位异或^ : 两位一个为0,一个为1,结果为1,否则为0
- 按位取反~ : 0->1,1->0
//位运算
public class BitOperator {
//编写一个main方法
public static void main(String[] args) {
//推导
//一个字节八个bit,int类型有四个字节,2的二进制10
//1.先得到 2的补码 => 2的原码(00000000 00000000 00000000 00000010)一个字节八个bit,int类型有四个字节
// 2的补码 00000000 00000000 00000000 00000010
//2.再得到 3的补码 => 3的原码(00000000 00000000 00000000 00000011)
// 3的补码 00000000 00000000 00000000 00000011
//3.按位与&
// 00000000 00000000 00000000 00000010
// 00000000 00000000 00000000 00000011
// 00000000 00000000 00000000 00000010 & 运算后的补码
// 运算后的原码 也是 00000000 00000000 00000000 00000010
// 结果就是 2
System.out.println(2&3); // 2
//推导
//1.先得到 -2的原码 10000000 00000000 00000000 00000010
//2.得到 -2的反码 11111111 11111111 11111111 11111101
//3.得到 -2的补码 11111111 11111111 11111111 11111110
//4.~-2操作 00000000 00000000 00000000 00000001
//5.运算后的原码 就是 00000000 00000000 00000000 00000001 => 1
System.out.println(~-2); // 1
//推导
//1.得到 2的补码 00000000 00000000 00000000 00000010
//2.~2操作 11111111 11111111 11111111 11111101
//3.运算后的反码 11111111 11111111 11111111 11111100
//4.运算后的原码 10000000 00000000 00000000 00000011 => -3
System.out.println(~2);// -3
}
}
运算结果:
位运算符(二)
-
(>>、<<、>>>)
分别是算术右移<<、算数左移>>、逻辑右移>>>,它们的运算规则如下:
- 算术右移<< : 低位溢出,符号位不变,并用符号位补溢出的高位
- 算数左移>> : 符号位不变,低位补0
- 逻辑右移(也叫无符号右移)>>> : 低位溢出,高位补0
- 特别说明:没有 <<< 符号
案例 :int a = 1>>2; 1 => 00000001 => 00000000 本质 1/2/2 = 0
int b = 1<<2; 1 => 00000001 => 00000100 本质 1*
2*
2 = 4
public class BitOperator02 {
//编写一个main方法
public static void main(String[] args) {
System.out.println(1>>2); //0
System.out.println(4<<3); //4*2*2*2 = 32
System.out.println(1<<2); //4
System.out.println(15>>2); //15/2/2 = 3
}
}
运行结果: