原码 反码 补码#
一:为什么会有原码反码补码?#
为了让计算机更简单的计算数值。所以计算机用补码
具体怎么实现,后边会说,接下来先看一下 什么是原码 反码和补码
二:正数的原码 反码 补码#
网上大多都是按 原码 反码 补码 分别去介绍,博主 (本人) 感觉这样的方法并不方便理解。所以改用 正数和负数来说
如果按 int 来的话,0 太多了,看着不方便,就是 8 位来表示吧.
正数就是 把十进制的数 变成二进制而已
正数的原码 反码 补码是一样的
[+1] = [00000001](原码) = [00000001](反码) = [00000001](补码)
三:负数的原码 反码 补码#
原码:最高位为1
代表这个数是负数
反码: 符号位不变
, 其他位取反
补码: 反码 + 1
[-1] = [10000001](原码) = [11111110](反码) = [11111111](补码)
四:原码 反码 补码出现的意义#
他们的出现都是为了让计算机计算的更加简单,从而性能更好.
知识: 1 - 1 = 1 + (-1) 所以机器可以只有加法.
首先如果只是原码计算,人可以很方便的计算出数值,因为人可以分清符号位.
可是计算机想识别符号位,是很麻烦的。有什么方法能让计算机更简单的计算呢,于是就有了反码.
接下来看,反码的计算
1 - 1 = 1 + (-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]反 + [1111 1110]反
= [1111 1111]反
= [1000 0000]原
= -0
反码已经可以让计算机计算更简单。但是为什么还有补码呢.
因为反码中 0 的编码 可以是 [1111 1111] 反 = [-0] 和 [0000 0000] 反 =[+0]
正负 0 是没有意义的,所以补码是为了解决 0 有两个编码的问题.
(其实到这里 反码是不能直接看出来它代表哪个数,就需要理解了,补码再反码的基础上 + 1, 就更加难理解,我也尝试用更简单的方法来表达出来,有问题可以提出写到评论里)
补码中规定:0的编码为[0000 0000]补 = [+0]
在这里先不要去想二进制代表的十进制数,只想象它是编码
首先 8 位的二进制,就只有 0000 0000 到 1111 1111 这么多个编码 (从 0000 0000 开始 + 1)
然后正数原码反码补码 都是一样的,那么咱们去掉 0000 0000 到 0111 1111
剩下的就是 1000 0000 到 1111 1111 这些数值这些都是负数 (因为符号位是 1)
这些编码挨个 + 1 是这样的
1000 0000
1000 0001
1000 0010
....
1111 1101
1111 1110
1111 1111
首先这些编码 如果是原码那么对应成十进制就是
-0
-1
-2
....
-125
-126
-127
反码不是可以让计算机计算方便么,这些编码是反码 对应的十进制是
-127
-126
-125
...
-2
-1
-0
不是有 - 0 么 怎么解决这个 - 0 呢,每个数 - 1, 不就没有 - 0 了么,最后变成了
-128
-127
-126
...
-3
-2
-1
完美解决 - 0 的编码问题,而且多了一个-128
, 这就是为什么 java 中 int 取值范围是 $-2^{31}$ ~ $2^{31}-1$
好了现在讨论反码怎么才能变成这些数呢,
-1 的反码是 1111 1110 , 然后现在 - 1 的编码
变成了 1111 1111 (这个就是 - 1 的补码了)
综上所述: 补码=反码+1
补码就是这么来的。所以计算机使用补码可以更快的是实现计算.(反码也可以,但是还是有 - 0 问题,所以还是使用补码)