计算机组成原理第二章

第二章要解决的问题如下:
1.8位的计算机定点整数表示,范围是多大?讨论原、反、补码的情况。
2.半加器和全加器的电路?
3.行波进位加法器的缺点,以及延迟分析(以8位为例)?
4.8位并行加法器设计电路
5.定点数表示数和浮点数表示的区别和联系?IEEE754为什么阶码部分为什么采用移码表示?
6.为什么要校验位?奇偶校验码的作用?
7.海明码和CRC码的编码方法,以及各自用途。
8.国标码GB2312汉字编码和存储规则。
9.如何判断溢出,以及溢出电路设计?
10.logisim和verilog两种软件如何使用,以及他们的用途是什么?
11.为什么减法可以通过加法实现?
12.移位运算是什么?

1.原码、反码、补码

1.真值与机器数

为了区分一般书写的数和机器中的编码数,我们有如下定义:
真值:一般书写表示的数
机器数(或机器码):机器中用编码表示的数
机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0、负数为1
比如,十进制中的数+3 ,如果计算机字长为8位,转换成二进制就是00000011。如果是-3 ,就是10000011 。这里的 0000001110000011就是机器数。
因为第一位是符号位,所以机器数的值不等于真正的数值。例如上面的有符号数10000011,其最高位1代表负,其真正数值是 -3,而不是131。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例:00000001的真值 = +0000001 = +110000001的真值 = –0000001 = –1

2.原码

1.原码的定义

