计算机组成原理-6-计算机的运算方法

6. 计算机的运算方法

文章目录

  • 6. 计算机的运算方法
    • 6.1 机器数的表示
      • 6.1.1 无符号数和有符号数
      • 6.1.2 有符号数-原码
      • 6.1.3 有符号数-补码
      • 6.1.4 有符号数-反码
      • 6.1.5 有符号数-移码
      • 6.1.6 原码、补码、反码的比较
    • 6.2 数的定点表示和浮点表示
      • 6.2.1 定点表示
      • 6.2.2 浮点表示
      • 6.2.3 ΔIEEE 754标准
    • 6.3 定点运算
      • 6.3.1 移位运算
      • 6.3.2 加减法运算-补码
      • 6.3.3 Δ乘法运算-原码
      • 6.3.4 Δ乘法运算-补码
      • 6.3.5 除法运算-原码
      • 6.3.6 Δ除法运算-补码
    • 6.4 浮点四则运算
      • 6.4.1 浮点数的加减运算
      • 6.4.2 Δ浮点数的乘除运算
      • 6.4.3 Δ浮点运算的硬件配置
    • 6.5 算术逻辑单元
      • 6.5.1 ALU电路
      • 6.5.2 快速进位链

  • 本笔记参考哈工大刘宏伟老师的MOOC《计算机组成原理(上)_哈尔滨工业大学》、《计算机组成原理(下)_哈尔滨工业大学》。
  • 或者是B站《计算机组成原理(哈工大刘宏伟)135讲(全)高清》,大家一起听比较热闹。
  • 中文教材:《计算机组成原理(第二版)-唐朔飞.pdf》、《学习指导与习题解答(第2版)-唐朔飞.pdf》
  • 本篇笔记对应课程第六章(下图加粗)。

本章全是重点😅,Δ表示笔记补充了MOOC没有讲到的内容。


本章重点:

  1. 计算机中数的表示【6.1、6.2】:介绍能够被硬件直接识别和处理的数据类型。也就是计算机指令中,包含对这些数据类型进行处理的指令,所以必须用硬件来实现这些运算。
  2. 计算机的运算方法【6.3、6.4】:整体思路就是对笔算方法进行改进,主要关心硬件可实现。
  3. 运算器的设计【6.5】:介绍CPU中的算术逻辑运算单元ALU的电路设计。

6.1 机器数的表示

6.1.1 无符号数和有符号数

  我们平常手写的有符号数被称为“真值”,而“机器数”则是数字在计算机中的表示方法。“无符号数”就是没有正负号的整数(默认正数),只需要将无符号数用二进制表示,即可按位存储到寄存器中。寄存器的位数反映无符号数的表示范围,比如8位寄存器的取值范围就是 0 ∼ 255 0\sim 255 0255 (C语言char)、16位寄存器的取值范围就是 0 ∼ 65535 0\sim 65535 065535 (C语言unsigned short)、32位寄存器的取值范围就是 0 ∼ 2 32 − 1 0\sim 2^{32}-1 02321 (C语言unsigned int)。

  有符号数包括“符号部分”、“数值部分”,将“符号部分”的正负号进行数字化表示,然后和“数值部分”分别保存到寄存器中,就是“机器数”。通常使用最高位表示“符号位”,也就是将寄存器的最高位作为符号位,“0”就表示为“正号+”、“1”就表示为“负号-”。下图给出“真值”和“机器数”的关系:

有符号数
将±变成0/1
将0/1变成±
机器数
真值
图6-1 有符号数的“真值”和“机器数”之间的转换
  • 符号位:默认为机器数的最高位,0表示正、1表示负。
  • 数值部分:机器中没有硬件表示小数点,只靠约定。比如对于纯小数来说,符号位后面就是小数点。
  • 位数:寄存器长度有限,所以机器数会受到存储字长的限制。

注:本节只考虑有符号的 整数绝对值小于1的小数。绝对值比1大的小数(如“ 8.4 8.4 8.4”),将在下一节“6.2节-数的定点表示和浮点表示”再进行介绍。

下面介绍四种机器数:原码、反码、补码、移码。主要关心:

  • 机器数与真值的转换。
  • 不同机器数形式之间的转化。
  • 机器数表示的范围与其字长的关系。

6.1.2 有符号数-原码

图6-2 原码的计算公式

  将数值部分写成二进制形式、符号位使用0/1表示就是“原码”,也就是“带符号的绝对值表示”。上面直接给出原码表示法的计算公式,但实际上,上述计算公式是根据下面的思想反推出来的!比如下面直接给出二进制数,写出其原码:

整数:用 逗号 将“符号位”和“数值部分”隔开。

  • x = + 1110 ⟶ [ x ] 原 = 0 , 1110 x=+1110 \longrightarrow [x]_{原}=0,1110 x=+1110[x]=0,1110
  • x = − 1110 ⟶ [ x ] 原 = 1 , 1110 = 推导公式 1 , 0000 + 0 , 1110 x=-1110 \longrightarrow [x]_{原}=1,1110\xlongequal{推导公式}1,0000+0,1110 x=1110[x]=1,1110推导公式 1,0000+0,1110

小数:用 小数点 将“符号位”和“数值部分”隔开。

  • x = + 0.1101 ⟶ [ x ] 原 = 0.1101 x=+0.1101 \longrightarrow [x]_{原}=0.1101 x=+0.1101[x]=0.1101,注意前面的“0”表示数值大小,后面原码的“0”表示正负号
  • x = − 0.1101 ⟶ [ x ] 原 = 1.1101 = 推导公式 1.0000 + 0.1101 x=-0.1101 \longrightarrow [x]_{原}=1.1101\xlongequal{推导公式}1.0000+0.1101 x=0.1101[x]=1.1101推导公式 1.0000+0.1101

注:假设数值部分为4位。

来看几个例子:

注:下面均假设数值部分为4位。

【例6.1】已知 [ x ] 原 = 1.0011 [x]_{原}=1.0011 [x]=1.0011,求 x x x
解:由定义得 x = 1 − [ x ] 原 = 1 − 1.0011 = − 0.0011 x=1-[x]_{原}=1-1.0011=-0.0011 x=1[x]=11.0011=0.0011

【例6.2】已知 [ x ] 原 = 1 , 1100 [x]_{原}=1,1100 [x]=1,1100,求 x x x
解:由定义得 x = 2 4 − [ x ] 原 = 10000 − 1 , 1100 = − 1100 x=2^4-[x]_{原}=10000-1,1100=-1100 x=24[x]=100001,1100=1100

【例6.3】已知 [ x ] 原 = 0.1101 [x]_{原}=0.1101 [x]=0.1101,求 x x x
解:因为原码符号位为0,表示为正数,所以直接 x = + 0.1101 x=+0.1101 x=+0.1101

【例6.4】求 x = 0 x=0 x=0 的原码?
解:对于小数来说, [ + 0.0000 ] 原 = 0.0000 [+0.0000]_{原}=0.0000 [+0.0000]=0.0000 [ − 0.0000 ] 原 = 1.0000 [-0.0000]_{原}=1.0000 [0.0000]=1.0000
  对于整数来说, [ + 0 ] 原 = 0 , 0000 [+0]_{原}=0,0000 [+0]=0,0000 [ − 0 ] 原 = 1 , 0000 [-0]_{原}=1,0000 [0]=1,0000
  即,“+0”和“-0”的原码不同!

图6-3 使用“原码”计算加法的问题

  原码的特点就是简单、直观。但是用原码作加法时,两个操作数符号不同时,本质上还是要执行减法(如上图)。此时就希望找到一个与负数等价的正数来代替这个负数,使“减”转化成“加”,也就是“补码”。

6.1.3 有符号数-补码

图6-4 补码的计算公式

  “补”这个概念来自于时钟,比如想将6点时钟拨成3点,那么可以逆时针-3小时、或者顺时针+9小时(因为时钟要对12取模),也就是“-3”和“+9”等价!于是 “补码”就是与负数等价的正数,根本思想为,一个正数和一个负数互为补数时,它们绝对值之和即为模数。正数的补数即为其本身,负数加上模数则为其补数。但实际负数的补码,可用原码除符号位外每位取反,末位加1求得。也就是,正数的补码为其自身,负数的补码=反码+1。如下:

整数:用逗号将“符号位”和“数值部分”隔开。

  • x = + 1010 ⟶ [ x ] 补 = 0 , 1010 x=+1010 \longrightarrow [x]_{补}=0,1010 x=+1010[x]=0,1010
  • x = − 1010 ⟶ [ x ] 补 = 10000 + ( − 1110 ) = 1 , 0110 = 发现规律 1 , ( 0101 + 0001 ) = [ x ] 反 + 1 x=-1010 \longrightarrow [x]_{补}=10000+(-1110)=1,0110\xlongequal{发现规律}1,(0101+0001)=[x]_{反}+1 x=1010[x]=10000+(1110)=1,0110发现规律 1,(0101+0001)=[x]+1

