关于原码、反码与补码
1. 计算机是如何存储负数的?
计算机中的所有数据都以二进制的形式存储,因此,我们所认知的负数(如-5、-109)需要进行处理后才能存储在计算机中。为了在计算机中存储负数,人们想出了以下两种处理方案(以char型举例说明):
方案一:采用原码表达数字
原码:把最左边的一位腾出位置,存放符号,0来表示整数,1表示负数。
以数字109举例:
+109表达为: 0110 1101 最左边的0代表数字为正;
-109表达为: 1110 1101 最左边的1代表数字为负。
以数字5举例:
+5表达为: 0000 0101 最左边的0代表数字为正;
-5表达为: 1000 0101 最左边的1代表数字为负。
如和表达0?
规定:0000 0000 表示0
1000 0000 表示128。
我们把这种表达数字的形式称为原码(True Form)。
若采用原码表达数字,109 + 5在计算机的运算结果是什么?
0110 1101
+ 0000 0101
0111 0010 (114)
运算结果是114的原码,完全正确。因此,对于正整数而言,其原码可直接参与运算。
同样地,109 + (-109)在计算机的运算结果是什么?
0110 1101
+ 1110 1101
10101 1110(与现实运算不符)
出现了问题,运算结果不为0,并且数字出现了溢出(超过8位)。因此,对于负数而言,其原码不能参与计算机中的运算,该方案需要改进。
方案二:采用补码的方式存储负数
我们不妨设想,若要使下面的运算结果为0,中间数到底是什么?
0110 1101 (109)
+ ????? (-109)
0000 0000 (0)
如果中间填的是 1001 0011,则:
0110 1101 (109)
+ 1001 0011 (-109)
10000 0000 (0)
运算结果是:1 0000 0000 共9位,而因为该数是8位的char型,故最高位被舍弃(最左边的1被扔掉),该数最终在计算机中被存储为: 0000 0000 , 符合我们的要求。
即:若把-109 表示为1001 0011,则在计算机中的运算结果与现实中的相同,完美符合要求,我们把这一种表达数字的形式称为补码。那么,-109是如何表示成补码的?请看下面的介绍。
2. 怎样得到补码?原码、反码、补码之间是如何转换的?
如何求负整数的补码?以-109为例:
(1)先将-109表示为原码:
十进制数转换为原码的方法为:把最左边的一位腾出位置,存放符号,0来表示整数,1表示负数。
-109 -> 1110 1101 (原码)
(2)再将原码转换为反码
为了得到一个数的补码,我们要借助一个工具------反码(Inverse Code)
原码与反码的转换方法为:符号位置不变,其余位置取反。
1110 1101 (原码) -> 1001 0010(反码)
(3)最后将反码加1,得到补码
1001 0010(反码) -> 1001 0011(补码)
如何得到正整数的补码?
虽然正整数的原码可直接参与运算,但为了统一,计算机中的所有数都以补码的形式存储,因此,我们规定:正整数的原码与补码一致。
3. 总结
我们可以从英文名称来理解原码、反码、补码的意义
原码:True Form
反码:Inverse Code
补码:Two's Complement Representation
原码与整数的二进制形式最接近,因此命名为True Form;将反码命名为Inverse Code,顾名思义,就是反转二进制位的意思。补码命名里的“Complement”意为替代,表示这是二进制数在计算机中的一种替代表达方式。
计算机最终存储的是一个整数的补码!原码和反码只是一个整数转换为补码的“过渡工具”。也就是说,要得到整数的补码,要先求对应的原码,然后再将原码转换成反码,最后将原码转换成补码。