2.1 位运算的理解
寄存器:CPU 中的存储器,数量非常的少。但是速度比 内存要快很多。
在讲解 数字运算之前,我们需要 先讲一下 位运算。
- 提个问题:2 * 8 最高效的计算方式。
2 << 3 = 2 * 8 = 16
很多 底层的调试器。需要通过位来判断 CPU 的状态。
-
与运算(and &)
全 是 1 就 是 1。全是 0 就是 0。1 和 0 也是 0!!!
1011 0011
1101 1000
and-----&
1001 0000 -
或运算(or |)
有一个是 1 就是1
1011 0001
1101 1000
or------|
1111 1001 -
异或运算(xor ^)
不一样就是 1,一样就是0
1011 0001
1101 1000
xor-----^
0110 1001 -
非运算(not ~)
0就是1。 1 就是0 取反。
1101 1000
not-----^
0010 0111 -
位运算(移动)
0000 0001 左移一位(shl <<):0000 0010
左移就是 高位丢弃,低位补0
0000 0001 右移一位(shr >>):0000 0000
右移就是 低位丢弃,高位补0,如果是有符号数,那么就根据符号位来决定补什么!
这也是为什么,在大多数编程语言里:1 / 2 = 0(因为 1 / 2 在内存里是直接被用 位运算处理的。)
左移一位就是 * 2
右移一位就是 / 2
2.2 实现加减乘除
计算机只认识 0 1
人类的基本数学是 建立在 加减乘除上面的!所以我们必须让计算机实现加减乘除。才能去 解决 基本数学的问题。基本的数学问题得到了解决,我们才能去解决 更加难的数学问题。这些问题都得到了解决,其实很多东西也就都能 弄出来了。
计算机通过对 数字的解析,从二进制得到了 各种 进制的有符号数和无符号数。那么理论上来讲 也可以 通过 位运算,来实现 数字的加减乘除!
加法的实现(4 + 5 = 9)
第一步:异或,如果不考虑进位,异或是可以直接出结果的。
0000 0100
0000 0101
----------
0000 0001第二步:进行与运算,来判断进位(和记录进位的位置)
0000 0100
0000 0101
----------
0000 0100发现进位,我们直接 左移一位!进行 进位处理。
–> 0000 1000第三步:异或的结果与进位处理的结果进行异或!
0000 0001
0000 1000
----------
0000 1001第四步:用与运算 再次验证 异或的结果与进位处理的结果 是否有进位
0000 0001
0000 1000
----------
0000 0000都是 0,也就是说 没有需要进位的地方。
这样经过反复的验证,当 与运算结果是 0 的时候,就证明 上一个 的异或结果 就是 最终结果!!!
减法的实现(4 - 5 = -1)
减法运算实际上就是 有符号位的 负数。那么有符号的负数,在计算机内存里 存储的是 补码。
第一步:异或,如果不考虑进位,异或是可以直接出结果的。
0000 0100
1111 1011
----------
1111 1111第二步:进行与运算,来判断进位(和记录进位的位置)
0000 0100
1111 1011
----------
0000 0000没发现进位。
那么 结果 就是 1111 1111 有符号数 解析 就是 -1
- 乘法的实现
x * y 就是 x 个 y 进行 加法的实现!
- 除法的实现
x / y 就是 x - n 个 y 不断进行 减法的实现!最后结果是 进行的减法次数!!
再次强调:所谓的有符号数,是一个解析规则。计算机只有 二进制数,有符号数和无符号数 是咱们 人类 创造出来 解析 二进制数的 一个 规则而已。所以对于计算机而言,它只是存储了 一串二进制代码而已。而对于 人而言,我可以通过 不同的解析规则,来 说明 这一串二进制数 到底 是个 什么数字。