小数:用小数点将“符号位”和“数值部分”隔开。

  • x = + 0.1110 ⟶ [ x ] 补 = 0.1110 x=+0.1110 \longrightarrow [x]_{补}=0.1110 x=+0.1110[x]=0.1110,注意前面的“0”表示数值大小,后面原码的“0”表示正负号
  • x = − 0.1110 ⟶ [ x ] 补 = 10.0000 + ( − 1.0010 ) = 1.0010 = 发现规律 1. ( 0001 + 0001 ) = [ x ] 反 + 1 x=-0.1110 \longrightarrow [x]_{补}=10.0000+(-1.0010)=1.0010\xlongequal{发现规律}1.(0001+0001)=[x]_{反}+1 x=0.1110[x]=10.0000+(1.0010)=1.0010发现规律 1.(0001+0001)=[x]+1

下面给出几个例子:

【例6.5】已知 [ x ] 补 = 0.0001 [x]_{补}=0.0001 [x]=0.0001,求 x x x
解:正数的补码为其自身,显然 x = + 0.0001 x=+0.0001 x=+0.0001

【例6.6】已知 [ x ] 补 = 1.0001 [x]_{补}=1.0001 [x]=1.0001,求 x x x
解:由定义得 x = [ x ] 补 − 2 = − ( 10.0000 − 1.0001 ) = − 0.1111 x=[x]_{补}-2=-(10.0000-1.0001)=-0.1111 x=[x]2=(10.00001.0001)=0.1111。或者直接 x = [ 1.0001 − 0.0001 ] 反 = − 0.1111 x=[1.0001-0.0001]_{反}=-0.1111 x=[1.00010.0001]=0.1111,非常便捷。

【例6.7】已知 [ x ] 补 = 1 , 1110 [x]_{补}=1,1110 [x]=1,1110,求 x x x
解:可以由公式反推,也可以直接 x = 1 , [ 1110 − 0001 ] 反 = − 0010 x=1,[1110-0001]_{反}=-0010 x=1,[11100001]=0010

【自定义例】求 0 0 0 的补码?
解:对于小数来说, [ + 0.0000 ] 补 = 0.0000 [+0.0000]_{补}=0.0000 [+0.0000]=0.0000 [ − 0.0000 ] 补 = 1.1111 + 0.0001 = 0.0000 [-0.0000]_{补}=1.1111+0.0001=0.0000 [0.0000]=1.1111+0.0001=0.0000
  对于整数来说, [ + 0 ] 补 = 0 , 0000 [+0]_{补}=0,0000 [+0]=0,0000 [ − 0 ] 补 = 1 , 1111 + 0 , 0001 = 0 , 0000 [-0]_{补}=1,1111+0,0001=0,0000 [0]=1,1111+0,0001=0,0000
  即,“+0”和“-0”的补码相同!

【自定义例】 求真值 − 1.0000 -1.0000 1.0000 的补码?求补码 [ x ] 补 = 1 , 0000 [x]_{补}=1,0000 [x]=1,0000 对应的真值?
解:由小数补码的定义得 [ x ] 补 = 2 + x = 10.0000 − 1.0000 = 1.0000 [x]_{补} = 2+x=10.0000-1.0000=1.0000 [x]=2+x=10.00001.0000=1.0000原码无法表示 − 1.0000 -1.0000 1.0000
  由正数补码的定义得 x = [ x ] 补 − 2 5 = − ( 10 , 0000 − 1 , 0000 ) = − 1 , 0000 = − 2 5 x=[x]_{补}-2^5=-(10,0000-1,0000)=-1,0000=-2^5 x=[x]25=(10,00001,0000)=1,0000=25
  即,只有符号位是1的补码,表示取值范围内最小的幂次!

6.1.4 有符号数-反码

图6-5 反码的计算公式

  反码很简单,就是正数的反码为其自身,负数的反码将其“原码”的“数值部分”按位取反、“符号位”不变。如下:

整数:用逗号将“符号位”和“数值部分”隔开。

  • x = + 1101 ⟶ [ x ] 反 = 0 , 1101 x=+1101 \longrightarrow [x]_{反}=0,1101 x=+1101[x]=0,1101
  • x = − 1101 ⟶ [ x ] 反 = 1 , 0010 x=-1101 \longrightarrow [x]_{反}=1,0010 x=1101[x]=1,0010

小数:用小数点将“符号位”和“数值部分”隔开。

  • x = + 0.1101 ⟶ [ x ] 反 = 0.1101 x=+0.1101 \longrightarrow [x]_{反}=0.1101 x=+0.1101[x]=0.1101,注意前面的“0”表示数值大小,后面原码的“0”表示正负号
  • x = − 0.1010 ⟶ [ x ] 反 = 1.0101 x=-0.1010 \longrightarrow [x]_{反}=1.0101 x=0.1010[x]=1.0101

【例6.8】已知 [ x ] 反 = 0 , 1110 [x]_{反}=0,1110 [x]=0,1110,求 x x x
解:由定义得 x = + 1110 x=+1110 x=+1110

【例6.9】已知 [ x ] 反 = 1 , 1110 [x]_{反}=1,1110 [x]=1,1110,求 x x x
解:由定义得 x = − 0001 x=-0001 x=0001

【例6.10】求 0 0 0 的反码?
解:对于小数来说, [ + 0.0000 ] 反 = 0.0000 [+0.0000]_{反}=0.0000 [+0.0000]=0.0000 [ − 0.0000 ] 反 = 1.1111 [-0.0000]_{反}=1.1111 [0.0000]=1.1111
  对于整数来说, [ + 0 ] 反 = 0 , 0000 [+0]_{反}=0,0000 [+0]=0,0000 [ − 0 ] 反 = 1 , 1111 [-0]_{反}=1,1111 [0]=1,1111
  即,“+0”和“-0”的反码不同!

6.1.5 有符号数-移码

图6-6 补码难以直接比较大小

  如上图,补码表示很难直接判断其真值大小。单纯从寄存器的角度看,不仅所有的负数都比正数大,就连负数也是按照逆序排序的。于是很自然的就想到直接将补码的符号位取反不就可以了!于是给出移码的定义,如下:

图6-7 移码的计算公式

移码和补码的比较

  • x = + 1100100 ⟶ [ x ] 补 = 0 , 1100100 [ x ] 移 = 1 , 1100100 x=+1100100 \longrightarrow [x]_{补}=0,1100100\quad [x]_{移}=1,1100100 x=+1100100[x]=0,1100100[x]=1,1100100
  • x = − 1100100 ⟶ [ x ] 补 = 1 , 0011100 [ x ] 移 = 0 , 0011100 x=-1100100 \longrightarrow [x]_{补}=1,0011100\quad [x]_{移}=0,0011100 x=1100100[x]=1,0011100[x]=0,0011100

移码的特点:

  1. “补码”与“移码”符号位相反。两者的转换非常简单。
  2. 不区分正数和负数“+0”和“-0”的移码相同!
  3. 小数没有移码。在计算机中,“移码”专用于判断,通常用于“浮点数”的阶码部分,所以没有小数的移码定义。
  4. 最小真值的移码为全0。根据第一条,最小真值的补码只有符号位为1。

6.1.6 原码、补码、反码的比较

  下图给出了“原码”、“补码”、“反码”的转换关系:

将±变成0/1
符号位不变
数值部分按位取反
+1
符号位不变,数值部分取反、+1
有符号数的真值
原码
反码
补码
图6-8 负数的机器数转换关系

正数的机器数都与原码相同,负数有如下转换关系:

  • 【原码–>反码】除符号位外每位取反。
  • 【反码–>补码】末位加1。
  • 【原码–>补码】除符号位外每位取反、末位加1。
  • 【补码–>原码】除符号位外每位取反、末位加1。

注意:【原码–>补码】和【补码–>原码】的转换逻辑相同!

下面给出两个例子:

【例6.11】设机器数字长为8位(其中1位为符号位)。对于整数,当其分别代表无符号数、原码、补码和反码时,对应的真值范围各为多少?
即,补码比原码、反码可以多表示一个负数

【例6.12】 已知 [ y ] 补 [y]_{补} [y],求 [ − y ] 补 [-y]_{补} [y]
解: [ y ] 补 [y]_{补} [y] 连同符号位在内,每位取反,末位加1,即为 [ − y ] 补 [-y]_{补} [y]。这是一个非常重要的规律。

6.2 数的定点表示和浮点表示

6.2.1 定点表示

图6-9 定点表示的格式

  “定点表示”也就是小数点位置固定,要么在第一位后表示“绝对值小于1的小数”,要么在最后一个表示“整数”。上一节已经详细的介绍了。于是在定点机中可以分为如下两种。其中“小数定点机”精度为 2 − n 2^{-n} 2n、“整数定点机”的精度为 1 1 1下表给出了取值范围:

表6-1 定点表示的取值范围

但“定点表示”有很多问题,于是便有了下一小节的“浮点表示”:

  • 编程困难,程序员要调节小数点的位置。
  • 数的表示范围小,为了能表示两个大小相差很大的数据,需要很长的机器字长。比如太阳的质量是 0.2 × 1 0 34 0.2\times 10^{34} 0.2×1034 克,一个电子的质量大约为 0.9 × 1 0 − 27 0.9\times 10^{-27} 0.9×1027 克,两者数量级相差 1 0 61 10^{61} 1061,使用定点表示则相差203位。
  • 数据存储单元的利用率往往很低。

6.2.2 浮点表示

