原码
计算机内的数据都是使用 0 或 1 进行存储,为了引入我们的负数,就用一个数的最高位作为符号位,即用 0 代表正数,1 代表负数,这就是提到的 原码
但是很快就发现了原码在实际使用中的问题:
(1)10−(1)10=(1)10+(−1)10=(0)10 在十进制下运算显然正确
但是,假设字长为 8bits
,在二进制下
(00000001)Y+(10000001)Y=(10000010)Y=(−2) 出现错误
- 问题出现在带符号位的计算上,由于二进制相加直接按位相加,会导致结果的符号位出现错误。
反码
很快就有了新的解决方案:反码
,即对负数
除符号位之外的各位逐位取反就产生了与之对应的反码
随之出现了新的问题
(1)10−(1)10=(1)10+(−1)10=(0)10
(00000001)R+(11111110)R=(11111111)R=−0
- 在我们的认知中,0 不区分正负,这会导致计算出现 0 的情况有两种: +0 和 -0,显然也是错误的
补码
于是又引出了补码
的概念:负数的补码就是对其反码加一,正数的原码、反码、补码都是一样,且规定使用-128
代替-0
这样就规避了上面提到的问题:
(1)10−(1)10=(1)10+(−1)10=(0)10
(00000001)B+(11111111)B=(00000000)B=(0) 正确。
(1)10−(2)10=(1)10+(−2)10=(−1)10
(00000001)B+(11111110)B=(11111111)B=(−1) 正确。
所以补码的设计目的