文章目录
- 位运算
- 按位与操作
- 按位或操作
- 按位取反
- 按位亦或
- 移位运算
- 有符号左移
- 有符号右移
位运算
处理数据的时候可以直接对组成整形数值的各个位完成操作
& | | | ~ | ^ |
---|---|---|---|
and | or | not | xor |
下面我们以byte类型为例子:
按位与操作
两个操作数,如果同为1则为1,否则为0
例题:
-10 & 8 = 0
-10 & 8
-10--->10001010(源码)--->11110101(反码)--->11110110(补码)
8--->00001000(源码)--->00001000(反码)--->00001000(补码)
-10 11110110
& 8 00001000
---------------
00000000
注意计算机运算时,是补码的运算,先转换再计算,最后结果再转换为源码
按位或操作
连个操作数对应位同为0时才为0,其余结果全为1
例题
-10 | -12 = -10
-10 | 12
-10--->10001010(源码)--->11110101(反码)--->11110110(补码)
-12--->10001100(源码)--->11110011(反码)--->11110100(补码)
-10 11110110
|-12 11110100
---------------
11110110
转换后为:10001010(-10)
按位取反
所有位直接取反
例题
10 00001010
--------------
-10 11110101
按位亦或
两位操作数对应位,相同为0,不同为1
例题
-10 ^ 8 = -2
-10 ^ 8
-10--->10001010(源码)--->11110101(反码)--->11110110(补码)
8--->00001000(源码)--->00001000(反码)--->00001000(补码)
-10 11110110
^ 8 00001000
---------------
11111110
转换后为:10000010(-2)
移位运算
有符号左移
右边空出来的位用0来填补,高位左移溢出则舍弃高位,左移几位其实就是这个数*2的几次幂—>乘法
例题
-8 << 2 = -32
-8 11111000(补码)
---------------
-8<<2 11100000(补码)
10100000(源码)
有符号右移
左边空出来的位用0或1来填补,正数用0,负数用1,右移几位其实就是/2的几次幂—>除法
例题
-8 >> 2 = -2
-8 11111000(补码)
---------------
-8>>2 11111110(补码)
10000010(源码)
-
为什么会有移位运算?
运算时间快 差了10倍的数量级
例题:用最快的速度计算出2*16的值
public class Demo {
public static void main(String[] args) {
// 用最快的速度计算出2*16
long startTime = System.nanoTime(); // 获取开始时间
System.out.println(2*16);
long endTime = System.nanoTime(); // 获取结束时间
System.out.println("程序运行时间:"+(endTime-startTime)+"ns");
long startTime1 = System.nanoTime(); // 获取开始时间
System.out.println(2<<4);
long endTime1 = System.nanoTime();
System.out.println("程序运行时间:"+(endTime1-startTime1)+"ns");
}
}
输出结果:
很明显移位运算要比普通的乘除法更快