下面是本小节关心的问题:

  • 为什么在计算机中要引入浮点数表示?——定点表示不够用
  • 浮点表示的格式是什么?
  • 尾数和阶码的基值必须是2吗?基值的影响?——不一定,但影响表示精度
  • 表数范围与精度和哪些因素有关?
  • 为什么要引入规格化表示?
  • 目前浮点数表示格式的标准是什么?——IEEE 754

  “浮点表示”的基本思想就是使用 二进制的“科学记数法”,比如 N = 11.0101 = 0.110101 × 2 [ 10 ] 二进制 N=11.0101=0.110101\times 2^{[10]_{二进制}} N=11.0101=0.110101×2[10]二进制,注意幂次也是二进制数(规格化数)。由于幂次的阶码本身也是二进制表示,所以幂次的范围很大,这样我们便可以使用有限字长表示数量级相差很大的数字。下面给出浮点数的规格化形式

图6-10 浮点表示的规格化格式
  • j j j:阶码,是一个有符号整数,控制尾数的左右移动。 j f j_f jf 是符号位、其余是数值部分(长度为 m m m)。
  • S S S:尾数,是绝对值小于1的小数、要求尾数规格化 S f S_f Sf 是符号位、其余为数值部分(长度为 n n n)。
  • r r r:尾数的基值,计算机中通常取 2、4、8、16等。基数 r r r 越大,可表示的浮点数的范围越大,但浮点数的精度降低,因为一次移动的位数增加。基数不同,浮点数的规格化形式不同,如下。
  • r = 2 r=2 r=2,“原码规格化”原则是尾数最高位为1;“补码规格化”原则是尾数的符号位和第一数位不同。
  • r = 4 r=4 r=4,“原码规格化”原则尾数最高2位不全为0。
  • r = 8 r=8 r=8,“原码规格化”原则尾数最高3位不全为0。

注:规格化是为了尽可能保证数据精度,防止存储很多无效0。

  浮点数本质上是用用有限的数据表示无限多的实数。显然浮点数的表示范围和 阶码 j j j、尾数 S S S 的取值范围有关。阶码长度影响范围,尾数长度影响精度。如下图,可以看到 m = 4 m=4 m=4 n = 10 n=10 n=10 的浮点数(16位),表示范围为 ± [ 2 − 25 ∼ 2 15 ) \pm[2^{-25}\sim2^{15}) ±[225215)、精度为 2 − 10 2^{-10} 210(十进制):

图6-11 浮点数的表示范围
  • 上溢:阶码>最大阶码,按“计算出错”处理。
  • 下溢:尾数为0、或者阶码<最小阶码,按“机器零”处理。机器零的两种情况:
  1. 浮点数尾数=0时。
  2. 浮点数阶码≤能表示的最小数时。若阶码采用“补码”,最小值是只有最高位为1;若阶码采用“移码”,最小值是阶码全是0。

注:上述机器零的规定有利于机器中“判0”电路的实现。

下面是几个浮点数范围的练习:

【练习】设机器数字长为24位,欲表示±3万的十进制数,试问在保证数的最大精度的前提下,除阶符、数符各取1位外,阶码、尾数各取几位?
解:由 2 14 < 30000 < 2 15 2^{14}<30000<2^{15 } 214<30000<215,阶码取值范围应大于15,于是阶码长度最小为 4 + 1 = 5 4+1=5 4+1=5 位。剩下的19位就是尾数长度。

【例6.13】将 + 19 128 +\frac{19}{128} +12819 写成二进制定点数、浮点数及在定点机和浮点机中的机器数形式。其中数值部分均取10位,数符取1位,浮点数阶码取5位(含1位阶符),尾数规格化。
解:二进制定点数: x = + 19 128 = 10011 × 2 − [ 7 ] 十进制 = 0.00100 11000 x=+\frac{19}{128}=10011\times2^{-[7]_{十进制}}=0.00100\;11\bold{000} x=+12819=10011×2[7]十进制=0.0010011000
  浮点数的规格化形式 x = 0.10011 00000 × 2 − [ 10 ] 二进制 x=0.10011\;00000\times 2^{-[10]_{二进制}} x=0.1001100000×2[10]二进制
  定点机: [ x ] 原 = [ x ] 反 = [ x ] 补 = 0.00100 11000 [x]_{原}=[x]_{反}=[x]_{补}=0.00100\;11000 [x]=[x]=[x]=0.0010011000
  浮点机(原码):阶码为 j = 1 , 0010 j=1,0010 j=1,0010、尾数为 0.10011 00000 0.10011\;00000 0.1001100000
  浮点机(反码):阶码为 j = 1 , 1101 j=1,1101 j=1,1101、尾数为 0.10011 00000 0.10011\;00000 0.1001100000
  浮点机(补码):阶码为 j = 1 , 1110 j=1,1110 j=1,1110、尾数为 0.10011 00000 0.10011\;00000 0.1001100000

【例6.14】将 − 58 -58 58 表示成二进制定点数和浮点数,并写出它在定点机和浮点机中的三种机器数及阶码为移码、尾数为补码的形式(其他要求同上例)。
解:二进制定点数: x = − 111010 = − 00001 11010 x=-111010=-\bold{0000}1\;11010 x=111010=0000111010
  浮点数的规格化形式 x = − 0.11101 00000 × 2 + [ 110 ] 二进制 x=-0.11101\;00000\times 2^{+[110]_{二进制}} x=0.1110100000×2+[110]二进制
  定点机(原码): [ x ] 原 = 1 , 00001 11010 [x]_{原}=1,00001\;11010 [x]=1,0000111010
  定点机(反码): [ x ] 反 = 1 , 11110 00101 [x]_{反}=1,11110\;00101 [x]=1,1111000101
  定点机(补码): [ x ] 补 = 1 , 11110 00110 [x]_{补}=1,11110\;00110 [x]=1,1111000110
  浮点机(原码):阶码为 j = 0 , 0110 j=0,0110 j=0,0110、尾数为 1.11101 00000 1.11101\;00000 1.1110100000
  浮点机(反码):阶码为 j = 0 , 0110 j=0,0110 j=0,0110、尾数为 1.00010 11111 1.00010\;11111 1.0001011111
  浮点机(补码):阶码为 j = 0 , 0110 j=0,0110 j=0,0110、尾数为 1.00011 00000 1.00011\;00000 1.0001100000
  浮点机(要求):阶码为 j = 1 , 0110 j=1,0110 j=1,0110、尾数为 1.00011 00000 1.00011\;00000 1.0001100000

【习题6.16】设机器数字长为16位,写出下列各种情况下它能表示的数的范围。设机器数采用1位符号位,答案均用十进制数表示。
(1) 无符号数。—— 0 ∼ 65535 0\sim 65535 065535
(2) 原码表示的定点小数。—— − ( 1 − 2 − 15 ) ∼ 1 − 2 − 15 -(1-2^{-15})\sim1-2^{-15} (1215)1215
(3) 补码表示的定点小数。—— − 1 ∼ 1 − 2 − 15 -1\sim1-2^{-15} 11215
(4) 补码表示的定点整数。—— − 32768 ∼ 32767 -32768\sim32767 3276832767
(5) 原码表示的定点整数。—— − 32767 ∼ 32767 -32767\sim32767 3276732767
(6) 浮点数的格式为:阶码6位(含1位阶符),尾数10位(含1位数符)。分别写出正数和负数的表示范围。(假设阶码和尾数都是原码、且不用规格化)
  原码非规格化:正数 2 − 9 × 2 − 31 ∼ ( 1 − 2 − 9 ) × 2 31 2^{-9}\times2^{-31}\;\sim\;(1-2^{-9})\times 2^{31} 29×231(129)×231;负数 − ( 1 − 2 − 9 ) × 2 31 ∼ − 2 − 9 × 2 − 31 -(1-2^{-9})\times 2^{31}\;\sim\;-2^{-9}\times2^{-31} (129)×23129×231
(7) 浮点数格式同(6),机器数采用补码规格化形式,分别写出其对应的正数和负数的真值范围。
  补码规格化要求尾数的符号位和第一数位不同,于是其正数最小值为 2 − 1 2^{-1} 21,负数最大值为 − ( 2 − 1 + 2 − 9 ) -(2^{-1}+2^{-9}) (21+29)
  采用 补码规格化:正数 2 − 1 × 2 − 32 ∼ ( 1 − 2 − 9 ) × 2 31 2^{-1}\times2^{-32}\;\sim\;(1-2^{-9})\times 2^{31} 21×232(129)×231;负数 − 1 × 2 31 ∼ − ( 2 − 1 + 2 − 9 ) × 2 − 32 -1\times 2^{31}\;\sim\;-(2^{-1}+2^{-9})\times2^{-32} 1×231(21+29)×232
  若 补码非规格化:正数 2 − 9 × 2 − 32 ∼ ( 1 − 2 − 9 ) × 2 31 2^{-9}\times2^{-32}\;\sim\;(1-2^{-9})\times 2^{31} 29×232(129)×231;负数 − 1 × 2 31 ∼ − 2 − 9 × 2 − 32 -1\times 2^{31}\;\sim\;-2^{-9}\times2^{-32} 1×23129×232

6.2.3 ΔIEEE 754标准

