位运算
计算机底层就是一堆电路(与门、或门、非门、异或门等等)
计算机只会做与、或、非、异或、左(右)移等位运算,并不会什么加减乘除。
-
与运算(and &)
两个都为1,结果为1
1111 1101
0101 0001
--------------- 与运算
0101 0001
-
或运算(or |)
只要有一个为1,结果为1
1101 1001
0001 1011
-------------- 或运算
1101 1011
-
非运算 (not ~)
1变0,0变1
1101 0011
------------- 非运算
0010 1100
-
异或运算(xor ^)
不一样为1,一样为0
1101 1011
0101 0001
----------- 异或运算
1000 1010
-
移动位
移动位(左移、右移)可以使数值倍数变化,并且比加减乘除执行效率更高(比如一条加法指令底层机器可能需要执行一系列的操作指令,单纯对位移动的话就很快)
左移(shl <<)
0000 0001 1 所有二进制位全部左移若干位,高位就丢弃了,低位补0
0000 0010 2
0000 0100 4
0000 1000 8
右移(>>)
0000 0001 所有二进制全部右移若干位,低位就丢弃了,高位需要补0,1(符号位决定)
0000 0000
位运算实现加减乘除
计算机就是利用这些电路结构实现加减乘除运算,而不是单纯的像数学里面那样来做。
加法运算的详细步骤:
4 + 5
# 计算机是怎么操作的
0000 0100
0000 0101
----------- (加法:计算机是不会直接加的)
0000 1001
# 计算机的实现原理
#第一步:异或:如果不考虑进位,异或就可以直接出结果
0000 0100
0000 0101
----------
0000 0001
#第二步:与运算(判断进位,如果与运算结果为0,没有进位)
0000 0100
0000 0101
-----------
0000 0100
#第三步:将与运算的结果,左移一位。
0000 1000 #进位的结果
#第四步:异或 (跟第一步重复了)
0000 0001
0000 1000
-----------
0000 1001
#第五步:与运算(判断进位,如果与运算结果为0,没有进位)
0000 0001
0000 1000
-----------
0000 0000 运算结果为0,没有进位
#所以最终的结果就是与运算为0的结果的上一个异或结果。
计算机只会做加法,减乘除都是转换为加法来做。
- 减法转换成加法:减数按位取反再加1,再与被减数做加法
- 乘法转换成加法:x*y,就是y个x相加,还是加法
- 除法转换成加法:x/y,本质就是减法,就是x能减去多少个Y