【2020/12/4修订】【梳理】计算机组成与设计 第3章 算术 第2节 浮点(docx)

配套教材:
Computer Organization and Design: The Hardware / Software Interface (5th Edition)
这是专业必修课《计算机组成原理》的复习指引。建议将本复习指导与博客中的《简明操作系统原理》配合复习。
需要掌握的概念在文档中以蓝色标识,并用可读性更好的字体显示 Linux 命令和代码。代码部分语法高亮。
计算机组成原理不是语言课,本复习指导对用到的编程语言的语法的讲解也不会很细致。如果不知道代码中的一些关键字、指令或函数的具体用法,你应当自行查找相关资料。


第三章 算术

第一节 整数的四则运算

第二节 浮点

第三节 数据级并行

注意

链接:https://pan.baidu.com/s/1KqTIQs9qUwwrt3ov-qYNCw
提取码:0000


第二节 浮点
浮点(floating-point)是一种用于近似表示小数的数据格式。之所以这样命名是因为小数点的位置不固定。计算机中采用科学计数法(scientific notation)表示一个浮点数。采用科学计数法的优点有:
(1)简化了包含浮点数的数据交换。
(2)简化了浮点数的算法,因为所有浮点数都始终保持这一种格式。
(3)尽可能增加了数据的精度(相同的存储空间而存储精度更高),因为不必要存储一连串前导0(leading 0),腾出的空间可以存储小数点后的有效位。科学计数法中,没有前导0的数称为规范化(normalized,规格化)的数。

一个浮点数中,一部分是小数(分数(fraction),也称尾数),一部分是指数(exponent)。这两部分互相挤占存储空间:其中一项多一位,另一项就少一位。第二章我们已经提过:好的设计要求好的妥协。
浮点数除了有上溢(overflow)的概念以外还有下溢(underflow),分别代表浮点数过大或过小以至于指数部分不能表示。

计算机中的浮点数主要有单精度(single precision)和双精度(double precision)两种。它们的格式如下:

单精度和双精度的最高位都是符号,正0负1;单精度的指数部分是8位,分数23位;双精度的指数部分是11位,分数部分是52位。它们都由IEEE 754标准规定,1980年以来的每台计算机都遵循该标准。符号位放在最高位,指数位放在分数位之前,能够简化浮点数与整数混合的一组数据比较大小的过程。
上面的格式中,指数和分数部分自然也是二进制的;将能够表示的范围转换成十进制,单精度和双精度能表示的绝对值范围大约分别是:1.18×10-38 ~ 3.40×1038,2.23×10-308 ~ 1.79×10308。
除了0以外,分数部分总是在1到2之间。由于1也算一个有效位,所以有效位数(significand)是指数部分的位数+1。当所有位数都是0时,浮点数表示0。还有专门的值表示正负无穷大和NaN(Not a Number)。

设分数部分为F,指数部分为E,符号位S,指数偏移(exponent bias)B,则一个浮点数的值可以表示为:
(–1)S×(1 + F)×2E–B
对单精度浮点数,B = 127;对双精度浮点数,B = 1023。
有很多数是无法用常见的浮点格式精确表示的,这时它们会被转换成离实际数据最近的浮点数保存。

2008年,IEEE修订了IEEE-754标准,称为IEEE-754 2008。相比IEEE-754 1985,新版本的标准增加了对半精度(half precision)和四精度(quadruple precision)的支持,也增加了十进制算术的规定。IBM的大型机已经跟进了十进制算术。目前还没有硬件提供对四精度的支持。

在IEEE 754以前,为了扩大浮点数能表示的范围,一些计算机表示浮点数并非采用二进制。例如IBM 360、370大型机采用16进制。也就是说,这种计算机的浮点格式中的指数部分每位移一位,相当于乘或除以16。“规格化”后的16进制浮点数最多可以有3个前导零(前导零的数量达到4的时候才可以修改分数部分和指数部分使得分数部分的最高位非0)。于是,16进制浮点在使用过程中,有效位数部分最多有3个bit需要丢弃(二进制位被前导0占了),这就带来了精度上的大问题。IBM的大型机目前既支持IEEE 754标准,也支持十六进制的浮点格式。

浮点数的加法过程如下:

先比较指数,当指数不同时,调整指数和分数部分,使得指数较小的浮点数的指数与指数较大的浮点数的相同。然后就可以将有效位相加。接下来将结果规范化,结合左移右移和指数的加减来调整。下一步检查是否上溢或下溢。如是,抛出异常;如否,对结果进行舍入。如果舍入之后的结果不是规范化的,则重新进行规范化,直到舍入后的结果也规范化为止,然后输出。