图6-12 浮点数标准格式—IEEE 754

  IEEE 754中规定了浮点数的格式,如上图。因为规定基值 r = 2 r=2 r=2,所以尾数规格化后,尾数的第一位 S 1 S_1 S1 为定值——原码是1、补码则和符号位相反。于是便可以将这一位省略,称为“隐藏位”,进一步扩大了浮点数的表示范围。下面给出了 IEEE 754 的长度规定:

表6-2 IEEE 754标准规定的三种常用浮点数
三种浮点数符号位阶码尾数总位数
短实数 (C语言float)182332
长实数 (C语言double)1115264
临时实数1156480

以上表中“短实数”为例,计算“原码”的取值范围:

  • 未规格化:。???
  • 规格化(短实数):正数 2 − 1 × 2 − 127 ∼ ( 1 − 2 − 24 ) × 2 127 2^{-1}\times2^{-127}\sim (1-2^{-24})\times2^{127} 21×2127(1224)×2127、负数 − ( 1 − 2 − 24 ) × 2 127 ∼ − 2 − 1 × 2 − 127 -(1-2^{-24})\times2^{127}\sim -2^{-1}\times2^{-127} (1224)×212721×2127

可以看到,规格化可以使尾数最高位被省略,于是提升了“浮点数”的精度。

参考视频:“王道-计算机组成原理-2.3.2 IEEE 754”???等待完善内容
??????????????????????????
临时实数没有隐藏位
移码的表示
??????????????????????????

6.3 定点运算

6.3.1 移位运算

1、移位的运算规则

  从数学意义上说,“移位”是改变小数点的位置。但是在机器用语中,“移位”则是小数点不动,移动数值部分。若使用二进制存储,移位就表示按2的倍数进行扩大、缩小。“移位”与“加减”配合,能够实现乘除运算。移位分为“算术移位”和“逻辑移位”,下面是给出移位规则:

图6-13 算术移位规则、逻辑移位规则
  • 算术移位:有符号数的移位。
  • 逻辑移位:无符号数的移位。

上述“补码”的移位规则,本质上是建立在原码的移位规则上,负数“左移填0”是因为“原码”最后的“10000”在“补码”中不会改变;负数“右移填1”是因为补码的高位都是“原码”取反。下面是一些练习:

【例6.16】设机器数字长为8位(含1位符号位),写出 A = + 26 A=+26 A=+26 时,三种机器数左、右移一位和两位后的表示形式及对应的真值,并分析结果的正确性。
解: A = − 11010 A=-11010 A=11010,得 [ A ] 原 = [ A ] 补 = [ A ] 反 = 0 , 001 1010 [A]_{原}=[A]_{补}=[A]_{反}=0,001\;1010 [A]=[A]=[A]=0,0011010,于是

【例6.17】设机器数字长为8位(含1位符号位),写出 A = − 26 A=-26 A=26 时,三种机器数左、右移一位和两位后的表示形式及对应的真值,并分析结果的正确性。
解: A = − 11010 A=-11010 A=11010,得 [ A ] 原 = 1 , 001 1010 [A]_{原}=1,001\;1010 [A]=1,0011010 [ A ] 反 = 1 , 110 0101 [A]_{反}=1,110\;0101 [A]=1,1100101 [ A ] 补 = 1 , 110 0110 [A]_{补}=1,110\;0110 [A]=1,1100110,于是

注:上述两题可以看出,只要没有溢出,计算就非常准确。

2. 移位的硬件实现

  当移位移出了1时,就会发生“溢出”。高位溢出称为“出错”,是因为移位后会和正确结果差距很大。低位溢出称为“影响精度”,这是因为移位后和正确结果的偏差不会超过最小精度。和上述移位规则相对应,下面给出了移位的硬件实现。可以看到,如果移位的添补代码是0,那就直接传入;若填补代码是1,还可以利用符号位。如下图:

图6-14 算术移位的硬件实现、逻辑移位的硬件实现
  • 左侧方框:符号位所在寄存器。
  • 蓝色箭头所在方框:数值部分所在寄存器。

注:为了避免“逻辑左移”将最高位移丢,上右图使用了“带进位的移位”。

6.3.2 加减法运算-补码

1. 补码加减法运算的公式

  进行加法运算时,若采用“原码”,那么正数和负数的加法实际上还是减法,而“补码”就是与负数等价的正数。如下给出计算公式,注意相加时连同符号位一起相加,最后舍弃最高的进位即可:

图6-15 补码加减法运算的公式

注:【例6.12】中提到过“ [ y ] 补 [y]_{补} [y] 连同符号位在内,每位取反,末位加1,即为 [ − y ] 补 [-y]_{补} [y]”。

下面给出几个例子:

【例6.18】设 A = 0.1011 A=0.1011 A=0.1011 B = − 0.0101 B=-0.0101 B=0.0101,求 [ A + B ] 补 [A+B]_{补} [A+B]
解: [ A ] 补 + [ B ] 补 = 0.1011 + 1.1011 = 10.0110 [A]_{补}+[B]_{补}=0.1011+1.1011=10.0110 [A]+[B]=0.1011+1.1011=10.0110,于是舍弃符号位进位即得 [ A + B ] 补 = 0.0110 [A+B]_{补}=0.0110 [A+B]=0.0110

【例6.19】设 A = − 9 A=-9 A=9 B = − 5 B=-5 B=5,求 [ A + B ] 补 [A+B]_{补} [A+B]?(假设数值部分是4位)
解: [ A ] 补 + [ B ] 补 = [ 1 , 1001 ] 补 + [ 1 , 0101 ] 补 = 1 , 0111 + 1 , 1011 = 11 , 0010 [A]_{补}+[B]_{补}=[1,1001]_{补}+[1,0101]_{补}=1,0111+1,1011=11,0010 [A]+[B]=[1,1001]+[1,0101]=1,0111+1,1011=11,0010,于是舍弃符号位进位即得 [ A + B ] 补 = 1 , 0010 [A+B]_{补}=1,0010 [A+B]=1,0010

【例6.20】设机器数字长为8位(含1位符号位),且 A = 15 A=15 A=15 B = 24 B=24 B=24,用补码求 A − B A-B AB
解: [ A ] 补 + [ − B ] 补 = 0 , 000 1111 + [ 1 , 001 1000 ] 补 = 0 , 000 1111 + 1 , 110 1000 = 1 , 111 0111 = [ A − B ] 补 [A]_{补}+[-B]_{补}=0,000\;1111+[1,001\;1000]_{补}=0,000\;1111+1,110\;1000=1,111\;0111=[A-B]_{补} [A]+[B]=0,0001111+[1,0011000]=0,0001111+1,1101000=1,1110111=[AB],于是 A − B = 1 , 000 1001 = [ − 9 ] 十进制 A-B=1,000\;1001=[-9]_{十进制} AB=1,0001001=[9]十进制

【练习1】设机器数字长为5位(含1位符号位),且 x = 9 16 x=\frac{9}{16} x=169 y = 11 16 y=\frac{11}{16} y=1611,用补码求 x + y x+y x+y
解: [ A ] 补 + [ B ] 补 = 0.1001 + 0.1011 = 1.0100 [A]_{补}+[B]_{补}=0.1001+0.1011=1.0100 [A]+[B]=0.1001+0.1011=1.0100,于是得 x + y = 1.1100 = [ − 0.75 ] 十进制 x+y=1.1100=[-0.75]_{十进制} x+y=1.1100=[0.75]十进制。计算错误!

【练习2】设机器数字长为8位(含1位符号位),且 A = − 97 A=-97 A=97 B = + 41 B=+41 B=+41,用补码求 A − B A-B AB
解: [ A ] 补 + [ − B ] 补 = [ 1 , 110 0001 ] 补 + [ 1 , 010 1001 ] 补 = 1 , 001 1111 + 1 , 101 0111 = 10 , 111 0110 [A]_{补}+[-B]_{补}=[1,110\;0001]_{补}+[1,010\;1001]_{补}=1,001\;1111+1,101\;0111=10,111\;0110 [A]+[B]=[1,1100001]+[1,0101001]=1,0011111+1,1010111=10,1110110,于是舍弃符号位进位即得 [ A + B ] 补 = 0 , 111 0110 [A+B]_{补}=0,111\;0110 [A+B]=0,1110110,也就是 A − B = + 118 A-B=+118 AB=+118。计算错误!

注:实际中数值部分字长不是无限的,一定要注意机器数字长,机器数字长不够会导致溢出

2. 溢出的判断

  上面提到补码相加时,需要连通管符号位一起相加,最后舍弃最高的进位。那么如何判断补码溢出呢?如下:

  1. 使用一位符号位判判断:两个操作数一正一负必不可能溢出;但若两个操作数符号相同,其结果的符号与原操作数的符号不同,即为溢出。缺点是需要记录两个进位,然后进行异或。
  • 硬件实现(异或):最高有效位的进位 ⊕ \oplus 符号位的进位 = 1,溢出。
  • 关键点:“最高有效位的进位”会影响“符号位的进位”。
  1. 使用两位符号位判溢出:使用两个符号位,新增符号位与原符号位相同。进行加/减运算后,若结果的双符号位相同,未溢出;若结果的双符号位不同,溢出最高符号位代表其真正的符号
  2. 进位判断法:在进行补码加减运算时,可以记录下进位和借位的情况。如果最高位的进位和次高位的进位不同,则表示发生了溢出。

