Post

🌳为什么计算机中负数要用补数表示

什么是补数

x+y = 0 x就叫y的补数 y就叫x的补数

比如 1+(-1) = 0

对于 1 来说 -1 就是它的补数 对于 -1 来说 1 就是它的补数

计算机的数据表示

计算机中,表示数据一般是用二进制,这是因为计算机的内部集成电路IC的引脚状态一般是 0V 或 5V, 这种物理状态决定了计算机中数据用二进制表示最为合适.

而一般我们都是由一个字节,8位来表示一个基本信息单位,位是最小单位. 就像,

  • 汉字是我们阅读的最小语义单位
  • 位只是”笔画”,不单独承载意义

计算机中,数据也是有一个或多个字节表示的(根据编程语言来)

比如1是 0000 0001

计算机中的运算指令

其实计算机的指令大概只有4类

  • 移动指令
  • 运算指令
  • 跳转指令
  • call/return 指令

而运算指令中的基本运算,加减乘除,最终在硬件层面,都是通过加法加控制逻辑来完成的.

为什么? 因为它是唯一能稳定堆叠出复杂性的运算

问题来了:计算机如何表示负数

对于我们人类而言, 1, -1 我们一眼就能看出哪个是正数和负数,

但是我们现在是要设计一套表达形式,让计算机懂哪个是正数哪个是负数.

计算机不理解”符号”,它只会对比特模式,也就是0,1 做运算

其实就两个状态,我们可以用最高位来表示正负符号,0表示正数,1表示负数.不要问为什么, 我们规定就是这样. 命运的齿轮就是那么恰好

原码方案为什么失败?

那-1 是不是就是 1000 0001?

前面提到过,所有的基本运算在硬件层面上都是加法运算

如果是这样的话, 1+(-1) 在二进制加法上,就变成了

0000 0001 1000 0001 1000 0010 = -2???

而我们必须要满足这个 1+(-1) = 0 这个宇宙绝对真理

因此如果我们要用这种方案,就不能直接加!需要额外的判断符号位,来进行额外的一些处理!这样就增加了复杂性!

补码:被逼出来的方案

既然 1 是

0000 0001

那么它和

1111 1111

相加是0,位溢出会忽略

归纳总结后

1111 1111 是根据 0000 0001 按位取反然后加1得来的

那么-1在计算机中的表示就是

1111 1111

其实我们是用补数,来表达 -1

但事实上,计算机中负数就是用补数来表示的

至此我们没有借助 - 这样的符号,用纯数字来表达了正负

补码带来的好处

使用补码表示负数,意味着: 1. 加法和减法完全统一 2. 只有一个 0 3. 符号位不需要特殊电路 4. 比较大小只看最高位 5. 溢出自然发生、自然丢弃

这不是“聪明技巧”,而是:

在“只能做加法”的硬件世界里, 唯一能让整数系统自洽的表示方式。

计算机并不是“选择”了补码,而是所有其它方案在工程上都失败了。

This post is licensed under CC BY 4.0 by the author.