位运算
一、原码,反码,补码
-
(1) 二进制的最高位是符号位:0 表示正数,1 表示负数(怎么记?
1
旋转一下变成-
) -
(2) 正数的原码、反码、补码都一样(三码合一)
-
(3) 负数的反码=它的原码符号位不变,其他位取反(0 - > 1 , 1 - > 0)
-
(4) 负数的补码=负数的反码+1,负数的反码=负数的补码 - 1
-
(5) 0 的反码,补码都是 0
-
(6) java 没有无符号数,换言之,java 中的数字都是有符号的
-
(7) (很重要!!!)在计算机运算的时候,都是以补码的方式来运算的
-
(8) (重点!!!)当我们看运算结果的时候,要看它的原码
二、位运算
1. 位运算符
2. 运算规则
-
注意:先将左右操作数转换成二进制,计算过程是采用补码计算
-
按位
&
:两位全为 1,结果为 1,否则为 0 -
按位或
|
:两位有一个为 1,结果为 1,否则为 0 -
按位异或
^
:两位一个为 0,一个为 1,结果为 1,否则为 0 -
按位取反
~
:0 - > 1 , 1 - > 0 -
算术右移2 位
>>
:低位溢出(指的是保存十进制数值所需要的二进制位数),符号位不变,并用符号位补溢出的高位-
int a=1>>2
: // 1 => 00000001 => 00000000 (标黄的就是溢出的位) -
本质 :1 / 2 / 2 = 0
-
速算结果:左操作数作为被除数,右操作数表示除于二的次数,结果即为操作结果值
-
-
算术左移2 位
<<
:符号位不变,低位左移(指的是保存十进制数值所需要的二进制位数),低位补 0-
int c=1<<2;
// 1 => 00000001 => 00000100 -
本质:1 _ 2 _ 2 = 4
-
速算结果:左操作数作为乘数,右操作数表示乘以二的次数,结果即为操作结果值
-
-
逻辑右移
>>>
:符号位也无符号右移,运算规则是:低位溢出,高位补 0 -
特别说明:没有
<<<
符号
三、运算方法代码示例
说明:由于数据类型是
int
类型,所有采用四个字节大小
// 位运算
public class BitOperator {// 编写一个main方法public static void main(String[] args) {// 推导过程// 1. 先得到 2的补码 => 2的原码 00000000 00000000 00000000 00000010// 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// 结果就是 2System.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 => 1System.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 => -3System.out.println(~2); // -3System.out.println(1 >> 2); // 0System.out.println(1 << 2); // 4System.out.println(4 << 3); // 4 * 2 * 2 * 2 = 32System.out.println(15 >> 2); // 15 / 2 / 2 = 3System.out.println(-10.4 % 3); // -1.4 近似值int i = 66;System.out.println(++i + i); // 134}
}
小结
一、对于 &
、 |
、 ^
、 ~
的运算
-
(1)首先得到操作数的补码
-
(2)看是什么运算符,回想对应的操作规则,在操作数的补码基础上按照规则操作,得到操作后的补码
-
(3)把操作后的补码转成源码,得到操作结果