3. 补码加减法的硬件配置

根据上述原理很容易实现补码加减法的硬件配置,如下图:

图?补码加减法的硬件配置
  • 加法器:核心部件,完成补码的加减法运算。
  • A \text{A} A:也就是 ACC \text{ACC} ACC,保存被加数。
  • X \text{X} X:保存加数。
  • G A \text{G}_{\text{A}} GA G S \text{G}_{\text{S}} GS:加减法标记位。 G A = 1 \text{G}_{\text{A}}=1 GA=1 表示做加法, G S = 1 \text{G}_{\text{S}}=1 GS=1做减法。
  • 求补控制逻辑:减法时,控制 X \text{X} X 求解所保存加数的补码,也就是“取反、+1”。

6.3.3 Δ乘法运算-原码

1. 笔算乘法的分析和改进

  乘法运算可用“加”和“移位”实现。如下左图,给出了手写的二进制乘法计算过程,可以看到其本质上就是不断的“移位+相加”。但向左移动乘数不符合硬件的逻辑,于是进行改进。最重要的改进就是将遍历过程改为,由乘数的末位决定被乘数是否与原部分积相加,然后右移1位形成新的部分积,同时乘数右移1位(末位移丢),空出高位存放部分积的低位。可以看到乘法计算的中间结果不断占用乘数的空间,如下右图所示:

笔算乘法改进


硬件改进
符号位单独处理异或电路
乘数的某一位决定是否加被乘数将乘数放到移位寄存器当中
4个位积一起相加多次累加
乘积的位数扩大一倍两个寄存器
图?根据笔算乘法改进成实际的“原码乘法”

重要的改进内容:

  1. 不断的右移、求和。被乘数只与部分积的高位相加。
  2. 在保留乘法的中间值的同时,顺便蹭一下乘数的空间。
  3. 符号位单独使用异或电路计算。

2. 原码乘法—一位乘

  上述改进的笔算乘法就是“原码一位乘算法”。原码乘法的特点:

  1. 乘积的符号位单独处理,数值部分为绝对值相乘。
  2. 用移位的次数判断乘法是否结束。因为有可能不做加法。

注:移位操作均为“逻辑移位”。

【例6.21】已知 x = − 0.1110 x=-0.1110 x=0.1110 y = 0.1101 y=0.1101 y=0.1101,求 [ x ⋅ y ] 原 [x\cdot y]_{原} [xy]
解:写出原码后,符号位直接异或,数值部分如右

3. 原码乘法的硬件配置—一位乘

图?原码一位乘的硬件配置
  • A \text{A} A:n+1寄存器,也就是 ACC \text{ACC} ACC,保存累加和高位(不断移位)。最高位不是符号位,而是保存低位部分相加后的进位。
  • Q \text{Q} Q:n+1寄存器,乘商寄存器。计算刚开始时保存乘数,计算过程不断右移,计算结束后就是乘积的低位。
  • X \text{X} X:n+1寄存器,保存被乘数(无需移位)。
  • 加法器:n+1位加法器
  • 移位和加控制:由乘数的最低位控制。“控制门”可以送0给加法器。
  • 计数器 C \text{C} C:记录移位的次数,判断乘法是否结束。一般是从n递减。
  • S \text{S} S:符号位,将两个操作数的符号位异或得到。
  • G M \text{G}_\text{M} GM:乘法的标志位。

核心部件:三个n+1位寄存器 A \text{A} A Q \text{Q} Q、$\text{X}、一个n+1位全加器。

3. 原码乘法—两位乘

待补充。。。。。。。。

6.3.4 Δ乘法运算-补码

1. 补码乘法—一位乘

(1)补码一位乘运算规则
以小数为例
1.被乘数任意,乘数为正。
与原码乘相似,但加和移位按补码规则运算。乘积的符号自然形成
②被乘数任意,乘数为负
乘数[y]补,去掉符号位,操作同①
最后加[-x]补,校正

2. 补码乘法的硬件配置—一位乘

3. 补码乘法—两位乘

4.乘法小结

  • 整数乘法与小数乘法过程完全相同,可用逗号代替小数点。
  • 原码乘符号位单独处理;补码乘符号位自然形成。
  • 原码乘去掉符号位运算,即为无符号数乘法。
  • 不同的乘法运算需有不同的硬件支持。

本小节参考视频:“王道-计算机组成原理-2.2.6.2 补码的乘法运算”???等待完善内容
??????????????????????????

6.3.5 除法运算-原码

约定

  1. “小数定点机”除法中,被除数小于除数,这样的到的商还是小数。否则溢出。
  2. “整数定点机”除法中,被除数大于除数,这样的到的商就是整数。否则溢出。
  3. 被除数不为0、除数不为0,可以提前通过判断电路规避。

注:上述前两种“溢出”的情况可以见下一节“6.4节-浮点四则运算”。

1. 笔算除法的改进

  二进制除法实际上比十进制除法简单,因为二进制商的每一位只有0/1。如下左图所示,给出了笔算除法的过程。我们已经约定好“被除数小于除数”,于是笔算乘法本质上也是不断地比较被除数和当前余数的大小。商的符号位单独处理、数值部分为绝对值相除。按照硬件逻辑进行改进后,和“原码乘法”相反,“原码除法”是从低位计算到高位。如下:

笔算除法改进


硬件改进
商符单独处理符号位异或电路
心算上商
|x|-|y|>0上商1、|x|-|y|<0上商0
加法电路给出上商
余数不动低位补“0”,减右移一位的除数余数左移一位低位补“0”,减除数
2倍字长加法器1倍字长加法器
上商位置不固定在寄存器最末位上商,然后左移
图?根据笔算除法进行改进-小数定点除法

重要的改进内容:

  1. 不断的左移、求和。每次都与“负的除数绝对值的补码”低位相加。
  2. 不断缩小余数的中间值的空间,最终只剩下商。
  3. 符号位单独使用异或电路计算。

2. 原码除法:恢复余数法

在第 i i i 步:

  1. 上商:若余数 R i > 0 R_i>0 Ri>0,上商1;若余数 R i < 0 R_i<0 Ri<0,上商0。
  2. 恢复余数:若上商1,则跳转到下一步;若上商0,恢复余数 R i + y ∗ R_i+y^* Ri+y
  3. 逻辑移位:将余数逻辑左移1位。
  4. 准备下一次运算:再将现在的余数减去 y ∗ y^* y,得到下一次余数 R i + 1 R_{i+1} Ri+1

特点:若数值部分为n位,则上商n+1次,其中第一次上商判溢出。移位n次。加n+1~2n+1次。用移位的次数判断除法是否结束。

【例6.24】假设机器字长5位(符号位1位),给出 x = − 0.1011 x=-0.1011 x=0.1011 y = − 0.1101 y=-0.1101 y=0.1101,在小数定点机中求 [ x y ] 原 [\frac{x}{y}]_{原} [yx]
解: [ x ] 原 = 1.1011 [x]_{原}=1.1011 [x]=1.1011 [ y ] 原 = 1.1101 [y]_{原}=1.1101 [y]=1.1101 [ y ∗ ] 补 = 0.1101 [y^*]_{补}= 0.1101 [y]=0.1101 [ − y ∗ ] 补 = 1.0011 [-y^*]_{补}= 1.0011 [y]=1.0011。然后如下:

  • 每一步:首先判断上商、若上商0则进行“加法”恢复余数、然后余数“逻辑左移”、最后进行“加法”用于下一次判断。
  • 上图中未展示“第一次上商”,其作用是判断是否溢出。不符合本节开始提到的“约定”。

3. 原码除法:加减交替法

  “加减交替法”是对“恢复余数法”的改进,将每一步中的两次加法合并,直接节省掉“恢复余数法”中“恢复余数”的过程。如下:

在第 i i i 步:

  • 若为第一步直接 + y ∗ +y^* +y
  • 否则,若余数 R i > 0 R_i>0 Ri>0,则上商1,计算新的余数 R i + 1 = 2 R i − y ∗ R_{i+1}=2R_i-y^* Ri+1=2Riy
  • 否则,若余数 R i < 0 R_i<0 Ri<0,则上商0,计算新的余数 R i + 1 = 2 ( R i + y ∗ ) − y ∗ = 2 R i + y ∗ R_{i+1}=2(R_i+y^*)-y^*=2R_i+y^* Ri+1=2(Ri+y)y=2Ri+y
  • 如果最后一步且上商为0,则最后加法计算的结果不是对应的余数,还需要再 + y ∗ +y^* +y 恢复余数。

特点:若数值部分为n位,则上商n+1次,第一次上商判溢出。移位n次。加(n+1)/(n+2)次。用移位的次数判断除法是否结束。

【例6.25】假设机器字长5位(符号位1位),给出 x = − 0.1011 x=-0.1011 x=0.1011 y = − 0.1101 y=-0.1101 y=0.1101,在小数定点机中求 [ x y ] 原 [\frac{x}{y}]_{原} [yx]
解: [ x ] 原 = 1.1011 [x]_{原}=1.1011 [x]=1.1011 [ y ] 原 = 1.1101 [y]_{原}=1.1101 [y]=1.1101 [ x ∗ ] 补 = 0.1011 [x^*]_{补}= 0.1011 [x]=0.1011 [ y ∗ ] 补 = 0.1101 [y^*]_{补}= 0.1101 [y]=0.1101 [ − y ∗ ] 补 = 1.0011 [-y^*]_{补}= 1.0011 [y]=1.0011。然后如下:

