This commit is contained in:
许大仙 2024-08-17 17:26:01 +08:00
parent d38d1cb342
commit 054fe08da9
7 changed files with 66 additions and 2 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 253 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 398 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 507 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 534 KiB

View File

@ -1140,9 +1140,9 @@ int main() {
> [!IMPORTANT]
>
> * ① 补码表示法解决了`原码`和`反码`存在的`两种`零(`+0` 和 `-0`)的问题,即:在补码表示法中,只有`一个`零,即 0000 0000。
> * ① 补码表示法解决了`原码`和`反码`存在的`两种`零(`+0` 和 `-0`)的问题,即:在补码表示法中,只有`一个`零,即 `0000 0000`
> * ②补码使得`加法运算`和`减法运算`可以统一处理,通过将减法运算`转换`为加法运算,可以简化硬件设计,提高了运算效率。
> * ③ 计算机底层`存储`和`计算`的都是`二进数的补码`。
> * ③ 计算机底层`存储`和`计算`的都是`二进数的补码`。换言之,当读取整数的时候,需要采用逆向的转换,即:将补码转换为原码。正数的原码、反码、补码都是一样的,三码合一。负数的补码转换为原码的方法就是先减去 `1` ,得到反码,再按位取反,得到原码。
### 3.5.5 总结
@ -1170,3 +1170,47 @@ int main() {
![](./assets/32.png)
## 3.7 补码到底是如何简化硬件电路的?
* 假设 6 和 18 都是 short 类型,现在我们要计算 `6 - 18` 的结果,根据运算规则,它等价于 `6 +-18`。如果按照采用`原码`来计算,那么运算过程是这样的,如下所示:
> [!NOTE]
>
> 直接使用原码表示整数,让符号位也参与运算,那么对于减法来说,结果显然是不正确的。
![](./assets/33.svg)
* 于是,人们开始继续探索,不断试错,终于设计出了`反码`,如下所示:
> [!NOTE]
>
> 直接使用反码表示整数,让符号位也参与运算,对于 6 +-18来说结果貌似正确。
![](./assets/34.svg)
* 如果我们将`被减数`和`减数`对调一下,即:计算 `18 - 6` 的结果,也就是 `18 +-6`的结果,继续采用`反码`来进行运算,如下所示:
> [!NOTE]
>
> * ① 6 - 186+-18如果采用`反码`计算结果是正确的但是18 - 618 +-6如果采用`反码`计算,结果相差 1 。
> * ② 可以推断:如果按照`反码`来计算,小数 - 大数,结果正确;而大数 - 小数,结果相差 1 。
![](./assets/35.svg)
* 对于这个相差的 `1` 必须进行纠正,但是又不能影响`小数-大数`的结果。于是,人们又绞尽脑汁设计出了`补码`,给`反码`打了一个`“补丁”`,终于把相差的 `1` 给纠正过来了。那么,`6 - 18` 按照`补码`的运算过程,如下所示:
![](./assets/36.svg)
* 那么,`18 - 6` 按照`补码`的运算过程,如下所示:
![](./assets/37.svg)
> [!IMPORTANT]
>
> 总结:采用`补码`的形式正好将相差的 `1`纠正过来,也没有影响到小数减大数,这个“补丁”非常巧妙。
>
> * ① 小数减去大数,结果为负,之前(负数从反码转换为补码需要 +1加上的 1 ,后来(负数从补码转换为反码要 -1还需要减去正好抵消掉所以不会受到影响。
> * ② 大数减去小数,结果为正,之前(负数从反码转换为补码需要 +1加上的 1 ,后来(正数的补码和反码相同,从补码转换为反码不用 -1就没有再减去不能抵消掉这就相当于给计算结果多加了一个 1。
>
> `补码`这种天才般的设计,一举达成了之前加法运算和减法运算提到的两个目标,简化了硬件电路。