十进制数的每一个数位的基为10,但到了计算机内部,出于存储与计算方便的目的,必须采用基2码对每个十进制数位进行重编码,所需要的最少的基2码的位数为log210,取整数为4。4位基2码有16种不同的组合,怎样从中选择出10个组合来表示十进制数位的0-9,有非常多的可行方案,下面介绍其中的最常用的几种。
① 十进制有权码
是指表示一个十进制数位的4位基2码的每一位有确定的位权。
用得最普遍的是8421码,即4个基2码位的权从高向低分别为8、4、2和1,使用基2码的0000、0001、…1001这10种组合,分别表示0到9这十个值。这种编码的优点是这4位基2码之间满足二进制的规则,而十进制数位之间则是十进制规则,故称这种编码为以二进制编码的十进制(Binary Coded Decimal)数,简称BCD码或二-十进制码。另一个优点是在数字符的ASCII码与这种编码之间的转换方便,即取每个数字符的ASCII码的低4位的值便直接得到该数字的BCD码,入/出操作简便。在计算机内实现BCD码之间的算术运算要复杂一些,在某些情况下,需要对加法运算的结果进行修正。修正规则是:
若两个8421码数相加之和等于或小于1001,即10进制的9,不需要修正;
若相加之和在10到15之间,一方面应向高位产生一进位,本位还要进行加6修正,进位是在进行加6修正时产生的;
若相加之和在16和18之间时,向高位的进位会在相加过程中自己产生,对本位还需进行加6修正。下面给出三种情况下的具体例子。
例如,1+8=9的运算结果是正确的,不必修正。
0 0 0 1
+)1 0 0 0 (1)10+(8)10=(9)10
1 0 0 1
而4+9的结果就必须用 +6 修正,进位是在修正过程中产生的。
0 1 0 0
+)1 0 0 1 (4)10+(9)10 =(1)10 (3)10
1 1 0 1
+) 0 1 1 0
1 0 0 1 1
而7+9的结果也必须用 +6 修正,进位是在相同加过程中产生的。
0 1 1 1
+)1 0 0 1 (7)10+(9)10 =(1)10(6)10
1 0 0 0 0
+) 0 1 1 0
1 0 1 1 0
另外几种有权码,如2421、5211、84-2-1、4311码(表2.9),也都是用4位有权基2码表示一个十进制数位,但这4位基2码之间并不符合二进制规则。这几种有权码的特性表现为:
当采用2421、5211和4311编码时,任何两个十进制数位相加产生10或大于10的结果,相应的基2码相加会向高一位产生进位,有利于实现逢十进位的计数和加法规则。
任何两个相加之和等于9的十进制数位的基2码,互为反码,即满足十进制数按9互补(9's Complement)的关系,有利于简化减法处理。表2.9给出的是上面提到的十进制数位的编码方案。
表2.9 四位有权码
十进制数 | 8421码 | 2421码 | 5211码 | 840201码 | 4311码 |
② 十进制无权码
是指表示一个十进制数位的4位基2码的每一位没有确定的位权。
在采用的无权码的一些方案中,早期用的比较多的是余3码(Excess-3 code),是把原二进制的每个代码都加0011值得到的。它的主要优点是执行十进制数位相加时,能正确地产生进位信号,而且还给减法运算带来了方便。
采用余3码执行加法运算的规则是:
当两个余3码相加不产生进位时,应从所得结果中减去0011;
产生进位时,一方面应将进位信号送入高位余3码,本位还应执行加0011的修正操作。例如:
(1) 0101 0011 (20)10+(75)10= (95)10
+) 1010 1000
1111 1011
-) 0011 0011
1100 1000
(2) 0101 1011 (28)10+(55)10=(83)10
+) 1000 1000
1101 1 0011
1110
-)0011 + 0011
1011 0110
格雷码是另外一种常用的二-十进制编码,是使任何两个相邻的代码只有一个二进制位的状态不同,其余三个二进制位必须有相同状态。这种编码方法的好处是,从一编码变到下一个相邻编码时,只有一位的状态发生变化,有利于得到更好的译码波形,在模拟→数字、数字→模拟转换的电路中得到更好的运行结果。用四个二进制位的格雷码表示十进制数的十个状态的方案很多。表2.10给出两组最常用的编码值。
表2.10 四位无权码
十进制数 | 余三码 | 格雷码(1) | 格雷码(2) |
③ 十进制数的其它编码方法
也有用多于4位基2码,如用5位、7位、甚至10位基2码,来表示一个十进制数位的方案。有些属于无权码,有些属于有权码。表2.11给出4种编码方案。
表2.11 十进制数位编码方案
十进位 | 无权码 | 有权码 | ||
符号 | 五中取二码 | 蠕变码 | 二元五进制码 5043210 | 独热码 0123456789 |
五中取二码 (2-out-of-5 Code)使用5位基2码,并且每个代码必须包含2个"1"和3个"0",因此提供了一位(或奇数位)检粗能力。
蠕变码(Creeping Code)也用5位基2码,是由一个"1"逐次移位扩展和收缩而形成的,符合格雷码的编码规则。
④ 数字串在计算机内的表示与存储
人们习惯使用10进制数,而在计算机内,采用二进制表示和处理数据更方便。因此,在计算机输入和输出数据时,要进行十→二和二→十的进制转换处理,这是多数应用环境中的实际情况。而在某些特定的应用领域中,如商业统计,其特点是运算简单而数据量很大,这样使输入输出过程中的进制转换所占的时间比例很大。从提高机器的运行效率考虑,也可以采用在计算机内部直接用十进制方式表示和处理数据,这要求计算机内部增加少量硬件线路。目前,大多数通用性较强的计算机,都能直接处理十进制形式表示的数值。采用十进制表示数据的另一个目的,是提高数据的表示范围和运算精度,就是说,十进制数在计算机内是以十进制的数位组成的数串形式存储与计算的,其位数,即串长是可变的,可规定最长可用位数,因此不受二进制整数和浮点数统一格式的约束。
十进制数串在计算机内主要有两种表示形式。
a. 字符串形式,即一个字节存放一个十进制的数位或符号位。在主存中,这样的一个十进制数占用连续的多个字节,故为了指明这样一个数,需要给出该数在主存中的起始地址和位数(串的长度)。
对用这种方式表示的数据进行算术运算是很不方便的,因为每个数字符占用一个字节,其低四位的值表示数值,而高四位的值在进行算术运算时不具有数值的意义。因此,用这种方式表示的十进制字符串,主要用在非数值计算的有关应用领域中。
b. 压缩的十进制数串形式,即一个字节存放两个十进制的数位,它比前一种形式节省存储空间,又便于直接完成十进制数的算术运算,是广泛采用的较为理想的方法。
用压缩的十进制数串表示一个数,要占用主存连续的多个字节,每个数位占用半个字节(即4个二进制位),其值可用二-十进制编码(BCD码,数字符的ASCII码的低4位)表示,符号位也占用半个字节并存放在最低数字位之后,其值选用四位编码的六种冗余状态中的有关值,如用1100表示正号,用1101表示负号。在这种表示中,规定数值位加符号位之和必须为偶数,当其和不为偶数时,应在最高数字位之前补一个0。此时,表示一个数要占用该偶数值位的一半那么多个字节。例如:
+123被表示成 123C, -12 被表示成 012D。
要指明一个压缩的十进制数串,也需给出它在主存中的首地址和数字位个数(不含符号位),又称位长,位长为0的数其值为0。压缩的十进制数串表示方法的优点是位长可变,许多机器中规定该长度从0到31,有的甚至更长。