4. 加减交替法的硬件配置

图?原码加减交替除法的硬件配置
  • A \text{A} A:n+1寄存器,也就是 ACC \text{ACC} ACC。一开始保存被除数,计算过程不断左移,最后就是余数。最高位不是符号位,而是保存高位部分相加后的进位。
  • Q \text{Q} Q:n+1寄存器,乘商寄存器。计算刚开始时保存0,计算过程不断右移,计算结束后就是商。
  • X \text{X} X:n+1寄存器,保存除数(无需移位)。
  • 加法器:n+1位加法器
  • 移位和加控制逻辑:最低位控制加减交替。“控制门”可以送 + y ∗ +y^* +y − y ∗ -y^* y 给加法器。
  • 计数器 C \text{C} C:记录移位的次数,判断除法是否结束。
  • S \text{S} S:符号位,将两个操作数的符号位异或得到。
  • G D \text{G}_\text{D} GD:除法的标志位。
  • V \text{V} V:表示是否溢出。

6.3.6 Δ除法运算-补码

补码除法也分恢复余数法和加减交替法,后者用得较多,在此只讨论加减交替法。

参考视频:“王道-计算机组成原理-2.2.7.2 补码的除法运算”???等待完善内容
??????????????????????????

6.4 浮点四则运算

6.4.1 浮点数的加减运算

1. 浮点数加减运算的基本步骤

  假设浮点数基数为2,并且使用“补码”计算,下面直接直接给出“浮点加减运算”的基本步骤:

  1. 对阶:首先用补码求阶差 [ Δ j ] 补 = [ j x ] 补 − [ j y ] 补 [\Delta_j]_{补}=[j_x]_{补}-[j_y]_{补} [Δj]=[jx][jy],然后“小阶向大阶看齐”。小阶所在的浮点数阶码增加、尾数算数右移。注意“右移”只是可能影响数据精度,而“左移”可能会出现特别大的错误。
  2. 尾数求和:补码定点求和,注意要重复一位符号位
  3. 尾数规格化:非规格化时,检查尾数的两个符号位,若为 10 / 01 10/01 10/01 则“右规”;否则就“左规”。每次移位都是算术移位,同时需要调整阶码。尾数溢出则“右规”。
  • 原码规格化原则是第一数位为1。
  • 补码规格化原则是符号位和第一数位不同。

注:若计算结果溢出(参考“6.2.2 浮点表示”),下溢全部按照机器零处理。上溢会进入“出错处理”。

2. 舍入方法和溢出判断

  需要注意的是,上述“对阶”和“规格化”过程中,只要进行尾数右移时,丢失有效数字就会引起误差,于是便有下面的舍入方法

  1. 截断法:直接移出。后续没有任何操作。上述“计算步骤”中的默认方法。
  2. 0舍1入法:移出的是1,移动后,就在最末尾加1。可能会使尾数再次溢出。类似于“四舍五入”。
  3. 恒置“1”法:只要右移,就强制使末位为1。

计算完成之后再判断是否溢出。“溢出判断”较为简单,只要计算结果超出范围就是溢出。“上溢”需要进入“出错处理”,“下溢”则按照“机器零”处理:

  1. 阶码判断法:阶码为0,判断为下溢,按照“机器零”处理。若阶码采用补码,且为补码的最小负数(符号位为1、其余位都是0),判定为上溢,进入“出错处理”。
  2. 尾数判断法:尾数为0,就判定为下溢,按照“机器零”处理。

最后给出两个例题,理解浮点数的加减运算过程:

