整数编码表示方法主要有以下4种: 原码,补码,反码,移码。
这里从介绍 补码开始
1. 补码表示法
该法也称“2-补码”表示法, 由符号位后跟上 真值的模 补码构成。 因此在介绍补码概念之前,先讲一下有关模运算的概念
- 模运算, 在模运算系统中, 若A, B, M满足下列关系: A=B+K * M(K为整数), 则记为: A = B(mod M)。 即A、B各除以M后的余数相同, 故称B 和 A 为 模M同余。 也就是说在一个模运算系统中, 一个数与它除以"模"后得到的余数是等价的。
“钟表” 是一个典型的模运算系统, 其模数为12. 假定现在钟表时针指向10点, 要将它拨向6点, 则有以下两种拨法。
(1)倒拨4格: 10-4=6
(2)顺拨8格:10+8=18=6(mod 12)
所以在模12系统中, -4=8(mod 12). 同样有 -3 = 9(mod 12), -5 =7(mod 12)
我们称8是-4对模12的补码。
看一个例子1:
假定算盘只有 4档, 且只能做加法, 则如何用该算盘计算9828-1928的结果?
解: 这个算盘 是一个 “4位十进制数” 模运算系统, 其模为10000
9828-1928=9828+(10000-1928)=9828+8072 = 7900(mod 1000
0) (注意这里= 实际是三横,表示取模, 不是等号)
解答完成
~~~~~~~~~~~~~~~
所以,可用9828 + 8072(-1928的补码)来实现9828-1928的功能。
可以看到,在只有4档的算盘上运算时,如果运算结果超过4位, 则高位无法在算盘上表示,只能用低4位表示结果, 留在算盘上的值相当于是除以10000后的余数。 推广到计算机内部, n位运算部件就相当于只有n档的二进制算盘, 其模就是
2 补码的定义
正数的补码是它本身, 负数的补码等于模与该负数绝对值之差。
注意一个结论: n位数补码的最大可表示值为
,最小可表示值为
~~~~~~~~~~~~~~~~~~~~~~~~
例子2: 分别求出补码的位数为 n和 n+1时- 2的(n-1)次广场的补码表示。
解: 当补码的位数为n位时,其模为
从该例可以看出,同一个真值在不同位数的补码表示中, 其对应的机器数不同。因此 在给定的编码表示时, 一定要明确编码的位数。
例3 :假设补码的位数为n, 求 -1 的补码表示。
解: 根据补码定义, 有[-1]补 = 2的n次方-1 = 11...1(n个1)。
例4: 求 0 的补码表示。
解:根据补码的定义,
(1) 减少了+0 和-0之间的转换
(2)少占用一个编码表示,使补码比原码能多表示一个最小负数。在n位原码定点数中, 100...0 用于表示-0, 但在n位补码表示中, -0 和 +0都用00...0 表示, 而100...0 用来表示最小负整数- 2的(n-1)次方
3. 补码与真值之间的转换方法
原码与真值之间的对应关系简单,只要对符号转换, 数值部分不需改变。
原码与补码之间的对应关系, 需要根据补码的定义 转换。
例4: 假设补码的位数为8, 求110100 和 -1101100 的补码表示。
解:补码的位数为8, 说明补码数值部分有 7位,故
[1101100] 补 = 2的8次方 + 1101100 = 10000 0000 + 1101100 = 0110 1100(mod 2的8次方)
[-1101100]补 = 2的8次方 - 1101100 = 10000 0000 - 1101100 =10000 0000 + (1111111-1101100)+1
= 10000 0000 + 0010011 +1 = 10010100 (mod 2的8次方)
从负数的计算过程,可以得出结论,符号位取1, 对数值部分 “各位取反,末位加1”。
再看一个例子5: 假设补码位数为8, 求数-1100011的补码表示。
解:[-1100011]补 = 1 0011100 + 0 0000001 = 1 0011101
4 . 由补码求真值
由补码求真值的简便方法为: 若符号位为0, 则真值的符号为正,其数值部分不变, 若符号位为1, 则真值的符号为负, 其数值部分的各位由补码 “各位取反,末位加1” 得到。
例子6: 已知[Xt]补 = 1 0110100, 求真值 Xt.
解: Xt= -(1001011 + 1) = -1001100
可以总结得出, 根据补码 [Xt] 补 求 [-Xt]补 的方法是,对[Xt] 补 “各位取反, 末位加1”。 这里要注意最小负数取负后会发生溢出,即最小负数取负后的补码表示是不存在的。 看下一个例子,注意解法。
例子7: 已知[Xt]补 = 1 0110100, 求[-Xt]补; 已知[Xt]补= 1 0000000,求[-Xt]补。
解:第一问 [-Xt]补 = 0 1001011 + 0 0000001 = 0 1001100
第二问[-Xt]补 = 0 1111111 + 0 0000001 = 1 0000000(结果溢出)
在这里第二问,两个正数相加,结果为负数,结果是一个错误的值,我们称结果“溢出”。
分析原因: 8位整数补码1000 0000对应的是最小负数“- 2的7次方”, 对其取负后的值为2的7次方(即128), 而8位整数补码能表示的最大正数为127, 因而数 128太大,无法用8位补码表示, 故结果溢出。
5 反码表示法
如果将原码 各位取反,末位不加1, 得到原码的反码表示。 因此负数反码的定义就是在相应的补码表示中再末位减1.
关于移码,是用于表示浮点数,本文暂不介绍。