现代的许多计算机的CPU中包含专门的浮点处理单元(Float processing unit,FPU)来进行浮点运算。

FPU中有一个小的ALU,用于比较两个指数不同的浮点数谁的指数更大。比较结果控制三个数据选择器,也叫多路选择器(multiplexer,MUX),它们选择较大的指数和两数的有效位,然后根据比较结果进行调整,使得指数相同,然后将有效位在大的ALU中相加,接着对结果进行舍入。

浮点数乘法的计算步骤如下:

先将指数加起来(要加回多减去一次的指数偏移),然后把有效位相乘,规范化,再检查是否溢出,然后舍入。如果舍入后并非规范化的浮点数,再次规范化(位移有效位兼加减指数),直到舍入后仍旧规范化为止,计算结果的符号并输出。

有的CPU使用专门的浮点寄存器。这种独立的寄存器设计会可能会略微增加程序的汇编指令数目;同时,可能需要专门的指令在浮点寄存器和内存之间进行数据传输。
专用的浮点寄存器的好处是:倍增了寄存器数目,而可以不在指令格式中增加更多的位数表示寄存器;另外,可以将整数和浮点并行读写,增加了寄存器带宽;此外,还可以针对性地设计浮点寄存器的结构,以提升寄存器性能,降低其功耗。

32个MIPS浮点寄存器中,只有16个用于双精度操作: f 0 、 f0、 f0f2、$f4、……。双精度运算成对使用这些偶数编号的浮点寄存器,而编号为奇数的浮点寄存器仅用于存储双精度浮点数的右半部分。MIPS-32的所有浮点指令都提供了“单精度配对”(paired single)版本,一条指令可以并行执行两个浮点运算。

C / C++和许多语言的二维数组是行优先存储的(row-major order),也就是说存储顺序是a[0][0],a[0][1],a[0][2],……。Fortran则采用列优先存储。

为了提高舍入的精度,按照 IEEE 754的规定,在浮点数的计算过程中会多留两位有效数字,分别称为保护位(guard bit)和舍入位(round bit)。当需要计算乘法时,两位保护位是必要的:乘法的结果可能会出现一个前导零,这时候因为要进行规范化,有效位会被左移一位,这时候一个保护位就会移到最低有效位(least significant bit,LSB)处,这时候仍然需要另一个位于最低有效位右侧的保护位来进行舍入。

ULP(units in the last place)用于衡量浮点误差,代表浮点数可以表示的有效数字有几个低位与实际结果不同。IEEE 754保证计算机在使用单精度和双精度浮点每次进行各种运算时的误差在1.5 ULP以内。

IEEE 754规定了四种舍入模式:向正无穷舍入、向负无穷舍入、截断(truncate)、向最近的偶数舍入。美国国税局(IRS)总是将0.5美元向上舍入;一个更公平的方法是随机决定:一半的概率向上舍入,一半的概率向下。IEEE 754规定:将末位为5的浮点向最近的偶数进行舍入时,如果是奇数,进一;如果是偶数,截断。
为了实现向最近偶数舍入,舍入位之后还有一位粘滞位(sticky bit)。向最近偶数舍入时,入的条件为guard = 1 and sticky = 1,或者:guard = 1 and sticky = 0但精度最低位为1。

PowerPC、SPARC64和支持AVX的x86架构均支持乘加融合(fused multiply add,FMA)指令。这个指令计算a = a + b×c。IEEE 754-2008也添加了FMA支持。这种算式很常用,因此FMA指令大大提升了性能。而且,FMA只在执行完加法后进行一次舍入,而非在乘法和加法的过程中各舍入一次,也提高了精度。

有序比较(ordered compare)和无序比较(unordered compare)的区别是:一次有序比较检查是否两个操作数都不是NaN。一次无序比较检查两个操作数中是否任意一个操作数是NaN。与NaN的比较结果是不确定的(无法确定结果),因此,有序 / 无序比较用来检查是否是这种情况。

IEEE 754标准允许操作数以非规范化的形式出现,使得能表示更接近0的数。例如(b后缀表示二进制):
最小的正单精度规格化数为1.0000 0000 0000 0000 0000 000b×2-126;
最小的单精度非规格化数为0.0000 0000 0000 0000 0000 001b×2-126,即1.0b×2-149。
对于双精度,非规格化间隙为1.0×2-1022到1.0×2-1074。
如果想设计更快速的浮点单元,就需要应付操作数为非规范化数的情形,这一点很麻烦。因此,许多计算机选择在源操作数不是规范化数时产生异常。软件上可以等效实现不产生异常的非规格化浮点运算,但效率很低。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值