原码是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1,其余位表示数值的大小。
[ x ] 原 = { x 0 ≤ x < 2 n   2 n − x = 2 n + ∣ x ∣ − 2 n < x < 0 [x]_原= \begin{cases} x& \text{$0\le x<2^n$ }\\ 2^n-x=2^n+|x|& \text{$-2^n<x<0$} \end{cases} [x]={x2nx=2n+x0x<2n 2n<x<0
x < 0 x<0 x<0时, [ x ] 原 [x]_原 [x]相当于在 x x x的最前位加了个1。
举个例子,当 x = + 1011 x=+1011 x=+1011时, [ x ] 原 = 01011 [x]_原=01011 [x]=01011;当 x = − 1011 x=-1011 x=1011时, [ x ] 原 = 2 4 − ( − 1011 ) = 2 4 + 1011 = 11011 [x]_原=2^4-(-1011)=2^4+1011=11011 [x]=24(1011)=24+1011=11011
其中 [ x ] 原 [x]_原 [x]机器数 x x x真值

2.原码的优点

简单直观;例如,我们用8位二进制表示一个数,+11的原码为00001011-11的原码就是10001011

3.原码的缺点

0的表示不唯一,有+0-0之分。而且原码的加法运算复杂。这是因为,当两数相加时,如果是同号则数值相加;如果是异号,则要进行减法。而在进行减法时,还要比较绝对值的大小,然后大数减去小数,最后还要给结果选择恰当的符号。

2.反码

1.反码的定义

反码是在原码的基础上,符号位不变而数值位按位取反。
[ x ] 反 = { x 0 ≤ x < 2 n   2 n + 1 + x − 1 − 2 n < x < 0 [x]_反= \begin{cases} x& \text{$0\le x<2^n$ }\\ 2^{n+1}+x-1& \text{$-2^n<x<0$} \end{cases} [x]={x2n+1+x10x<2n 2n<x<0
其中 x < 0 x<0 x<0时, [ x ] 原 + [ x ] 反 = 2 n + 1 + 2 n − 1 [x]_原+[x]_反=2^{n+1}+2^n-1 [x]+[x]=2n+1+2n1,从而推出 [ x ] 反 [x]_反 [x]的表达式
举个例子:当 x = − 1011 x=-1011 x=1011时, [ x ] 原 = 2 4 − ( − 1011 ) = 2 4 + 1011 = 11011 [x]_原=2^4-(-1011)=2^4+1011=11011 [x]=24(1011)=24+1011=11011,而 [ x ] 反 = 10100 [x]_反=10100 [x]=10100 [ x ] 原 + [ x ] 反 = 101111 = 2 5 + 2 4 − 1 [x]_原+[x]_反=101111=2^5+2^4-1 [x]+[x]=101111=25+241

2.反码的优点

运算相对原码简单,符号位参与运算,只需要设置加法器,但符号位进位位需要加到最低位。

3.反码的缺点

反码的表示相对原码比较复杂,而且0的表示也不唯一。

3.补码

1.补码的定义

补码的表示是在反码的基础上再加1。
[ x ] 补 = { x 0 ≤ x < 2 n   2 n + 1 + x − 2 n ≤ x ≤ 0 [x]_补= \begin{cases} x& \text{$0\le x<2^n$ }\\ 2^{n+1}+x& \text{$-2^n\le x\le0$} \end{cases} [x]={x2n+1+x0x<2n 2nx0
其中 x < 0 x<0 x<0时, [ x ] 补 = [ x ] 反 + 1 [x]_补=[x]_反+1 [x]=[x]+1,从而推出 [ x ] 补 [x]_补 [x]的表达式

2.补码的优点

补码的运算简单,只需要设置加法器,而且0的表示唯一。

3.补码的缺点

补码的表示相对原码比较复杂。

4.移码


移码一般在阶码中采用,由移码定义可知,移码无负值。且相同位数的补码与移码表示范围相同。

5.编码方式

对于一个数,计算机要使用一定的编码方式进行存储,原码、反码、补码是机器存储一个具体数字的编码方式。
原码的表示方法是:符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。
反码的表示方法是:正数的反码就是其本身;负数的反码是在其原码的基础上,符号位不变,其余各位取反。
补码的表示方法是:正数的补码就是其本身;负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1,即取反+1。

6.为什么采用原码、反码和补码

首先,让我们看一个最简单的加法,-11相加。

1 - 1 = 1 + (-1) = [00000001]原 + [10000001]= [10000010]= -2

如果用原码表示, 让符号位也参与计算,显然对于减法来说结果是不正确的。比如上面计算得到的就是-2
这也就是为何计算机内部不使用原码表示一个数。

1 - 1 = 1 + (-1) = [00000001]原 + [10000001]= [00000001]反 + [11111110]= [11111111]= [10000000]= -0

为了解决原码做减法的问题,人们发明了反码,但是人们又发现用反码计算减法,结果的真值部分是正确的,而唯一的问题出现在0这个特殊的数值上。虽然人们理解上+0-0是一样的,但是0带符号是没有任何意义的。

1-1 = 1 + (-1) = [00000001]原 + [10000001]= [00000001]补 + [11111111]= [00000000]=[00000000]= 0

最后补码出现了,它解决了0的符号以及两个编码的问题。除此之外,我们还可以用[10000000]补表示-128,但是-128没有原码和反码表示。

(-1) + (-127) = [10000001]原 + [11111111]= [11111111]补 + [10000001]= [10000000]

所以,使用补码不仅仅修复了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数,这就是为什么8位二进制使用原码或反码表示的范围为 [-127, +127],而使用补码表示的范围为 [-128, 127] 的原因。而在补码

2.半加器与全加器

半加器
如果仅仅考虑两个1位二进制数A和B相加,而不考虑低位的进位,称为半加。实现半加运算的电路叫做半加器。半加器有两个输入端A和B,两个输出端S和C,其中S为和,C为向高位的进位。
半加器的真值表如下:

ABCarrySum
0000
0101
1001
1110

由真值表可以写出逻辑表达式:
S = A ⊕ B S=A\oplus B S=AB
C = A B C=AB C=AB
显然,我们可以用异或门和与门实现S和C从而构成半加器。

全加器
为了说明什么是全加,我们首先要知道什么是半加,由上述知识可知,半加就是在两个二进制数进行相加时,不考虑低位向高位的进位,而全加就是考虑了低位向高位的进位,这样才能反映两个二进制数相加过程中任何一位相加的一般情况。实现全加的电路就叫全加器。

全加器真值表如下:

ABCinCoutSum
00000
00101
01001
01110
10001
10110
11010
11111

由真值表我们可以写出输出逻辑表达式:
S = ( A ⊕ B ) ⊕ C i n S=(A\oplus B)\oplus Cin S=(AB)Cin
C o u t = ( A ⊕ B ) C i n + A B Cout=(A\oplus B)Cin+AB Cout=(AB)Cin+AB
由此可见, S S S是半加和 A ⊕ B A\oplus B AB与低位进位 C i n Cin Cin的异或逻辑,因此可以用两个半加器和一个或门组成一个全加器。


3.行波进位加法器

1.行波进位加法器的定义

N-bit加法器可以根据1-bit全加器组合而成。每个全加器的输出进位cout作为下一个全加器的输入进位cin,这种加法器称为行波进位加法器(Ripple-carry adder,简称RCA)。

行波进位是指进位信号从低位逐位向高位传递,特点是结构简单,但是由于后一位的进位依赖于前一位的进位,所以关键路径更长,限制速度,性能不高。

2.行波进位加法器的时延分析

例如下面一个4bit行波进位加法器的时延分析

如上图所示,假设一个基本门电路时延为T,与非,或非为2T,异或为3T,则该四位加法器的时延为最长路线的时延之和,例如上图的时延为3T+T+T+T+T+T+T+T+T=3T+2T*4=11T,由此我们也可推出8bit行波进位加法器时延为3T+2T*8=19T。但是这种是建立在我们假设了时延大小的情况下计算得出的,具体的时延还要根据题目具体分析。

4.8位并行加法器

5.定点数与浮点数

1.定点数

所谓定点,即约定机器中所有数据的小数点位置是固定不变的,因此既可以表示整数,也可以表示小数。原理上讲,小数点位置固定在哪一位都可以,但是我们通常将数据表示成纯小数纯整数
假设用一个 n + 1 n+1 n+1位字来表示一个定点数 x x x,其中一位 x n x_n xn用来表示数的符号,其余位数表示它的量值,这样,对于任意的定点数 x x x,我们可以在定点机中表示为如下形式:

如果数 x x x表示的是纯小数,那么小数点位于 x n x_n xn x n − 1 x_{n-1} xn1之间,且数的绝对值表示范围为:
0 ≤ ∣ x ∣ ≤ 1 − 2 − n 0\le |x|\le1-2^{-n} 0x12n
如果数 x x x表示的是纯整数,那么小数点位于最低位 x 0 x_0 x0的右边,且数的绝对值表示范围为:
0 ≤ ∣ x ∣ ≤ 2 n − 1 0\le |x|\le2^n-1 0x2n1

2.浮点数

所谓浮点,即把数的范围和精度分别表示,相当于数的小数点位置随比例因子的不同而在一定范围内可以自由浮动。
在计算机中一个任意二进制数 N N N可以写成: N = 2 e ⋅ M N=2^e\cdot M N=2eM
其中 M M M称为浮点数的尾数,是一个纯小数。 e e e是比例因子的指数,称为浮点数的指数,常称阶码,是一个整数。
在机器中表示一个浮点数时,一是要给出尾数,用定点小数形式表示。尾数部分给出了有效数字的位数,因而决定了浮点数的表示精度。二是要给出指数,用整数形式表示,阶码(指数)指明小数点在数据中的位置,因而决定了浮点数的表示范围。


阶码:-01=101,对应补码为111
尾数:-0.1110=11110,对应补码为10010
最后结果为11110010

3.IEEE754标准

早期,各个计算机系统的浮点数使用不同的机器码表示阶和尾数,给数据的交换和比较带来很大麻烦,因此现在的计算机都采用统一的IEEE754标准的格式表示浮点数,其中规定了32位短浮点数64位长浮点数的标准格式为:

其中, S S S是浮点数的符号位, S = 0 S=0 S=0表示正数, S = 1 S=1 S=1表示负数; M M M是尾数,占用23位,小数点位置放在尾数域最高有效位的右边; E E E是阶码,占用8位,阶符采用隐含方式,即采用移码来表示正负指数。用这种方式时,将浮点数的指数真值 e e e变成阶码 E E E时,应将指数加上一个固定的偏置数127,即 E = e + 127 E=e+127 E=e+127

浮点数的规格化表示

不论是32位浮点数还是64位浮点数,如果不对浮点数的表示作出明确规定,同一个浮点数的表示就不是唯一的。例如 ( 1.75 ) 10 (1.75)_{10} (1.75)10可以表示成 1.11 × 2 0 、 0.111 × 2 1 、 0.0111 × 2 2 1.11\times2^0、0.111\times2^1、0.0111\times2^2 1.11×200.111×210.0111×22等多种形式。为了提高数据的表示精度,当尾数的值不为0时,尾数域的最高有效位应为1,这就是浮点数的规格化表示。

一个规格化的32位浮点数 x x x的真值表示为:
x = ( − 1 ) S × ( 1. M ) × 2 E − 127 , e = E − 127 x=(-1)^S\times(1.M)\times2^{E-127},e=E-127 x=(1)S×(1.M)×2E127,e=E127
一个规格化的64位浮点数 x x x的真值表示为:
x = ( − 1 ) S × ( 1. M ) × 2 E − 1023 , e = E − 1023 x=(-1)^S\times(1.M)\times2^{E-1023},e=E-1023 x=(1)S×(1.M)×2E1023,e=E1023

对于32位浮点数 N N NIEEE754定义:


4.定点数与浮点数的区别和联系

1.当相同位数的计算机表示数据(比如64位),浮点数能表示的数据范围远远大于定点数表示的数据范围。
2.当相同位数的计算机表示数据(比如64位),浮点数的相对精度比定点数要高。
3.浮点数在计算时,要分阶码部分的计算和尾数部分的计算,而且运算结果要求规格化,故浮点运算步骤比定点数运算步骤多,运算速度比定点运算速度低。

5.阶码部分为什么用移码表示

这是为了方便浮点数在进行加减运算时进行对阶操作,也就是比较大小。

比如 ( 1.01 × 2 − 1 ) + ( 1.11 × 2 3 ) (1.01\times 2^{-1})+(1.11\times2^3) (1.01×21)+(1.11×23)这两个数相加 ,在科学计数法中,通常是将小阶向大阶看齐。也就是将 2 − 1 2^{-1} 21变为 2 3 2^3 23
如果用补码来表示 − 1 -1 1 3 3 3 − 1 : 111 , 3 : 011 -1:111,3:011 1:111,3:011;很明显二进制中 111 111 111 011 011 011大。所以结果会是第一个数大于第二个数,这是明显不对的。
因此通常是在阶的基础上加上偏置常数,当偏置常数为4时,-1+4=3;3+4=7;所以结果会是第二个数大于第一个数,这样才正确。

那为什么浮点型用 2 n − 1 − 1 2^{n-1}-1 2n11而不是 2 n − 1 2^{n-1} 2n1来作为偏移值呢,比如8位机器数采用127而不是128作为偏移值?
原因是127作为偏移值时表示的范围更大,例如阶码11111110以127作为偏移值转化为真值为127,而以128作为偏移值转化为真值为126,可以看出偏移值为127时,真值大一些,也就是可表示范围会大一点。

6.数据的校验

数据在计算机系统内被处理、传输和存储的过程中可能出现错误。为了减少和避免这类错误,引入了数据校验码。校验码的基本原理就是通过增加校验位提高码距,从而使编码具有检错或纠错能力。通常是在每个字上添加一些校验位,用来确定字中出现错误的位置。

码距的计算有两种方法:
例如对于01001111
1.直接观察法:可以看出,两者有3个数位的值不同,因此码距为3
2.异或计算法:0100 ⊕ \oplus 1111=1011,结果为1011,里面有三个1,结果里面有几个1就代表有多少个数位值不同,即码距为3

码距越大,反映了码集中每两个码字之间的差别程度越大。那么从一个编码传输错误变成另一个编码的可能性越小。则其检错、纠错能力也就越强。
比如我们用0代表女,1代表男,(码距为1)这时候如果0在传输的过程中变成了1,那么我们没有办法判断是否发生了错误,因为1仍然是一个正确的编码。
但比如我们用00代表女,11代表男,(码距为2)那么我们就可以检测出1位发生错误的情况,比如00变成了10或者01,因为合法的编码只有0011
如果继续冗余,用000代表女,111代表男,(码距为3)同理。那么这时候我们可以检测出1位2位发生错误的情况。同时,我们可以纠正1位发生错误的情况,比如如果出现了001,我们很清楚的知道它原来传输的正确编码应该是000,因为只有1位出错,所以不可能是111变过来的。
码距越大,抗干扰能力越强,纠错能力越强,数据冗余越大,编码效率越低,编码电路也相对复杂,因此我们在选择码距时必须考虑信息发生差错的概率和系统能容许的最小差错率。

1.奇偶校验

基本原理:在原编码中增加一个校验位,则原编码就变成了校验码。
特点:奇偶校验码的码距为2,只能检测出奇数位出错,如果发生偶数位错误就无法检测,但经研究是奇数位发生错误的概率大很多, 而且奇偶校验码无法检测出哪位出错,所以属于无法纠正错误的校验码,并且无错结论不可信。
奇偶校验码是奇校验码和偶校验码的统称,它们都是通过在要校验的编码上加一位校验位组成。

奇校验:加上校验位后,编码中1的个数为奇数个。
偶校验:加上校验位后,编码中1的个数为偶数个。

为什么码距是2:
举个例子,给定被校验数据长度为6,我们进行奇校验,则校验码可为1100010,也可为1101011,也就是只要保证校验码中1的个数为奇数即可,而要想保持1的个数为奇数,至少需要改变两位的值,因此码距为2,偶校验同理。

2.CRC校验

CRC(Cyclic Redundancy Check)循环冗余校验码

基本原理:数据发送、接受方约定一个除数, k k k个信息位 + r +r +r个校验位作为被除数,添加校验位后要保证模2除法的余数为0,收到数据后,进行除法检查余数是否为0,若余数非0说明出错,则进行重传或纠错。

这里介绍一下多项式及其对应的编码。

可以看出,多项式与编码是一一对应的,即编码为多项式的系数值,而且多项式 G ( X ) G(X) G(X)一般题目中会给出,直接利用即可。

校验位 r r r的位数是由生成多项式 G ( X ) G(X) G(X)的位数决定的,且是生成多项式的位数减一。

若余数位过少,我们就在前面补上0,保证余数位数比除数少一位即可。

若只考虑发生一位错误的情况下:应满足 k + r + 1 ≤ 2 r k+r+1\le2^r k+r+12r k k k为信息位, r r r为校验位。

循环特性:
前提:在一位出错情况下余数具有循环特性
方法:若余数不为0,我们对余数右边补0继续做模2运算,同时得到的结果即为校验码左移一位出错的余数,如此循环,即可得到所有位单独出错的余数。
特点:接收端进行校验得到的余数与出错位位置和 G ( X ) G(X) G(X)的取值有关,与 k k k位信息的取值无关。
例子:
对于被除数1100010,除数为1011,从左到右依次分为1、2...、7,第5位出错时,余数为100,补0继续模2运算,得到余数为011,也是第4位出错时的余数。

下图可以用来练个手

3.海明校验

基本原理:将信息位分组进行偶校验,分成 r r r个校验位, r r r个校验位标注出错位置。


校验位的写法是对应序号的校验位:
其中 P 1 P_1 P1校验位对应的数据位是含有 P 1 P_1 P1编号的,即含有 1 1 1,观察得 b 1 , b 2 , b 4 , b 5 . b 7 b_1,b_2,b_4,b_5.b_7 b1,b2,b4,b5.b7均含有 1 1 1,同理 P 2 P_2 P2校验位对应的数据位是含有 P 2 P_2 P2编号的,即含有 2 2 2,观察得 b 1 , b 3 , b 4 , b 6 . b 7 b_1,b_3,b_4,b_6.b_7 b1,b3,b4,b6.b7均含有 2 2 2 P 3 P_3 P3校验位对应的数据位是含有 P 3 P_3 P3编号的,即含有 4 4 4,观察得 b 2 , b 3 , b 4 b_2,b_3,b_4 b2,b3,b4均含有 4 4 4 P 4 P_4 P4校验位对应的数据位是含有 P 4 P_4 P4编号的,即含有 8 8 8,观察得 b 5 , b 6 . b 7 b_5,b_6.b_7 b5,b6.b7均含有 8 8 8
故有 P 1 = b 1 ⊕ b 2 ⊕ b 4 ⊕ b 5 ⊕ b 7 P_1=b_1\oplus b_2\oplus b_4\oplus b_5\oplus b_7 P1=b1b2b4b5b7 P 2 = b 1 ⊕ b 3 ⊕ b 4 ⊕ b 6 ⊕ b 7 P_2=b_1\oplus b_3\oplus b_4\oplus b_6\oplus b_7 P2=b1b3b4b6b7 P 3 = b 2 ⊕ b 3 ⊕ b 4 P_3=b_2\oplus b_3\oplus b_4 P3=b2b3b4 P 1 = b 5 ⊕ b 6 ⊕ b 7 P_1= b_5\oplus b_6\oplus b_7 P1=b5b6b7

指错字的写法是对应序号的校验位加上校验位对应的数据位:
G 1 = P 1 ⊕ b 1 ⊕ b 2 ⊕ b 4 ⊕ b 5 ⊕ b 7 G_1=P_1\oplus b_1\oplus b_2 \oplus b_4\oplus b_5\oplus b_7 G1=P1b1b2b4b5b7
G 2 = P 2 ⊕ b 1 ⊕ b 3 ⊕ b 4 ⊕ b 6 ⊕ b 7 G_2=P_2\oplus b_1\oplus b_3 \oplus b_4\oplus b_6\oplus b_7 G2=P2b1b3b4b6b7
G 3 = P 3 ⊕ b 2 ⊕ b 3 ⊕ b 4 G_3=P_3\oplus b_2 \oplus b_3\oplus b_4 G3=P3b2b3b4
G 4 = P 4 ⊕ b 5 ⊕ b 6 ⊕ b 7 G_4=P_4\oplus b_5\oplus b_6\oplus b_7 G4=P4b5b6b7





7.溢出

在运算过程中,如果出现结果大于字长绝对值的现象,称为溢出。两个正数相加,结果大于机器字长所能表示的最大正数,称为正溢(上溢);两个负数相加,结果小于机器所能表示的最小负数,称为负溢(下溢)。

溢出只可能发生在同符号数相加时,例如对于两个正数相加,可能发生溢出,一正一负相加,不会发生溢出,两个负数相加,可能发生溢出。而对于减法,我们通过采用补码将其转换为了加法,一正减一负为两个正数相加,一正减一正为一正一负相加,一负减一正为两个负数相加,一负减一负为一负一正相加。

因而我们有以下的溢出判断方法:

原理: V = 1 V=1 V=1的成立条件是两个逻辑表达式的任意一个为真即可,也就是 X 0 X_0 X0 Y 0 Y_0 Y0符号相同时,且与 S 0 S_0 S0的符号相反时。也就是两个正数相加为负或两个负数相加为正时 V = 1 V=1 V=1


原理: V = 1 V=1 V=1时发生溢出,即 C 0 C_0 C0 C 1 C_1 C1不同,也就是数据位 C 0 C_0 C0进位时,符号位 C 1 C_1 C1并没有进位,而数据位 C 0 C_0 C0没有进位时,符号位 C 1 C_1 C1却进位了。


原理:在数据位前面加上两位 00 00 00 11 11 11,其中 00 00 00代表正数, 11 11 11代表负数,若两数相加得到 01 01 01,表明发生了正溢出,得到 10 10 10,表明发生了负溢出。

8.国标码GB2312

GB2312将代码表分为94个区,对应第一字节;每个区94个位,对应第二字节,两个字节的值分别为区号值和位号值加32(20H)。01-09区为符号、数字区,16-87区为汉字区,10-15区88-94区是有待进一步标准化的空白区。GB2312将收录的汉字分成两级:第一级是常用汉字计3755个,置于16-55区,按汉语拼音字母/笔形顺序排列;第二级汉字是次常用汉字计3008个,置于56-87区,按部首/笔画顺序排列。故而GB2312最多能表示6763个汉字。


因为 y y y是03区的第8行第9列,所以 y y y的码区就为 0389 0389 0389

同理,饼位于17区第9行第3列,故其码区为 1793 1793 1793

侃字位于57区第0行第9列,故其码区为 5709 5709 5709

最终字符的存储是将码区按前两位和后两位分开,并且将其转换为十六进制,然后分别加上 A 0 A0 A0,再将其合并。
为什么要加 A 0 A0 A0
GB2312 是双字节编码,为了与 ASCII 码区分开,字节的第8位必须是1,所以GB2312是8位编码。所以至少要从 0x80(128, 1000 0000) 开始吧,但是根据上面的规定,0x80 - 0x9f 要留给控制块,所以只能从 0xA0 开始咯。那为什么 GB2312 编码不是从 0xA0 开始,而是 0xA1 开始呢? 因为 0xA0 正好是图形块的空格,所以就从 0xA1 编码,这就是 0xA0 的由来。 ​

11.如何将减法转为加法

介绍这节内容时,我们先来彻底了解一下补码的意义。

如图所示,现在的时间是10点,我想把时间调到7点,那么我该怎么做呢?
第一种方法:将时针顺时针调9个单位
第二种方法:将时针逆时针调3个单位
无论我们采用哪个方法,最后得到的结果都是一样的,但是其中的数学思想却有极大的差别,因为第一种方法是,第二种方法是,但是两者却能做到殊途同归,这是为什么呢?
其实细想一下不难发现,这里用到了同余的知识,什么是同余呢?简单的说,就是模后的值相同。即9/12=9-3/12=9。由此我们可以得到启发,得到的结果是一样的,那我们可不可以用来替代呢?
下面讲下模运算

怎么判断两个数同余呢?如果a的绝对值+b的绝对值=c*模,c为正整数,则a,b同余
最后我们回到计算机里来,对于一个8bit的二进制数而言,其模的值为 2 7 − 1 2^7-1 271,因此我们在进行加减运算时,可以考虑用补码来进行,补码是在反码的基础上末位+1,而反码是在原码的基础上符号位不变,其余各位按位取反(这里考虑的是负数的机器码表示),因此补码+原码=模,也就是二者同余,故可以得到相同的结果。也就是-原码=+补码。这也解释了补码的定义为何是反码末位+1

如上图所示,对于无符号数,我们直接相加对结果没有影响,但是有符号就不一样了,如果是两个正数相加可以直接进行,但是一正一负就不行了,因为不清楚结果的符号是正还是负,如果变成减法又要设置减法器,这又会额外增加计算机的成本,于是我们就直接采用补码进行计算,这样正数相加没有影响,而负数的话又转为同余的正数,因此直接相加也没有影响,最后我们就实现了只用加法器就能进行加减运算。

12.移位

移位分为三种类型,算术移位、逻辑移位与循环移位。

1.算术移位

对于算术移位,因为我们要考虑数字的符号,所以符号位是不移动的,移动的是数值位。而算术移位又分为三种情况:原码、反码及补码。

1.原码的算术移位


如上图所示,为定点小数的算术移位,对于定点整数也是同样的操作。

2.反码的算术移位


对于正数的反码,移位运算与原码相同;对于负数的反码,因为反码的数值位与原码相反,因此原来原码进行补位时补的0变成反码就应该补1

3.补码的算术移位


对于正数的补码,移位运算与原码相同;对于负数的补码,

最后对三种情况进行总结,如下图所示,但要注意的是,由于计算机的位数有限,因此有时候无法用算数移位精确地等效乘除法。

2.逻辑移位


如上图所示,逻辑移位比较简单,可以看做是无符号数的算术移位,因此就不需要考虑原码、反码和补码之类的。

3.循环移位

如上图所示,循环移位是指循环移动,用溢出位去补最低位或最高位。
举个例子:对于01101011,进行循环左移一位后为11010110,这个结果是怎么得到的呢?我们首先把所有位往左移,这时第一位的0就相当于溢出,而第八位的0又移到第七位,导致了此时的第八位为空,因此我们把溢出的0放在第八位,这样就得到了循环左移一位的结果。循环右移也是同样的道理,比如对于01101011,得到的结果为10110101
上面讨论的是不带进位的循环移位,对于带进位的循环移位,就是把溢出位的作用给进位。

13.定点数运算


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值