1.机器数和真值
在计算机中,无论数值还是符号,都是用0或1来表示的。通常用最高位作符号位,0表示正数,1表示负数。例如:
+10对应的二进制数为00001010。
-10对应的二进制数为10001010。
通常将在计算机中使用的、连同符号位一起数字化了的二进制数称为机器数。机器数所表达的真实值对应的十进制数叫真值。
例如:若以原码表示的机器数00101110,则所表达的真值为+46。
2.带符号数的表示方法
在计算机中,带符号数的表达方法有多种,最常用的是原码、反码和补码这三种。
(1)原码
在机器数中,将最高位作为符号位,其余二进制位表示该数的绝对值的表示方法叫作原码表示法。
例如:原码10101110,其真值为-46。
原码01101000,其真值为+104。
注意:原码表示法中,有正0(00000000)和负0(10000000)两种。以8位二进制为例,原码的表示范围为-127~+127。
要获得负数原码的真值,只需将除符号位以外的二进制数求值即可。
(2)反码
正数的反码表示与原码相同,负数的反码是将其对应的正数的各位取反,符号位为负。
例如:反码00101110,其真值为+46。
反码11010001,其真值为-46。
注意:反码表示法中,有正0和负0。
反码00000000,其真值为+0。
反码11111111,其真值为-0。
以8位二进制为例,反码的表示范围为-127~+127。
要获得负数反码的真值,需将除符号位以外的二进制数取反后求值。
(3)补码
正数的补码表示与原码相同,负数的补码是将其对应的正数的各位取反后再加1,符号位仍为负。
例如:补码00101110,其真值为+46。
补码11010010,其真值为-46。
注意:补码表示法中,只有正0,没有负0。
以8位二进制为例,补码以00000000表示0,以10000000表示-128,因此补码的表示范围为-128~+127。
在计算机中,由于补码表示法的机器数利用率较高,还能将减法转换为加法进行计算,所以总是以补码的形式来表示带符号数。
若要获得负数补码的真值,可以将除符号位以外的二进制数再求补得到。实际使用过程中,因负数本身就是用补码来表示的,故无须进行再求补计算。
3.编码
编码是为了在特定场合下方便使用而制定的一种数字代号。例如身份证号、手机号等,其作用是代表身份和用户的符号。虽然可以任意编号,但为了代表特定的意义,总会按照某种规律来编码,使编码容易理解、容易记忆等。例如身份证号中含有地区、生日等信息,手机号中含有运营公司等信息。
计算机中常用的编码有两种(BCD码和ASCII码),是为方便进行特定计算而制定的编码规则。
(1)二进制编码的十进制数(BCD码)
用4位二进制数表示1位十进制数的编码方法叫作BCD码(Binary-Coded Decimal)。最常用的BCD码是8421码。
按照这样的编码规则,将各十进制数表示为BCD码并将BCD码写为十六进制数的各数据见表1-1。
表1-1 十进制数与BCD码对照表
由于计算机中,存放二进制数的最小单位是1个字节(8位二进制数),因此,在计算机里BCD码的表示方法又分为两种:分离BCD码和组合BCD码(或压缩BCD码)。
1)分离BCD码:用1个字节表示1位十进制数,低4位为BCD码,高4位补0。用这种方式表示的BCD码叫作分离BCD码,见表1-2。
表1-2 十进制数与分离BCD码对照表
2)组合BCD码:在1个字节中,用低4位表示1位BCD码,同时高4位也表示为1位BCD码,即在1个字节中同时表示两位十进制数。
例如:十进制数56,用组合BCD码表示为01010110,写为十六进制数则为56H。
注意:此时获得的二进制数是通过编码规则直接书写而成,而非计算而得。
分离BCD码的特点:1个字节表示1位十进制数,直接书写,方便直观;缺点是浪费了高4位,加大了存储数据的存储空间。
组合BCD码的特点:1个字节表示两位十进制数,结构紧凑,节约了存储空间;缺点是实际使用中有时需要组装和拆分。
(2)字母和符号的编码(ASCII码)
计算机处理的信息要用到数字、字母和符号等,这些符号在计算机内部是通过统一编码来识别的。计算机普遍采用的是ASCII码(American Standard Code for Information Interchange),即美国标准信息交换码。ASCII码表示与分离BCD码表示很相似,低4位都是相同的,均用0000~1001表示0~9,差别仅在高4位,ASCII码不是0000而是0011。
在ASCII码编码规则中,应注意以下几点:
①0~9的ASCII为30H~39H。
②大写字母‘A’的ASCII码为41H,其余字母按十六进制顺序递增。
③小写字母‘a’的ASCII码为61H,其余字母按十六进制顺序递增。即小写字母与大写字母之间相差20H。
了解ASCII码的编码规则的特点,对于今后编程实现各种码制间的转换有着重要的指导作用。
ASCII码一般在计算机的输入和输出设备中使用,BCD码和二进制数则在数据的运算和处理过程中使用。在解决一些实际问题中,往往需要在这几种码中进行转换。
计算机中CPU能直接提供的运算有算术运算和逻辑运算。
算术运算中,提供加、减、乘、除四则运算。其他的计算函数都是由四则运算通过程序段来实现的。
常见的逻辑运算有与、或、非、异或、求补和移位等。
本节仅介绍基本运算规则。
1.带符号数和无符号数的运算
(1)带符号数的加减运算规则
在计算机中,带符号数均用补码来表示。
例1-1 利用二进制运算方法求带符号数23与56之和及23与56之差。
解 :①23+56=79
将23与56转换为二进制数进行运算的过程如下:
+23=00010111 +56=00111000
则:
②23-56=-33
将23与56转换为二进制数进行运算的过程如下,其运算结果以负数的补码形式呈现:
+23=00010111 +56=00111000
则:
例1-2 利用二进制运算方法求带符号数-23与-56之和及-23与-56之差。
解 :①(-23)+(-56)=-79
将-23与-56转换为二进制数进行运算的过程如下,其运算结果以负数的补码形式呈现:
-23=11101001[补码] -56=11001000[补码]
则:
②(-23)-(-56)=33
将-23与-56转换为二进制数进行运算的过程如下:
-23=11101001[补码] -56=11001000[补码]
则:
(2)无符号数的加减运算规则
例1-3 利用二进制运算方法求无符号数200与49之和及200与49之差。
解 :①200+49=249
将200与56转换为二进制数进行运算的过程如下:
200=11001000 49=00110001
则:
②200-49=151
将23与56转换为二进制数进行运算的过程如下:
200=11001000 49=00110001
则:
2.带符号数溢出和无符号数溢出的判断
(1)带符号数溢出的判断
当进行带符号数计算时,如果计算的结果超出了二进制带符号数的表达范围,就称为溢出。
带符号数是用补码表示,以8位补码为例,所能表达的范围是-128~+127。如果8位带符号二进制数的计算结果超出表达范围,则产生溢出,其结果出错。
例1-4 利用二进制运算方法求带符号数100与64之和。
解 :因为100+64=164,结果超过8位二进制带符号数的表达范围,故产生溢出。
将100与64转换成二进制数进行运算分析,其结果如下:
+100=01100100 +64=01000000
则:
;计算结果出现负数,有溢出
运算过程中,随时都有可能发生溢出,如果出现溢出,其运算结果不能使用,通常需要进行算法修改或停机处理。
对运算结果是否有溢出的判断,可通过状态标志中的OF来确定。OF是通过“双进位”法进行判断,其方法是:将最高位的进位记为C1,次高位的进位记为C2。若计算结果中,C1与C2相同,则无溢出;C1与C2不相同,则有溢出。即溢出标志为C1与C2的异或结果。
以例1-4为例,因最高位无进位,而次高位有进位,OF=1,故计算结果出现了溢出。
例1-5 利用二进制运算方法求带符号数-23与56之和。
解 :因为(-23)+56=33,结果在8位二进制带符号数的表达范围内,故没有产生溢出。
将-23与56转换二进制补码的运算过程如下:
-23=11101001 +56=00111000
则:
最高位有进位,次高位也有进位,两者相同,OF=0,无溢出。
(2)无符号数溢出的判断
同理,无符号数计算时,如果计算的结果超出了二进制带符号数的表达范围,也称为溢出。
以8位二进制为例,无符号数表示所能表达的范围是0~+255。如果8位无符号二进制数的计算结果超出表达范围,则产生溢出,其结果出错。
例1-6 利用二进制运算方法求无符号数128与129之和。
解 :因为128+129=257,结果超过8位二进制无符号数的表达范围,故产生溢出。
将128与129转换成二进制数进行运算分析,其结果如下:
+128=10000000 +129=10000001
则:
;以8位二进制表示计算结果为1,有溢出
本题产生溢出的原因是无符号数运算中最高位产生进位,导致结果超出8位无符号二进制数所能表达的范围。
因此对无符号数运算结果是否有溢出的判断,可通过判断最高位是否有进位来确定。在状态标志中以CF表示最高位的进位情况,故在进行无符号数运算,运算结果使CF=1时则表示结果溢出,反之结果没有溢出。
3.BCD码运算及十进制调整
日常生活中最常见的数制是十进制,利用BCD码编码规则,很容易将十进制数转换为BCD码。但是,由于计算机总是将数据作为二进制数来进行运算,在利用指令进行算术运算时,是按“逢16进一”的法则进行,而日常生活中采用的十进制运算均是按“逢10进一”法则进行的,故两种计算方法中相差6。因此,在利用指令进行BCD码运算时,为获得正确的十进制结果,往往需要将计算结果进行修正,即进行所谓的“十进制调整”。
例如,求分离BCD码7与5之和。
已知7+5=12,用二进制数进行运算有:
从计算的结果可看出结果为无效BCD码(即出现了A~F之间的值),故需再进行十进制调整操作,将计算结果再加F6H后,即可得到分离BCD码的正确结果12。
例如,求分离BCD码9与8之和。
已知9+8=17,用二进制数进行运算有:
计算结果虽是BCD有效码,但因在加法运算过程中出现了辅助进位,故仍需再进行十进制调整操作,将计算结果再加F6H后,得到分离BCD码的正确结果17。
例如,求组合BCD码56与82之和。
已知56+82=138,用二进制数进行运算有:
计算结果高4位为BCD无效码,低4位是有效码且无进位,故BCD码高位需进行十进制调整操作,将计算结果再加60H后,得到组合BCD码的正确结果138。
由以上几例可得,十进制调整的规则如下:
若BCD码加法运算结果中出现无效码或出现进位,则在相应位置再加6。
若BCD码减法运算结果中出现无效码或出现借位,则在相应位置再减6。
实际上,分离BCD码的十进制调整处理方法略有不同,在高4位上还需加F。
BCD码运算的十进制调整是由专门的十进制调整指令来完成的。算法不同、编码不同,其调整指令也不相同。注意:若被计算的数是BCD码,则程序中需要加上十进制调整指令,若被计算的数不是BCD码,则程序中不能加十进制调整指令。
采用哪种数据形式进行运算是程序员在编程之前必须确定的,不同的数据形式,实现的算法各不相同。正如高级语言在使用变量之前要求必须先定义变量类型一样,这样才能够在编译时确定正确的计算方法。
4.逻辑运算
逻辑运算是按照二进制的最小单位Bit(位)来进行的,常用的逻辑运算有与、或、异或、非等。
1)与运算
注意:与0相与得0,与1相与保持不变。利用与运算可以将指定位清0。
2)或运算
注意:与1相或得1,与0相或保持不变。利用或运算可以将指定位置1。
3)异或运算
注意:与1相异或等于取反,与0相异或保持不变。利用异或运算可以对指定位求反。
4)非运算
注意:按位取反,利用非运算可以对所有位求反。