系列文章目录
第六章——计算机的运算方法
文章目录
前言
今天是7月26日,开始预习第六章,这一部分是有关有符号数、无符号数以及一些运算逻辑单元
这部分大二已经学习过了,会很快带过,只记录一些需要注意的点,不再系统记录
一、无符号数和有符号数
1.1 无符号数
1.2 有符号数
1.2.1 机器数与真值
约定第一个数字是符号位,符号位后面紧跟着的是小数点位置
这是定点数
这里约定小数点位置在最后,这也是定点数
1.2.2 原码表示法 (考试的时候注意写上公式!)
原码简单来说,是先表示x的绝对值,然后在前面加一个0或者1,表示符号
需要注意的是,这里如果表示0,+0和-0的表示不同
注意这里的整数原码用的是逗号,后面小数的表示用的小数点(无论逗号还是小数点都只是阅读方便而不会真正存储)
小数的表示用的小数点(无论逗号还是小数点都只是阅读方便而不会真正存储)
例子:
缺点:用原码做加法的时候,运算器的加可能是实际操作的加也可能是实际操作的减,这会出现不同的结果,这对运算器比较麻烦,我们需要用补码方法实现加减法的归一化
1.2.3 补码表示法 (真值用于定义,原码用于简便方法)
1.2.3.1 整数的补码
一个负数加上“模”得到该负数的补数
正数和对应补数加上模后的表示是一样的,这样是不行的,如果以这个加和结果作为补码,则不能进行区分他是在做加法(加0101)还是做减法(减1011)——> 用一个符号位来将两者区分
为此我们希望把这个加和前面再加个符号位,那么对应负数要转换为补码的话需要加的是
2
n
+
1
2^{n+1}
2n+1,正数仍然是加
2
n
2^{n}
2n,前面符号位补0。这样我们可以得到符号位
补码形式,整数还是小数,0的表示无论正负都是相同的(下图的n不包括符号位)
1.2.3.2 小数的补码
1.2.3.3 求补码的快捷方式
负数的补码求解:符号位不变,后面数值位按位取反后+1
要注意的是,补码求原码和原码求补码的过程都是,符号位不变,后面数值位按位取反后+1
要求的是x,因此对应 求得的是真值 ,应该是带正号或者负号的数,不再有符号位!!!!
1.2.3.4 几个例子
整数的补码求x,直接加正号
小数的从补码算真值,可以推导:
1.0001-10.0000 = 1.0001 - 1.1111 - 0.0001 = - 0.1110 - 0.0001 = - 0.1111
这也是符号位不变,按位取反之后末尾加1
要注意原码和真值的区别,真值是带有正负号的
这里要注意的是小数以及整数的补码定义时,用的是x,这个x不是原码而是真值
这里的正0还有负0的补码,推荐用定义进行计算,毕竟是特殊值
这个负0,可以理解为,10.0000-0.0000 = 10.0000 , 前面的1丢掉,最后剩下0.0000
正0和负0的补码是相同的
1.2.4 反码表示法
1.2.4.1 整数的反码
1.2.4.2 小数的反码
1.2.4.3 几个例子
1.2.5 原码、反码、补码 三种机器数的小结
1.2.7 补码的补充知识点(小数,已知 [ y ] 补 求 [ − y ] 补 [y]_补求[-y]_补 [y]补求[−y]补)
推导:
当y为正数,那么可以推导如下
结果如下:
正数推导:
正数结果:
1.2.6 移码表示法
移码表示是加上
2
n
2^{n}
2n,与补码不一样,补码是负数加上
2
n
+
1
2^{n+1}
2n+1
补码不能简单比较两个数字的大小,而移码把负数加上偏移得到一个正数,用移码可以比较大小
移码在真正应用的时候,用于阶码,所以这里没有给出小数的表示
在移码的表示中,也将符号位与值隔开。因为平移的缘故,负数的符号位是0,正数的符号位是1
1.2.6.1 移码与补码的比较
正数:移码和补码只有符号位不同,数值位照抄
负数:移码和补码加的偏移量不一样,但是很显然,移码和补码的数值位应该是一致的
移码和补码只差一个符号位
1.2.6.2 直观对照表
他们的0都是唯一表示,移码的0的表示是1,00000,而0,00000是最小数字的表示
二、数的定点表示和浮点表示
2.1 定点表示
2.2 浮点表示
2.2.1 浮点数的表示形式
浮点表示的S,应该是0~1的
规格化数的形式应该是小数点后一位是非0的
2.2.2 浮点数的表示范围
上溢!和 下溢!有两个上溢!
上溢:计算出错
下溢:机器零
例题:
表示最大范围的时候,尾数最少15位,也就是n应该尽可能小但是应该最少是15位,因为这里需要让正负三万的每个能表示的尽可能表示,因此要留15位。
2.2.3 浮点数的规格化形式
r的值不同,如果r为2,那么尾数的1位就是1位二进制数
如果r为4,那么尾数的两位表示一个四进制数,最高位的这两位不能同时为0
2.2.4 浮点数的规格化
这里的尾数左移和右移,是小数点不动而移动数字
(在规格化的情况下!!!!!) 这里基数r越大,浮点数的范围越大,精度越低,表示的数个数越多
为什么表示个数越多呢?
请跳转到这个地方点这里,这个答主完美展示了原因!!超级感谢这位大佬
为什么r变大,精度变低呢?
假若r=16,那么0.00010000这个是r=16的情况的规格化情况。但是他的精度实际上只是后面的10000,这精度比不上r=2的情况
在这个1在不同位置的时候他的这个数字的的精度不一样
注意这与上面最大和最小的数值不同,这里算绝对值最小的数的时候,不是尾数最后一个数字为1
而是小数点后第一个为1!!!!
2.3 举例
在定点机表示中,正数的原码反码补码都一样
但是注意在浮点表示中,阶码是负数,所以原码补码反码不同,需要分别表示
当阶码是-16,也就是补码的最小数的时候,无论尾码是什么样的都认为是机器零
当阶码是移码表示,它的表示是全零的时候,无论尾码是什么样子都认为是机器零
阶码为移码的时候是,阶码全零或者尾码全零,或者全零
注意这里对机器零的判断最好用的就是移码进行表示
2.4 IEEE 754标准
这里的尾数中,第一位一定是1,所以它的表示可以把第一位的1省略
若要表示0那么就把阶码赋值到最小表达或者最小表达以下
754标准的单精度阶码偏移是127,双精度偏移量是1023!
符号位 s=1
带隐藏表示的1的时候的尾数 1.10011
指数 11 阶码的变换应该是127+3=128+2=1000 0010
那么IEEE754 表示应该是1 1000 0010 100 1100 0000 0000 0000 0000
例题:
第一问:
注意这个机器字长是16位,那么就是说明数值位加上符号位一共是十六位
第二问:
原码表示的范围是关于0对称的
原码的表示的定点小数,很明显应该是1.111···1~0.111···1
第三问:
补码的定点小数,补码一般不对称,负数得比正数多一个,因为补码中只有一个0的表示
1.00···0~0.11··1
第四问:
补码表示的定点整数,依然是负数比整数多一个
1,00··0~0,11···1
第五问:
原码表示的范围是关于0对称的
很明显应该是11···1~011···1
第六问:
两边分别取绝对值最大和最小的值,构成范围
第七问:
这里需要注意,这里尾数和阶数都是补码表示,而且要注意尾数应该是规格化数
正数照常,不过要注意绝对值最小的数是
0.10
⋅
⋅
⋅
0
×
2
−
32
0.10···0\times 2^{-32}
0.10⋅⋅⋅0×2−32,因此正数的范围:
需要我们注意的是负数的最大值,这里应该让绝对值最小,但是对于补码的负数表示来说,它的规格化形式不是尾码第一位为1
详细规定见这里,刚开始我也有点疑惑,不过之前有学习补码的经验,很好理解这里的设定
那么这里就不是很难了,不过我认为老师在视频中写的应该是不对的,最后结果的补码形式的最大负数应该是
1.011
⋅
⋅
⋅
⋅
1
×
2
−
32
1.011····1\times 2^{-32}
1.011⋅⋅⋅⋅1×2−32,对应的十进制表示老师的答案是对的,老师写的应该是对应原码,十进制答案是
−
(
1
2
+
2
−
9
)
×
2
−
32
-(\frac{1}{2}+2^{-9})\times2^{-32}
−(21+2−9)×2−32所以答案的值应该是:
−
2
31
∼
−
(
2
−
1
+
2
−
9
)
×
2
−
32
-2^{31}\sim - (2^{-1}+2^{-9})\times2^{-32}
−231∼−(2−1+2−9)×2−32
这里我在参考这篇博客的时候会注意到一个问题,按照原理
−
1
2
-\frac{1}{2}
−21这个数字对应的原码补码都是1.10··0,它的真值确实是在小数点后额第一位是有效位,但是为什么我们在补码的负数讨论的时候认为必须要让尾数为1.0xxx呢。我的理解是我们在机器中一般是用补码表示,所以与原码的讨论不同,我们需要考虑硬件设计,这样硬性规定补码尾数数值的第一位为0更加容易判断。这来自上面那篇博客的评论区,截图如下:
三、定点运算
3.1 移位运算
3.1.1 移位运算
机器中的移位不是小数点的移动,因为数值表示中没有表示小数点的硬件。数字的移动都是数据相对于小数点的移动
3.1.2 算术移位
注意这些移位是不移动符号位的!!!
正数照常
负数如果是原码,数值位置都是用0填充
如果是反码,数值位原来的0对应的需要填充的就是1
而补码如图中右上角所示,左移在右端补0,右移在左边补1,这个1是对应着
x
‾
\overline{x}
x这里的0对应的是1
例子:
3.1.3 逻辑移位与算术移位的对比
算术移位用于有符号数的移位,所以给他一个数他识别第一位是符号位,所以他不会动第一位
逻辑移位直接连着第一位一起都移动
下图的例子,算术移位是以补码为例子的
最后一行的
C
y
C_y
Cy是进位位,用于存放移丢的数
3.2 加减法运算
3.2.1 运算规则
符号位一起运算!!!这里的模运算的意思就是将溢出的位自然丢掉,最后结果是正确的
例子:
但是这个例子没有提到机器字长的限制,注意在题目中要看机器字长的限制
考虑机器字长的题目:
一定要注意:A-B没有括号,没说是什么码,因此应该是真值。!!!
考虑机器字长后,我们可以发现一个问题,那就是溢出问题,下面两个上溢错误:
注意这是正数,原码和补码一致:0.1001+0.1011=1.1100 运算结果出错,停机处理错误
3.2.2 溢出判断
3.2.2.1 一位符号位判断溢出
3.2.2.2 两位符号位判断溢出(即两位符号位)
这里是以小数为例,它们的补码符号位用两位表示,00和11
这样对应的定义就是负的小数是mod4,负的整数时加
2
n
+
2
2^{n+2}
2n+2,比原来多一位
判断是否溢出:看结果的符号位是否变成了01或者是10,出现10或者01就是溢出了
在溢出的情况下, 最高符号位代表其真正的符号
3.2.2.3 补码加减法的硬件配置
图示的A:模型机的ACC,保存的是被加数或者是被减数
图示的X:模型机的X,保存的是加数或者是减数
图示
G
A
G_A
GA:标记,做加法的话置1
图示
G
S
G_S
GS:标记,做减法的话置1
3.3 乘法运算
3.3.1 笔算乘法的分析
乘数位数是4位,乘积结果是8位
3.3.2 笔算乘法的改进
3.3.2.1 笔算乘法的改进
这四个步骤来看,“4个位积一起相加”硬件实现不是很简单,因为ALU没办法直接加四个
n次加法,n次移位,n是数值部分的位数,上例的n=4
下面推导得到的最后一行的蓝色部分是1011,正好对应数值部分
3.3.2.2 笔算乘法的改进(竖式)
在第一章时候我们学的是,被乘数在X寄存器中。ACC存放乘积结果高位,MQ存放乘积低位,而且在初始MQ存放的是乘数
具体原因可以乘法计算的过程如下,部分积的右移的溢出位结果会被储存在MQ中:
但是符号位需要特殊计算!
首先是要部分积清零,而且由过程可以看出来右移是逻辑右移,溢出的那一位符号位要给移动回来
四次加法四次右移
3.3.2.3 小结
三个寄存器,一个用来一直保存被乘数(不需要移位功能),一个ACC保存部分积高位,一个MQ保存部分积低位和乘数
(后面两个要有移位功能)。全加器只需要n+1位,而不是2n+1位!!!因为他是随时在移动的,相加的只是n位加法
3.3.3 原码的乘法运算
3.3.3.1 原码一位乘运算规则
3.3.3.2 原码一位乘递推公式
n次相加,n次相乘
下图我们要注意,图中的逻辑右移
因为是绝对值相乘,所以在逻辑移位的时候,尽管小数点左边的数字是1,但是右移以后还是用0补全。不能遗忘最后一个移位,最后一次移位是为了把乘积结果全部放到ACC和MQ里面
符号位的那个1在这里并不是代表符号位
用移位的次数判断乘法是否结束!!!
3.3.3.3 硬件配置
A寄存器,n+1位,这里多出的1位,最高位不是符号位,保存低位数值相加后的进位
X寄存器,n+1位,保存被乘数,计算过程中保持不变
Q寄存器,n+1位,MQ是乘商寄存器,开始时保存着乘数,计算过程中,会进行移位。高位逐渐被部分积的低位占据
计数器C,用来记录移位次数,每移位一次,计数器减1,计数器为0时,运算结束
S符号位,异或得到
G
M
G_M
GM:乘法标志
移位和加控制:这是由乘数的最后一位来控制的:
- 乘数最低位为1的时候,控制门打开,被乘数才被送入加法器,累加后右移一位
- 乘数最低位为0,控制门直接把0送入加法器;或者不送入0,直接由“移位和加控制”直接进行移位操作
所以这里解释了上面为什么用移位操作次数控制乘法的结束,而不是用加法的次数,这里当乘数最低位为0的时候可能不做加法
3.3.4 补码一位乘法
3.3.4.1 补码乘法的原理
这里因为刘宏伟老师没有讲,这里是基于王道的笔记
注意补码的每一次右移是算数的右移!符号位需要参与运算,补码的乘法结果正负由移位和加法运算自然确定
补码乘法与原码相比,最后会多一次加法,每次加法取决于的是“辅助位-MQ”
3.3.4.2 补码乘法的硬件实现
在硬件实现时,辅助位是MQ寄存器的最末尾,然而在原理中所说的“MQ中最低位”是实际中的倒数第二位。
所以实际上的MQ为n+2位,为了保持一致,其他的寄存器也是n+2位,ACC和X寄存器中就对应保存两位符号位的补码表示。
在每次MQ右移的时候,MQ的倒数第二位就会右移代替最末尾的辅助位。
−
x
-x
−x的补码交给辅助电路进行转换
3.3.4.3 补码乘法的手算模拟
注意是五次加法,四次算术右移
最后一次加法的判断会把乘数的符号位也涉及到
3.3.4.4 Booth编码
3.4 除法运算
3.4.1 如何进行笔算除法
3.4.1.1 笔算除法
这里分析可以发现问题,按照笔算除法的方式,余数会进行填0,除数会进行移位,寄存器的位数是个问题
上商应该是0还是1,用的是余数与右移一位的除数作比较
余数是写的是绝对值的差,写正余数
低位补0,需要让定点机位数(寄存器位数)变长,不可行
3.4.1.2 笔算与机器除法进行比较
3.4.1.3 原码除法的约定与规则
被除数为0的操作通过直接判断,得到结果为0
除数为0的情况直接出错
小数定点除法中,被除数大于除数时,会发生溢出
我们需要被除数小于除数,让结果还是小数;整数定点除法,被除数要大于除数,结果是整数
至于如何进行运算,运算方法有恢复余数法和加减交替法
3.4.2 如何用计算机硬件模拟笔算除法
3.4.2.1 恢复余数法
这里是以定点小数机作为的例子,包括第一位的上商,一共上商五次,左移了四次,第一次上商的0被移到小数点前面
如果第一次上商1,那么说明分子大于分母,出现溢出
3.4.2.2 不恢复余数法(加减交替法)
3.4.2.2.1 不恢复余数法(加减交替法)规则
3.4.2.2.2 加减交替除法硬件配置
A寄存器:ACC寄存器,保存被除数和余数
X寄存器:保存除数
Q寄存器:保存商
n次移位,n+1次加法
G
D
G_D
GD: 除法标志
S:符号位
V:是否发生溢出
四、浮点四则运算
4.1 浮点数的加减法
4.1.1 对阶
在计算机的运算中,我们通常更希望进行的是数据右移,这样就算丢失了最右边的位,也只是精度丢失,比左移的丢失代价小
如果是规格化数,左移会让直接移丢第一位,把1移丢
在计算机中的对阶,是小阶向大阶看齐
但是这里运算结果需要注意!!它的运算结果不是规格化数,需要之后再进一步规格化
4.1.2 规格化
4.1.2.1 规格化的定义与特例
规格化,尽可能地提高浮点数在计算机中的表示精度
**注意这里的特例,
−
1
2
-\frac{1}{2}
−21 **还有-1的情况,
−
1
2
-\frac{1}{2}
−21的原码和补码的符号位与第一位都是相同的,这里也正好呼应了我们在2.3的例题中的资料分析,在实现电路中是用异或电路进行的实现,所以还是用小数点后的第一位与符号位数字是否相同作为标准。
-1没有对应原码
4.1.2.2 如何进行规格化
右规只在相加后尾数溢出的时候,进行一次右边规
4.1.2.3 规格化例题
因为我们使用的是补码操作,阶符和数符都取两位
注意小数!这里是小数,在补0的时候在最后末尾进行补0,而不是跟整数一样在前面补0!!!!!
4.1.3 舍入
- 0舍1入法,舍去的若是0则直接丢弃,舍入的是1则进位
- 恒置1法,无论如何舍入都把保留的数字的最低位置为1
这里加入一个例题:
**运算方式都用补码,阶符和数符均取两位!!!溢出的判断比较容易 **
4.1.4 溢出判断
如果发生下溢,被视作0
上溢:出错处理
即使在能表示的范围中,计算机能表示的点也都是离散的,而不是连续的,在能表示的两个点中间的数字还是不能被表示,需要进行近似
4.2 浮点数的乘除法
这里老师跳过去了,没有讲,不知道开学老师会不会讲,先留个坑~
好吧,开学老师这里也不讲了,跟前面的差不多。
五、算术逻辑单元(ALU)
算术逻辑单元与控制器集成在一起就是CPU
5.1 ALU电路
组合逻辑电路,无记忆功能。为了能够正常运算使用,在输入和输出端都连接寄存器
A
i
A_i
Ai和
B
i
B_i
Bi是参加运算的两个数据
K
i
K_i
Ki:控制端确定什么类型的运算,是算术运算、逻辑运算、定点运算还是浮点运算?
F
i
F_i
Fi:输出结果
5.2 快速进位链
加法器中影响速度的瓶颈就是加法器中的进位链
5.2.1 并行加法器
这里
C
i
C_i
Ci的表达式可以看到最影响速度的是需要等待上一位的进位,因此我们对其进行化简变形
得到本地进位,以及决定是否需要上一位仅为的传送条件
5.2.2 串行进位链
“进位链” :传送进位的电路,在加法器中把进位产生相关的电路独立出来,产生的进位之后再与 A i A_i Ai B i B_i Bi一起参与运算
5.2.3 并行进位链
所谓“并行”,我们想要n位加法器的全部进位能过够同时产生
每个门的扇入比较大,下图只是四位的运算,当其在应用中为32位的时候,电路会非常复杂
我们希望电路更加简单一点,提出后面提到的两种折中方式
注意,这里在计算需要的时间的时候,与或非门设为1.5
t
y
t_y
ty,或门或者非门是1
t
y
t_y
ty,这一次并行进位链的计算是2.5
t
y
t_y
ty
5.2.3.1 单重分组跳跃进位链
n位全加器,n比较大,那就进行分组后,分别进行运算后再进行串行进位
5.2.3.2 双重分组跳跃进位链