【例6.27】 x = 0.1101 × 2 10 x= 0.1101\times 2^{10} x=0.1101×210 y = 0.1011 × 2 01 y= 0.1011\times 2^{01} y=0.1011×201,求 x + y x+y x+y?(除阶符、数符外,阶码取3位,尾数取6位)
解: [ x ] 补 = 00 , 010 ; 00.110100 [x]_{补}=00,010;\;00.110100 [x]=00,010;00.110100 [ y ] 补 = 00 , 001 ; 00.101100 [y]_{补}=00,001;\;00.101100 [y]=00,001;00.101100

  1. 对阶:阶差为1,则 y y y 阶码+1、尾数算数右移1位, [ y ] 补 ′ = 00 , 010 ; 00.010110 [y]_{补'}=00,010;\;00.010110 [y]=00,010;00.010110。(没有误差)
  2. 尾数求和: [ S x ] 补 + [ S y ] 补 ′ = 00.110100 + 00.010110 = 01.001010 [S_x]_{补}+[S_y]_{补'}=00.110100+00.010110=01.001010 [Sx]+[Sy]=00.110100+00.010110=01.001010
  3. 尾数规格化:补码规格化,尾数溢出则“右规”1位、阶码+1,得结果 [ x + y ] 补 = 00 , 011 ; 00.100101 [x+y]_{补}=00,011;\;00.100101 [x+y]=00,011;00.100101,于是 x + y = 00 , 011 00.100101 = + 37 64 × 2 3 x+y=00,011\;00.100101=+\frac{37}{64}\times 2^{3} x+y=00,01100.100101=+6437×23。(准确结果)

【例6.28】 x = − 5 8 × 2 − 5 x= -\frac{5}{8}\times 2^{-5} x=85×25 y = 7 8 × 2 − 4 y= \frac{7}{8}\times 2^{-4} y=87×24,求 x − y x-y xy?(除阶符、数符外,阶码取3位,尾数取6位)
解: [ x ] 补 = [ 1 , 101 ; 1.101000 ] 补 = 11 , 011 ; 11.011000 [x]_{补}=[1,101;\;1.101000]_{补}=11,011;\;11.011000 [x]=[1,101;1.101000]=11,011;11.011000 [ y ] 补 = [ 1 , 100 ; 0.111000 ] 补 = 11 , 100 ; 00.111000 [y]_{补}=[1,100;\;0.111000]_{补}=11,100;\;00.111000 [y]=[1,100;0.111000]=11,100;00.111000

  1. 对阶:阶差为-1,则 x x x 阶码+1、尾数算数右移1位, [ x ] 补 ′ = 11 , 100 ; 11.101100 [x]_{补'}=11,100;\;11.101100 [x]=11,100;11.101100。(没有误差)
  2. 尾数求和: [ S x ] 补 ′ + [ − S y ] 补 = 11.101100 + 11.001000 = 110.110100 [S_x]_{补'}+[-S_y]_{补}=11.101100+11.001000=110.110100 [Sx]+[Sy]=11.101100+11.001000=110.110100,舍弃符号位进位得 10.110100 10.110100 10.110100
  3. 尾数规格化:补码规格化,尾数溢出则“右规”1位、阶码+1,得结果 [ x − y ] 补 = 11 , 101 ; 11.011010 [x-y]_{补}=11,101;\;11.011010 [xy]=11,101;11.011010,于是 x − y = 11 , 011 ; 11.100110 = − 19 32 × 2 − 3 x-y=11,011;\;11.100110=-\frac{19}{32}\times 2^{-3} xy=11,011;11.100110=3219×23。(准确结果)

6.4.2 Δ浮点数的乘除运算

待补充。。。。。
符号阶码和尾数分开按类似于定点的运算然后合并,感觉浮点数乘除要比加减简单。

6.4.3 Δ浮点运算的硬件配置

待补充。。。。。。。

浮点运算器主要由两个定点运算部件组成,一个是阶码运算部件,另一个是尾数运算部件。

6.5 算术逻辑单元

6.5.1 ALU电路

  前面已经介绍了定点运算、浮点运算、算术运算、逻辑运算的硬件电路,实际上这些运算都被集成到一个集成电路芯片中,也就是ALU(Arithmetic and Logic Unit,算逻运算单元)。ALU是组合逻辑电路,若需要保存结果,还需要额外添加寄存器。ALU再和“控制器”集成在一起,就构成了计算机系统的CPU。如下左图是ALU电路的表示符号,其中 k i k_i ki 控制ALU进行“算术运算”还是“逻辑运算”:

图?ALU电路符号、74181外特性

但ALU只能实现“1位”的算逻运算,要完成“多位”的算逻运算还要将几个ALU集成在一起,如上右图74181中就集成了4个ALU,可以完成4位的算逻运算。下面给出74181的功能表:

表6-3 74181 ALU的算数/逻辑运算功能表

6.5.2 快速进位链

  那上述74181内部是如何连接多个ALU的呢?本节以“加法器”为例,介绍算术运算、逻辑运算的电路优化问题。根据“数字电子技术基础”的执行,要实现n位加法运算,可以使用n+1个“全加器”构成的一个“并行加法器”。之所以称之为“并行”,是因为两个n+1的数,可以利用该加法器以并行的方式完成加法运算。如下图所示,每个 FA i \text{FA}_i FAi 都是一个全加器:

图?并行加法器示意图
  • 和的计算: S i = A ‾ i B ‾ i C i − 1 + A ‾ i B i C ‾ i − 1 + A i B ‾ i C ‾ i − 1 + A i B i C i − 1 S_i=\overline{A}_i\overline{B}_iC_{i-1}+\overline{A}_iB_i\overline{C}_{i-1}+A_i\overline{B}_i\overline{C}_{i-1}+A_iB_iC_{i-1} Si=AiBiCi1+AiBiCi1+AiBiCi1+AiBiCi1
  • 进位的计算: C i = A ‾ i B i C i − 1 + A i B ‾ i C i − 1 + A i B i C ‾ i − 1 + A i B i C i − 1 = A i B i + ( A i + B i ) C i − 1 C_i=\overline{A}_iB_iC_{i-1}+A_i\overline{B}_iC_{i-1}+A_iB_i\overline{C}_{i-1}+A_iB_iC_{i-1}=A_iB_i+(A_i+B_i)C_{i-1} Ci=AiBiCi1+AiBiCi1+AiBiCi1+AiBiCi1=AiBi+(Ai+Bi)Ci1

但显然,依照上图的连接方式,每个“全加器”都需要等待上一级“进位”输入,才能输出本级的计算结果。每一级全加器的进位前后连接,形成“进位链”。于是,并行加法器的运算瓶颈在于“进位链”

并行进位链
拆分成多个小组
小组内并行、小组间串行
拆分成若干大组、若干小组
组内并行、组件串行
进位计算暴力展开
双重分组跳跃进位链
32位加法需要10ty
单重分组跳跃进位链
32位加法需要20ty
普通的并行进位链
串行进位链
32位加法需要64ty
图?进位链的改进思路

上图给出进位的链的改进思路及指标,下面来依次介绍。假设级延迟时间“与非门/或门” t y t_y ty、“与或非门” 1.5 t y 1.5t_y 1.5ty

1. 串行进位链

  前面所示的“并行加法器”结构实际上就是采用了“串行进位链”,进位逐级产生。我们可以将进位的计算专门抽出来,给出如下的进位递推公式

C i = A i B i + ( A i + B i ) C i − 1 = 令 t i = A i + B i 令 d i = A i B i d i + t i C i − 1 = 德 ⋅ 摩根定律 d i ‾ ⋅ t i C i − 1 ‾ ‾ C_i=A_iB_i+(A_i+B_i)C_{i-1}\xlongequal[令t_i=A_i+B_i]{令d_i=A_iB_i}d_i+t_iC_{i-1}\xlongequal{德·摩根定律}\overline{\overline{d_i}\cdot\overline{t_iC_{i-1}}} Ci=AiBi+(Ai+Bi)Ci1di=AiBi ti=Ai+Bidi+tiCi1摩根定律 ditiCi1

  • 本地进位: d i = A i B i d_i=A_iB_i di=AiBi
  • 传递进位: t i = A i + B i t_i=A_i+B_i ti=Ai+Bi

上述两者均与外来进位无关。

图?四位串行进位链示意图

假设“与非门”的级延迟时间为 t y t_y ty,当所有的 d i d_i di t i t_i ti 形成后,4位全加器需要 8 t y 8t_y 8ty 产生全部进位, n n n 位全加器需要 2 n t y 2nt_y 2nty 产生全部进位

2. 并行进位链-普通版

  “并行进位链”的宗旨就是“同时产生”n位加法器的进位,被称为先行进位/跳跃进位。最直观的想法就是根据进位的递推公式,将所有进位的计算直接暴力展开,于是 所有的进位都可以直接产生

C 0 = d 0 + t 0 C − 1 C 1 = d 1 + t 1 C 0 = d 1 + t 1 d 0 + t 1 t 0 C − 1 C 2 = d 2 + t 2 C 1 = d 2 + t 2 d 1 + t 2 t 1 d 0 + t 2 t 1 t 0 C − 1 C 3 = d 3 + t 3 C 2 = d 3 + t 3 d 2 + t 3 t 2 d 1 + t 3 t 2 t 1 d 0 + t 3 t 2 t 1 t 0 C − 1 \begin{aligned} & C_0 = d_0+t_0C_{-1}\\ & C_1 = d_1+t_1C_{0} = d_1+t_1d_0+t_1t_0C_{-1}\\ & C_2 = d_2+t_2C_{1} = d_2+t_2d_1+t_2t_1d_0+t_2t_1t_0C_{-1}\\ & C_3 = d_3+t_3C_{2} = d_3+t_3d_2+t_3t_2d_1+t_3t_2t_1d_0+t_3t_2t_1t_0C_{-1}\\ \end{aligned} C0=d0+t0C1C1=d1+t1C0=d1+t1d0+t1t0C1C2=d2+t2C1=d2+t2d1+t2t1d0+t2t1t0C1C3=d3+t3C2=d3+t3d2+t3t2d1+t3t2t1d0+t3t2t1t0C1

图?四位一组并行进位链

假设级延迟时间“与非门/或门” t y t_y ty、“与或非门” 1.5 t y 1.5t_y 1.5ty,当所有的 d i d_i di t i t_i ti 形成后,优点是不管有多少进位,只要“与或非门”能连接足够的输入,n位全加器只需 2.5 t y 2.5t_y 2.5ty 就能产生全部进位(上图中n=4)。缺点是电路连接非常复杂,一般也就做到上述4位。于是便给出下面的折衷方式。

3. 并行进位链-单重分组跳跃进位链

  “单重分组跳跃进位链”的思路是将n位全加器分若干小组,小组中的进位同时产生,小组与小组之间采用串行进位。每一个小组内部,都采用上述普通版的并行进位链:

图?单重分组跳跃进位链-16位

根据前面假设,当所有的 d i d_i di t i t_i ti 形成后,4位全加器只需 2.5 t y 2.5t_y 2.5ty 就能产生全部进位,于是上述16位全加器需要 10 t y 10t_y 10ty 就能产生全部进位(串行进位链需要 32 t y 32t_y 32ty)。

4. 并行进位链-双重分组跳跃进位链

  “双重分组跳跃进位链”的思路是将n位全加器分若干大组,大组中又包含若干小组。每个大组中,小组的最高位进位同时产生,小组间的进位同时产生,大组与大组之间采用串行进位。对于单个大组来说,第一重进位由各个小组完成,但注意高位的小组(如5、6、7)都需要等待第二重小组计算完毕才能计算进位。每个小组本质上都是前面介绍的普通版“并行进位链”,只不过不计算最高位的进位,而是生成 D i D_i Di T i T_i Ti (生成方式如下公式)。小组间的连接方式如下图,假设每个小组都是4位加法器:

C 3 = d 3 + t 3 d 2 + t 3 t 2 d 1 + t 3 t 2 t 1 d 0 + t 3 t 2 t 1 t 0 C − 1 = 令 T 8 = t 3 t 2 t 1 t 0 令 D 8 = d 3 + t 3 d 2 + t 3 t 2 d 1 + t 3 t 2 t 1 d 0 = D 8 + T 8 C − 1 C 7 = D 7 + T 7 C 3 = D 7 + T 7 D 8 + T 7 T 8 C − 1 C 11 = D 6 + T 6 C 7 = D 6 + T 6 D 7 + T 6 T 7 D 8 + T 6 T 7 T 8 C − 1 C 15 = D 5 + T 5 C 11 = D 5 + T 5 D 6 + T 5 T 6 T 7 + T 5 T 6 T 7 D 8 + T 5 T 6 T 7 T 8 C − 1 \begin{aligned} C_3 &= d_3+t_3d_2+t_3t_2d_1+t_3t_2t_1d_0+t_3t_2t_1t_0C_{-1} \xlongequal[令T_8=t_3t_2t_1t_0]{令 D_8=d_3+t_3d_2+t_3t_2d_1+t_3t_2t_1d_0}=D_8+T_8C_{-1}\\ C_7 &= D_7+T_7C_{3} = D_7+T_7D_8+T_7T_8C_{-1}\\ C_{11} &= D_6+T_6C_{7} = D_6+T_6D_7+T_6T_7D_8+T_6T_7T_8C_{-1}\\ C_{15} &= D_5+T_5C_{11} = D_5+T_5D_6+T_5T_6T_7+T_5T_6T_7D_8+T_5T_6T_7T_8C_{-1}\\ \end{aligned} C3C7C11C15=d3+t3d2+t3t2d1+t3t2t1d0+t3t2t1t0C1D8=d3+t3d2+t3t2d1+t3t2t1d0 T8=t3t2t1t0=D8+T8C1=D7+T7C3=D7+T7D8+T7T8C1=D6+T6C7=D6+T6D7+T6T7D8+T6T7T8C1=D5+T5C11=D5+T5D6+T5T6T7+T5T6T7D8+T5T6T7T8C1

  • i i i 小组的本地进位: D i = d 3 + t 3 d 2 + t 3 t 2 d 1 + t 3 t 2 t 1 d 0 D_i=d_3+t_3d_2+t_3t_2d_1+t_3t_2t_1d_0 Di=d3+t3d2+t3t2d1+t3t2t1d0
  • i i i 小组的传送条件: T i = t 3 t 2 t 1 t 0 T_i=t_3t_2t_1t_0 Ti=t3t2t1t0

上述两者均与外来进位无关,且在本小组内连线固定。

图?双重分组跳跃进位链-32位

当所有的 d i d_i di t i t_i ti C − 1 C_{-1} C1 形成后,有如下的计算步骤:

  • 2.5 t y 2.5t_y 2.5ty 时刻:所有小组计算所有的 D i D_i Di T i T_i Ti;第8小组额外计算出自己的进位 C 2 C_2 C2 C 1 C_1 C1 C 0 C_0 C0
  • 5 t y 5t_y 5ty 时刻:第二大组计算出第二重的四个进位 C 3 C_3 C3 C 7 C_7 C7 C 11 C_{11} C11 C 15 C_{15} C15
  • 7.5 t y 7.5t_y 7.5ty 时刻:第4、5、6、7小组计算出自己的所有进位;第一大组计算出第二重的四个进位 C 19 C_{19} C19 C 23 C_{23} C23 C 27 C_{27} C27 C 31 C_{31} C31
  • 10 t y 10t_y 10ty 时刻:第1、2、3小组计算出自己的所有进位。

总结一下,使用双重分组跳跃进位链,32位全加器只需要 10 t y 10t_y 10ty 就能产生全部进位,而“单重分组的并行进位链”需要 20 t y 20t_y 20ty、“串行进位链”需要 64 t y 64t_y 64ty

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/774914.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言程序编译和链接

翻译环境和运行环境 我们程序员天天要写代码&#xff0c;那我们天天写的代码是什么呢&#xff1f;我们写的其实莫过于是一些test.c文件和test.h这样的文件。都是一些文本信息&#xff0c;这些如果直接交给机器去处理机器是看不懂的&#xff0c;就像我们和外国人语言不通一样&…

如何使用ChatGPT准备即将到来的面试How to Use ChatGPT to Prepare for an Upcoming Interview

使用ChatGPT来准备即将到来的面试可以非常有帮助&#xff0c;因为它可以模拟真实的面试场景并提供反馈。以下是一些步骤和提示&#xff0c;说明如何利用ChatGPT进行面试准备&#xff1a; 研究职位和公司&#xff1a;在与ChatGPT对话之前&#xff0c;先对你申请的职位和公司进行…

js算法记录

> 更多请前往 https://www.passerma.com/article/86 滑动窗口 1 给定一个矩阵&#xff0c;包含N*M个整数&#xff0c;和一个包含K个整数的数组。现在要求在这个矩阵中找一个宽度最小的子矩阵&#xff0c;要求子矩阵包含数组中所有的整数 function minSubmatrixWidth(mat…

JAVA面试大全之JVM和调休篇

目录 1、类加载机制 1.1、类加载的生命周期&#xff1f; 1.2、类加载器的层次? 1.3、Class.forName()和ClassLoader.loadClass()区别? 1.4、JVM有哪些类加载机制&#xff1f; 2、内存结构 2.1、说说JVM内存整体的结构&#xff1f;线程私有还是共享的&#xff1f; 2.2…

深入理解SSL协议:从理论到实践(二)

前言 这是一篇关于SSL协议的技术文章&#xff0c;有理论知识&#xff0c;但又兼具一定的实战性&#xff0c;文章的主要内容分享了SSL协议的核心概念、工作原理、常见的应用场景&#xff0c;以及就https这种实际应用场景&#xff0c;又着重分享具体的工作原理以及如何实现https…

鸿蒙HarmonyOS应用开发之使用Node-API接口创建ArkTs运行时环境

场景介绍 开发者通过pthread_create创建新线程后&#xff0c;可以通过napi_create_ark_runtime来创建一个新的ArkTs基础运行时环境&#xff0c;并通过该运行时环境加载ArkTs模块&#xff0c;目前仅支持在ArkTs模块中使用console接口打印日志&#xff0c;使用timer定时器功能。…

气体间隙的击穿强度

本篇为本科课程《高电压工程基础》的笔记。 气体间隙的击穿电压难以精确计算。工程应用中&#xff0c;大多参照一些典型的击穿电压试验数据来选择绝缘距离&#xff0c;要求较高的情况下感召实际电极布置&#xff0c;用实验方法来确定击穿电压。 稳态电压下的击穿 直流与工频…

SpringBoot 多数据源及事务解决方案

1. 背景 一个主库和N个应用库的数据源&#xff0c;并且会同时操作主库和应用库的数据&#xff0c;需要解决以下两个问题&#xff1a; 如何动态管理多个数据源以及切换&#xff1f; 如何保证多数据源场景下的数据一致性(事务)&#xff1f; 本文主要探讨这两个问题的解决方案…

全国植被类型分布数据

引言 全国植被类型分布数据利用 Landsat 卫星数据&#xff08;Landsat TM&#xff0c;ETM和 OLI&#xff09;完成了长时序的地表覆盖变化检测&#xff0c;并结合变化 检测结果实现了逐区域和逐期的地表覆盖动态更新&#xff0c;30米精细植被类型分布数据&#xff0c;共包含 2…

Python爬虫之爬取网页图片

当我们想要下载网页的图片时&#xff0c;发现网页的图片太多了&#xff0c;无从下手&#xff0c;那我们写一个脚本来爬取呗。 这次的脚本是专门针对某个外国网站使用的&#xff0c;因此仅供参考思路。 在测试的过程中&#xff0c;我发现网站使用了发爬虫机制&#xff0c;具体就…

FPGA工程师及其相关岗位招聘~

社区的招聘功能上线之后&#xff0c;许多企业都在上面发布了招聘岗位。 目前有30企业&#xff0c;岗位围绕FPGA工程师&#xff0c;涵盖嵌入式软件工程师、射频工程师、C语言开发、BMC工程师等等&#xff0c;入口放在这里&#xff1a;F学社-全球FPGA技术提升平台 登录账号后&a…

HCIP-Datacom(H12-821)题库补充(3/27)

最新 HCIP-Datacom&#xff08;H12-821&#xff09;完整题库请扫描上方二维码访问&#xff0c;持续更新中。 运行OSPF协议的路由器&#xff0c;所有接口必须属于同一个区域。 A&#xff1a;正确 B&#xff1a;错误 答案&#xff1a;B 解析&#xff1a;OSPF的邻居关系是基于…

Python环境下滚动轴承状态监测与故障诊断(NASA IMS轴承数据集)

智能维护系统IMS)滚动轴承数据是美国辛辛那提大学智能维护系统中心提供的全寿命周期数据&#xff0c;轴上安装了4个轴承。通过摩擦带将转速保持恒定在 2000r/min。包含3个数据集&#xff0c;每个数据集描述了一个测试到失败的实验。其中第一个实验装置的数据采集从 2003 年 10月…

鸿蒙OS开发实例:【工具类封装-emitter组件间通信】

import Emitter from ohos.events.emitter; import pasteboard from ohos.pasteboard; MyEmitterUtil 是一个针对 HarmonyOS 的事件驱动编程封装类&#xff0c;主要用于组件间的通信和数据传递。 使用要求&#xff1a; DevEco Studio 3.1.1 Release 或更高版本API 版本&…

get 请求中传递数组参数

文章目录 问题分析 问题 使用get请求传参时有参数是数组 分析 qs.stringify({ a: [b, c] }, { arrayFormat: indices }) // 输出结果&#xff1a;a[0]b&a[1]c qs.stringify({ a: [b, c] }, { arrayFormat: brackets }) // 输出结果&#xff1a;a[]b&a[]c qs.stringif…

Qt C++ | QTimer经验总结

QTimer Class QTimer类提供重复计时器和单次计时器 头文件: #include <QTimer> qmake: QT += core 继承自: QObject 定时器信号 void timeout() 公共函数 Qt::TimerType 枚举定义了 Qt 中不同类型的定时器。它包含以下值: **Qt::PreciseTimer:**高精度定时器,用…

国内ip地址推荐,畅享网络新体验!

在数字化时代&#xff0c;IP地址不仅是网络连接的基石&#xff0c;也是互联网产业发展的重要标志。国内作为全球互联网市场的重要参与者&#xff0c;拥有众多IP地址资源。虎观代理小二旨在探索并推荐一些国内IP地址&#xff0c;分析它们的价值所在&#xff0c;并探讨如何更好地…

hcia datacom课程学习(4):ICMP与ping命令

1.什么是ICMP ICMP是ip协议的一部分&#xff0c;常用的ping命令就是基于icmp协议的。 在防火墙策略中也能看到ICMP&#xff0c;如果将其禁用&#xff0c;那么其他主机就ping不通该主机了 2. ICMP数据报 2.1数据报构成 ICMP协议的报文包含在IP数据报的数据部分&#xff0c; …

[windows]Windows上缩放窗体的两种方式

第一种 直接上图 第二种 第二种方式时&#xff0c;快速拖动时&#xff0c;如果是chrome浏览器套壳软件就会出现拖动部分出现黑边的现象而原生的桌面应用程序则不会出现黑边。这现象在chrome浏览器本身就存在。如图 typora是用electron写的软件存在该问题

相位解包裹前识别有效区域和无效区域(条纹和背景区域区分)

对于不连续场进行相位解包的时候,首先要识别出图象中的哪些部分为有效数据,哪些部分为非有效数据"。这不仅关乎着相位解包算法的速度,更影响着解包算法的精度。因此在解包之前,对有效区域和无效区域的判断必须是首先要做的一件事情。下面就来介绍一下什么是有效区域和…