在计算机系统内部,所有的信息都是用二进制进行编码的,这样做的原因有以下几点。
二进制只有两种状态,使用有两个稳定状态的物理器件就可以表示二进制数的每一位,制造成本比较低,例如用高低电平或电荷的正负极性都可以很方便地表示0和1。
二进制位1和0正好与逻辑值“真”和“假”对应,为计算机实现逻辑运算和程序中的逻辑判断提供了便利条件。
二进制的编码和运算规则都很简单,通过逻辑门电路能方便的实现算术运算。
上式中,r为基数, r i r^i ri为第i位的位权。
常见的记数制主要包括二进制(Binary)、八进制(Octal)、十进制(Decimalism)和十六进制(Hexademical)。
二进制 —> 八进制
3位一组,每组转换成对应的八进制符号
八进制—> 二进制
每位八进制对应的3位二进制
二进制 —> 十六进制
4位一组,毎组转换成对应的十六进制符号
十六进制—> 二进制
每位十六进制对应的4位二进制
真值:符合人类习惯的数字
机器数:数字实际存到机器里的形式,正负号需要被“数字化”
二进制编码的十进制数(Binary-Coded Decimal,BCD)是以二进制数来编码表示十进制的0-9。但4位二进制数可以组合出16种代码,因此必有6种状态为冗余状态。具体编码规则根据不同的BCD码有所不同。
目前,国际上普遍采用的一种字符系统是7位二进制编码的ASCII码(每个字节最高位保持为0,可用于奇偶校验)。
在ASCII码中,编码值0~31为控制字符,用于通信控制或设备的功能控制;编码值127是DEL码;编码值32是空格SP;编码值32~126共95个字符称为可印刷字符。
汉字的编码包括汉字的输入编码、汉字内码、汉字字形码三种,他们是计算机中用于输入、内部处理和输出三种用途的编码。
码字:由若干位代码组成的一个字叫做码字。
码距:任意两个合法码字之间最少变化的二进制位数,称为数据校验码的码距。
对于码距不小于2的数据校验码,开始具有检错的能力。码距越大,检错、纠错的能力越强,而且检错能力总是大于纠错能力。
检错编码:通过一定的编码和解码,能够在接收端解码时检查出传输的错误,但不能纠正错误。常见的检错编码有奇偶校验码和循环冗余校验码。
纠错编码:在接收端不仅能检测出错误还能纠正错误检查出来的错误。常见的纠错编码为海明码。
奇校验码:整个校验码(有效信息位和校验位)中“1”的个数为奇数。
偶校验码:整个校验码(有效信息位和校验位)中“1”的个数为偶数。
偶校验的硬件实现:各信息进行异或(模2加)运算,得到的结果即为偶校验位。
缺点:具有局限性,奇偶校验只能发现数据代码中奇数位的出错情况,但不能纠正错误,常用于对存储器数据的检查或传输数据的检查。
循环冗余校验码:又称多项式校验码,是在K位信息码之后再拼接R位的校验码,整个编码长度为N位。
奇偶校验码的检错率较低,不太实用。目前,在计算机网络和数据通信钟,用得最广泛的就是检错率高、开销小、易实现调地循环冗余校验码。
CRC通常用于计算机网络中的数据链路层,适合对大量数据的数据校验。
模2除运算规则
例:计算10110010000 模2除 11001
循环冗余校验码生成规则:
循环冗余校验码检验规则:
海明码:在信息段中插入若干数据位,用于监督码字里的哪一位数据发生了变化,具有一位纠错能力。
假设信息位有k位为101101,校验位共r位,求解海明码的步骤如下:
1.确定海明码的位数r
在一位出错前提下,海明码出错的总可能为k+r种,r位校验码可以表示 2 r 2^r 2r种可能性,排除正确的可能之外,应有如下不等式:
解除满足不等式的最小的r即为校验位的位数r = 4。
2.确定校验码的位置
校验位Pi放在海明位号为 2 r − 1 2^r−1 2r−1的位置上.
3.确定数据的位置
信息位Di按顺序放到剩余位置,如图所示:
4.求出校验位的值
每个数据位用多个校验位进行校验,但要满足条件:被校验数据位的海明位号等于校验该数据位的各校验位海明位号(Mi)之和。另外,校验位不需要再被校验。
从而得到海明码如下:
5.海明码的校验
校验时将海明码的每个校验位分别与上式分组时的所有位用异或连接起来,如下:
可以看到,若海明码没有错误信息,应得到一个全由0构成的r位二进制数。
若假设第五位出错了,将第五位(M5)的值由0改为1,校验过程如下:
最终得到二进制数1010,即十进制数5,对应第五位出错,可见海明码具有1位纠错能力。
无符号数:指整个机器字长的全部二进制位均为数值位,没有符号位,相当于数的绝对值。若机器字长为8位,则数的表示范围为0~ 2 8 − 1 2^8-1 28−1,即0~255。
有符号数:在机器中,数的正负号是无法识别的,有符号数用0表示正号,用1表示负号,从而将符号也数值化,并通常约定二进制数的最高位为符号位,即将符号位放在有效数字前面,组成有符号数。
有符号数的机器表示有原码、补码、反码和移码。为了能正确区别真值和各种机器数,约定用X表示真值,用[X]原表示原码,[X]补表示补码,[X]反表示反码,[X]移表示移码。
根据小数点的表示是否固定,在计算机中有两种数据格式:定点数和浮点数。
定点表示即约定机器数中的小数点位置是固定不变的,小数点不再使用“.”表示,而是约定它的位置。理论上,小数点位置固定在哪一位都可以,但在计算机中通常采用两种简单的约定:将小数点的位置固定在数据的最高位之前,或固定在最低位之后。一般常称前者为定点小数,后者为定点整数。
原码的0有两种表示方法,即有+0和-0的区别。
反码的0有两种表示方法,即有+0和-0的区别。
补码的0只有一种表示形式即全为0。
将补码转换为原码时同样是正数不变,负数数值为全部取反末位 加1。
已知[X]补求[-X]补时,连带符号位全部取反,末位加1。
补码以从右向左第一个1为分界线,在该1左边的数都与反码相同 ,在该1右边(包括1)的数都与原码相同。
移码的表示范围和补码相同,常用于比较大小。
移码只能表示整数。
绝大多数计算机系统都是采用补码来表示机器数。
**逻辑移位:**逻辑左移时,高位移丢,低位补0;逻辑右移时,低位移丢,高位补0。
算数移位:
原码、补码、反码中那种情况下的移动影响精度?哪种情况下的移动结果出错?
补码加法:
[x+y]补 = [x]补 + [y]补
补码减法:
[x-y]补 = [x]补 + [-y]补
溢出:假设机器字长固定,不妨设为8位(包含一位符号位),根据前面掌握的知识,补码的取值范围应该是-128~127,若现在两个数相加大于127,或者小于-128,则称为溢出,其中两数相加大于上界127,称为上溢或者正溢出;两数相加小于下界-128,称为下溢或者负溢出。定点小数的情况相同,若两个定点小数相加大于或等于1,则称为上溢;若两个定点小数相加小于-1,则称为下溢。
溢出的判定方法:
使用双符号位时两个符号位要连同数值部分一起参加运算,且高位符号位产生的进位直接丢弃。
特点:符号位和数值位分开求,乘积符号由两个数的符号位异或形成,数值部分是两个数的绝对值相乘之积。
在计算机中,除法运算可以转换成“累加——左移”(逻辑左移)。
1.恢复余数法
恢复余数法每次都让被除数(余数)与除数相减,判断正负,如果为正数则商1,左移进行下一步,如果为负,就再加上除数恢复余数并商0。
2.不恢复余数法(加减交替法)
根据上图,当余数小于0时,可以直接商0,余数左移一位并加上除数即可得到新余数。
若余数为负,则可直接商0,让余数左移1位再加上|除数|,得到下一个新余数。若余数为正,则商1,让余数左移1位再减去|除数|,得到下一个新余数。
被除数与除数同号:被除数减除数得到余数
被除数与除数异号:被除数加除数得到余数
余数(被除数)与除数同号商1,异号商0。
补码除法末尾恒置1.
强制类型转换的结果保持位值不变,仅改变了解释这些位的方式。
注意:数据转换时应注意的问题如下:
C语言中定义的各种数据类型的表示方法:
unsigned型数据就是无符号整数,不考虑符号位。直接用全部二进制位对数值进行编码得到的就是无符号数,一般都用补码表示。
int型数据就是定点整数,一般用补码表示。int型数据的位数与运行平台和编译器有关,一般是32位或16位。例如,真值是-12的int型整数,在机器内存储的机器数(假定用32位寄存器寄存)是1111 1111 1111 1111 1111 1111 1111 0100。
long型数据和 short 型数据也都是定点整数,只是位数不同,分别是长整型和短整型数,通常用补码表示。
float型数据是用来表示实数的浮点数。现代计算机用IEEE 754标准表示浮点数,其中 32位单精度浮点数就是float 型,64位双精度浮点数就是double型。
需要注意的是,C语言中的int型和unsigned型变量的存储方式没有区别,都按照补码的形式存储,在不溢出范围内的加减法运算也是相同的,只是int型变量的最高位代表符号位,而unsigned型中的最高位表示数值位,两者在C语言中的区别体现在输出时到底是采用%d还是采用%u。
多字节数据都存放在连续的字节序列中,根据数据中各字节在连续字节序列中的排列顺序不同,可以采用两种排列方式:大端方式和小端方式。
大端方式:按从最高有效字节到最低有效字节的顺序存储数据,即最高有效字节存放在前面。
小端方式:按从最低有效字节到最高有效字节的顺序存储数据,即最低有效字节存放在前面。
阶码:常用补码或移码表示的定点整数
尾数:常用原码或补码表示的定点小数
规格化浮点数:规定位数的最高位必须是一个有效值
左规:当浮点数运算的结果为非规格化时要进行规格化处理, 将尾数算数左移一位,阶码减1。左规可能进行多次。
右规:当浮点数运算的结果尾数出现溢出(双符号位为01或10)时, 将尾数算数右移一位,阶码加1。右规只要进行一次。
原码规格化后,数值位最高位必须为1
补码规格化后,数值位最高位必须与符号位相反
基数不同,浮点数的规格化形式也不同。
当浮点数尾数的基数为2时,原码规格化数的尾数最高位一定是1,补码规格化数的尾数最高位一定与尾数符号位相反。
当基数为4时,原码规格化形式的尾数最高两位不全为0。
当基数为8时,原码规格化形式的尾数最高3位不全为0。
基数越大,范围越大,但精度越低。
如图所示,**运算结果大于最大正数时称为正上溢,小于绝对值最大负数时称为负上溢,正上溢和负上溢统称上溢。数据一旦产生上
溢,计算机必须中断运算操作,进行溢出处理。当运算结果在0至最小正数之间时称为正下溢,在0至绝对值最小负数之间时称为负下溢,正下溢和负下溢统称下溢。**数据下溢时,浮点数值趋于零,计算机仅将其当作机器零处理。
按照IEEE754标准的浮点数格式如图所示。
IEEE 754标准规定常用的浮点数格式有短浮点数(单精度、float型)、长浮点数(双精度、double型)、临时浮点数。
在IEEE754标准中,短浮点数和长浮点数的尾数都采用隐含最高数位的方法,因此可多表示一位尾数。临时浮点数又称扩展精度浮点数,无隐含位。
阶码是以移码形式存储的。对于短浮点数,偏置值为127;对于长浮点数,偏置值为1023。存储浮点数阶码部分之前,偏置值要先加到阶码真值上。
注:偏置值为127(而非128)时,空出8位全1来表示无穷大(若偏置值选128,则不能区分无穷大)。此外,阶码值E的范围为1~254,空出全0表示非规格化数。
对阶
目的是使两个操作数的阶数相等,采用小阶向大阶对齐的原则,将阶码小的尾数右移一位,阶加1,直到两个数阶码相等为止。尾数右移时,舍弃掉有效位会产生误差。
尾数求和
将对阶后的尾数按定点数加(减)运算规则运算。
规格化
舍入
在对阶和右规的过程中,可能会将尾数低位丢失,引起误差,影响精度。常见的舍入方法有:“0”舍“1”入法和恒置“1”法。
溢出判断
在浮点数规格化中已指出,当尾数之和(差)出现01.xxx或10.xxx时,并不表示溢出,只能将此数右规后,再根据阶码来判断浮点数运算结果是否溢出。
浮点数的溢出与否是由阶码的符号决定的。以双符号位补码为例,当阶码的符号位出现“01”时,即阶码大于最大阶码时,表示上溢,进入中断处理;当阶码的符号位出现“10”时,即阶码小于最小阶码时,表示下溢,按机器零处理。实际上原理还是阶码符号位不同表示溢出,且真实符号位和高位符号位一致。
浮点数的运算结果可能出现以下几种情况:
在串行加法器中,只有一个全加器,数据逐位串行送入加法器中进行运算。若操作数长n位,则加法就要分n次进行,每次产生一位和,并且串行逐位地送回寄存器。进位触发器用来寄存进位信号,以便参与下一次运算。
串行加法器具有器件少、成本低的优点,但运算速度慢,多用于某些低速的专用运算器。
并行加法器由多个全加器组成,其位数与机器的字长相同,各位数据同时运算。并行加法器可同时对数据的各位相加,但存在一个加法的最长运算时间问题,原因是,虽然操作数的各位是同时提供的,但低位运算所产生的进位会影响高位的运算结果。因此并行加法器的最长运算时间主要是由进位信号的传递时间决定的,而每个全加器本身的求和延迟只是次要因素。因此,提高并行加法器速度的关键是尽量加快进位产生和传递的速度。
把n个全加器串接起来,就可进行两个n位数的相加,这种加法器称为串行进位的并行加法器。串行进位又称行波进位,每级进位直接依赖于前一级的进位,即进位信号是逐级形成的。
可见,低位运算产生进位所需要的时间将可能影响直至最高位运算的时间。因此,并行加法器的最长运算时间主要是由进位信号的传递时间决定的,位数越多延迟时间就越长,而全加器本身的求和延迟只为次要因素,所以加快进位产生和提高传递的速度是关键。
并行进位又称先行进位、同时进位,其特点是各级进位信号同时形成。采用并行进位的方案可以加快进位产生和提高传递的速度,即将各级低位产生的本级G和Р信号依次同时送到高位各全加器的输入,以使它们同时形成进位信号,各进位信号表达式如下,可见它们可以同时形成进位信号:
上述各式中所有的进位输出仅由Gi,Pi及最低进位输入C0决定,而不依赖于其低位的进位输入Ci-1,因此各级进位输出可以同时产生。
这种进位方式是快速的,与字长无关。但随着加法器位数的增加,Ci,的逻辑表达式会变得越来越长,输入变量会越来越多,这会使电路结构变得很复杂,所以完全采用并行进位是不现实的。
分组并行进位方式,实际上通常采用分组并行进位方式。这种方式把n位全加器分为若干小组,小组内的各位之间实行并行快速进位,小组与小组之间可以采用串行进位方式,也可以采用并行快速进位方式,因此有以下两种情况:
数字电路一般可分为组合逻辑电路和时序逻辑电路。
**组合逻辑电路在逻辑功能上的特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状态无关。**也就是说,组合逻辑电路没有“记忆”,运算后的结果要立刻送入寄存器保存。
**时序逻辑电路在逻辑功能上的特点是任意时刻的输出不仅取决于当时的输入信号,还取决于电路原来的状态。**也就是说,时序逻辑电路具有记忆元件,即触发器(能够存储一位信号的基本单元电路),可以记录前一时刻的输出状态(CPU就是一种复杂的时序逻辑电路)。
ALU是一种组合逻辑电路,因此在实际使用ALU时,其输入端口A和B必须与锁存器相连,而且在运算的过程中锁存器的内容是不变的,其输出也必须送至寄存器保存。
锁存器:锁存器就是多位触发器,因为触发器只能存储一位,而一般参与运算的操作数都是多位,所以引入锁存器。锁存器经常被用作运算器中的数据暂存器。以后看到锁存器就把它想象成一个临时存放数据的地方。
如何表示一个数值数据?计算机中的数值数据都是二进制数吗?
在计算机内部,数值数据的表示方法有以下两大类。
所以,计算机中的数值数据虽然都用二进制来编码表示,但不全是二进制数,也有用十进制数表示的。后面一章有关指令类型的内容中,就有对应的二进制加法指令和十进制加法指令。
对于位数相同的定点数和浮点数,可表示的浮点数个数比定点数个数多吗?
不是,可表示的数据个数取决于编码所采用的位数。编码位数一定,编码出来的数据个数就是一定的。n位编码只能表示2”个数,所以对于相同位数的定点数和浮点数来说,可表示的数据个数应该一样多(有时可能由于一个值有两个或多个编码对应,编码个数会有少量差异)。
际使用ALU时,其输入端口A和B必须与锁存器相连,而且在运算的过程中锁存器的内容是不变的,其输出也必须送至寄存器保存。
锁存器:锁存器就是多位触发器,因为触发器只能存储一位,而一般参与运算的操作数都是多位,所以引入锁存器。锁存器经常被用作运算器中的数据暂存器。以后看到锁存器就把它想象成一个临时存放数据的地方。
如何表示一个数值数据?计算机中的数值数据都是二进制数吗?
在计算机内部,数值数据的表示方法有以下两大类。
所以,计算机中的数值数据虽然都用二进制来编码表示,但不全是二进制数,也有用十进制数表示的。后面一章有关指令类型的内容中,就有对应的二进制加法指令和十进制加法指令。
对于位数相同的定点数和浮点数,可表示的浮点数个数比定点数个数多吗?
不是,可表示的数据个数取决于编码所采用的位数。编码位数一定,编码出来的数据个数就是一定的。n位编码只能表示2”个数,所以对于相同位数的定点数和浮点数来说,可表示的数据个数应该一样多(有时可能由于一个值有两个或多个编码对应,编码个数会有少量差异)。