前言

计算机三码的问题我记得很早的时候在本地typora上写过后面好像丢了。
但是还是要加强一下印象,就回头在写到博客上好了。


正文

首先,三码是哪三码:原码、反码、补码;


原码

原码可不是一个数简单转换成二进制就完事了,需要注意的是在二进制的最高位是代表了符号位,也就是说代表了这个数是整数还是负数,0表示正数,1则表示负数。

本文介绍统一采用一字节的方式举例
例如86的原码应该是0101 0110;
-86的原码则是1101 0110;

此时切记不能将原码和传统二进制混淆。


反码

正数的反码与原码一致,负数的反码除去符号位,其余取反。
还是86为例,它的反码依然是0101 0110;
-86,它的反码则是1010 1001


补码

正数的补码依然与原码一致,负数的补码则是在反码基础上左位移1位。
86的补码为0101 0110;
-86的补码为1010 1010;


那么为什么要这么麻烦呢,起初发明原码的目的就是为了能够很好的区分出正负的概念,使用原码的方式读写,是方便了人,但是计算机就吃苦了。

(+1) + (-1)=0这是常识,但是转换成原码0000 0001 + 1000 0001 = 1000 00101000 0010按照原码的概念高位为符号位,就成了-2,这就变成搬起石头砸自己的脚了。

所以在原码的基础上,又产生了反码的概念,上述提过,反码的目的其实也是为了解决负数的问题
(+1) + (-1) = 0还是这个题
换成原码时:0000 0001 + 1000 0001 = 1000 0010
加入反码后:0000 0001 + 1111 1110 = 1111 1111
正数的0我们知道原码应该是0000 0000,但是这里的结果是1111 1111
首先这个1111 1111还是处于反码的阶段,我们将其转换为原码:1000 0000
而这一比较就会发现,转换后的原码解读应该是-0
虽然结果有那点意思了,但是数学常识0就是0,没有正负之分才对。

最后在不断折磨下,又出现了补码,所以说正数的三码为什么都是一个样的,反码和补码的出现都是为了解决负数的问题。
补码就是反码+1,所以当-1的反码1111 1110转换成补码后应该是1111 1111
正数的三码一致,(+1) + (-1) = 0,变成补码形式0000 0001 + 1111 1111 = 1 0000 0000,一字节的情况下只能表示8个比特,所以最高位会被丢弃掉。也就是0000 0000,也就是我们计算机和数学中最为正确的0。

在明白了基础概念之后,我们可以浅浅的随便算几个数字之和情况下三码的形式。


(+86) + (-67)

原码:0101 0110 + 1100 0011
反码:0101 0110 + 1011 1100
补码:0101 0110 + 1011 1101
最后之和:1 0001 0011,丢弃多余的高位,转换成十进制也就是19


(+96) + (-36)

原码:0110 0000 + 1010 0100
反码:0110 0000 + 1101 1011
补码:0110 0000 + 1101 1100
求和:1 0011 1100,丢弃多余的,转换成十进制就是60


(101) - (-27)

老算加法没意思,回头看看减法呢?
这里也是要提的点,计算机本身其实是比较笨的,因为他只会进行+运算,原因在于计算机是通过电路设计的,那么交给他的活自然不能太繁琐,且在数学领域下,减去一个正数就等于加上这个正数变成负数的值:即1-1 = 1 + (-1) = 0,这也是为什么上述两个计算题还是使用加法的问题,其实(+86) + (-67)就是等于86-67。所以减法也不例外,减去一个负数就等于加上这个负数变符号成正数的结果。
故此(101) - (-27) = 101 + 27 = 128

计算方式如下:
原码:0110 0101 + 0001 1011
反码:0110 0101 + 0001 1011
补码:0110 0101 + 0001 1011
求和:1000 0000,现在按照原码或者反码来说它又是-0,实际上二进制应该表示为128了,但0已经有了它自己的编码0000 0000,所以补码1000 0000约定俗成给了-128。
这也是后来补码的优势,补码不仅区分0存在两个编码的问题,还可以让计算机多表示一个数[-128,127],如果按照原码或者反码一个字节就只能表示[-127,+127]。

如果你还记得编程语言中各类型的取值范围的话:比如char就是一字节,范围[-2^7 到 2^7-1]
int类型占用四字节,范围就是[-2^31 到 2^31-1]

可以看看这个图
正数不多解释三码一致0就是0000 0000直到127的补码0111 1111
按照补码习惯,1111 1111就表示为-1,-1的反码是1111 1110,原码是1000 0001
当然这也是因为一字节能够容纳这些数字,128的二进制是1000 0000


结语

三码的过程还是很意思的,补码也是后面计算机存储用的编码方式;不好理解的再去找些视频看看,做几个题练练吧。

另外就是提到计算机本质上减法也是通过加法实现,乘除好像是通过位运算,但是最终结果还是累加得到的。不过记不太清了后面用到了再回来补一补。