🌳为什么计算机中负数要用补数表示
什么是补数
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. 溢出自然发生、自然丢弃
这不是“聪明技巧”,而是:
在“只能做加法”的硬件世界里, 唯一能让整数系统自洽的表示方式。
计算机并不是“选择”了补码,而是所有其它方案在工程上都失败了。