电子商务网站策划ppt特效制作软件
系列文章目录
目录
- 浮点数的表示和运算
 - 浮点数的表示
 - 浮点数的规格化
 - 浮点数标准
 - IEEE754
 - 浮点数表示范围
 - 浮点数的转换
 - 浮点数的运算
 - 浮点数加法
 - 浮点数加法的硬件实现
 - 精度
 - 浮点乘法
 - 浮点运算硬件
 - MIPS中的浮点指令
 
浮点数的表示和运算
浮点数的表示
- 表达非整型的数 
- 可以表达很小和很大的数
 
 - 和科学计数法类似 
- -2.34e56
 - +0.002e-4
 - +987.02*e9
 
 - 二进制表示 
- ±1.×××××× * 2的n次方
 
 - C语言中float和double
 
浮点数的规格化
为了表示非整数实数,现在的计算机广泛采用小数点浮动的浮点数,以-0.75为例子,首先转化为二进制实数,然后将二进制实数表示为以2为基数的科学计数法,这个过程称为规格化
这时候得到三个重要信息:1.实数的正负 2.小数点右边的尾数 3. 2的指数
浮点数标准
- IEEE754 -1985标准 
- 消除表达的不一致性
 - 科学计算中的可移植性
 
 - 现在被普遍则采用的2种标准 
- 单精度(32-bit)
 - 双精度(64-bit)
 - IEEE
 
 
IEEE754
IEEE754规定,单精度浮点数大小为32位,其中最高1位是符号位(sign),随后8位是指数域(exponent),剩下全部表示尾数(fraction)

一般浮点数表达形式:
![]()
F 为小数域的值, E 为指数域的值
  
浮点数表示范围
8位指数可以表示0~255共256个自然数,但是只有1~254表示真正的浮点数,为了方便比较大小,浮点数的指数域采用一种类似于移码的表示方法, 即1(0000 0001)~254(1111 1110)分别对应-126~+127,也就是说,算出真正阶数指数后,还要加上127的偏阶
故浮点数表达形式也可写成
![]()

浮点数的转换
- 简单情况:如果除数是2的整数倍,则比较简单
 

- 除数不是2的整数倍 
- 该数无法精确表示
 - 可能需要多位有效位来保证精度
 - 难点是如何得到有效位
 
 - 循环小数有个循环体
 - 转换 
- 求出足够多的有效位
 - 根据精度要求(单、双) 截断多余位
 - 按照标准要求给出符号位、阶和有效位
 
 

浮点数的运算
浮点数加法
运算步骤
- 先转化为二进制科学计数法
 - 小对大,指数较小的数转化为指数较大的数的形式
 - 再相加,列竖式相加
 - 规格化,将和重新规格化
 - 舍入查,四舍五入,检查是否发生指数溢出
 
对单精度,指数高于+127为上溢,低于-126为下溢
浮点数加法的硬件实现
- 比整数复杂很多
 - 如果在一个时钟周期内完成,就会要求时钟周期非常的长 
- 比整数运算更费时
 - 较慢的时钟会对所有指令产生影响
 
 - 浮点加法器通常需要花费几个时钟周期 
- 可以被流水化
 
 


精度
IEEE定义了多种舍入控制策略
- 多存储几个位(舍入、保护、粘贴) 
- 保护位:在浮点数中间计算中,在右边多保留的两位以上的首位,用于提高传入精度
 - 舍入位:在右边多保留的两位中的第二位,使浮点中间结果满足浮点格式,得到最接近的数
 - 粘贴:末位始终为1,或末位为0舍1入
 
 - 可以选择不同的舍入模式
 - 允许程序员微调计算中的行为
 - 不是所有的硬件都实现了IEEE754的舍入策略 
- 大部分语言和类库只是使用了缺省的策略
 
 - 是硬件复杂度、效率和市场需求的折衷
 
浮点乘法
运算步骤
- 指数加:被乘数和乘数的指数相加(是真正指数,而不是加了偏阶的指数)
 - 再相乘:列竖式相乘
 - 规格化:将积重新规格化
 - 舍入查:四舍五入,检查是否发生指数溢出
 - 定符号:如果被除数和乘数反号,则符号位为1
 


浮点运算硬件
- 浮点乘法和加法的硬件复杂度类似 
- 有效位上进行乘法而不是加法
 
 - 浮点运算通常需要的操作是 
- 加法, 减法, 乘法, 除法, 求倒数, 平方根
 - 浮点数和整数间的转换
 
 - 通常需要多个时钟周期 
- 很容易用流水实现
 
 
MIPS中的浮点指令
- 浮点数使用协处理器 
- 通过ISA相连的协处理器
 
 - 独立的浮点寄存器 
- 32个单精度: $f0, $f1, … $f31
 - 配对为双精度: $f0/$f1, $f2/$f3, … 
- Release 2 of MIPs ISA supports 32 × 64-bit FP reg’s
 
 
 - 浮点指令只操作浮点寄存器 
- 程序通常不会在浮点寄存器上进行整数操作,或在整数寄存器上进行浮点操作
 - 因此可以提供更多的寄存器,而不影响指令的长度
 
 - 浮点数读取、存储指令 
- lwc1, ldc1, swc1, sdc1
 - e.g. ldc1 $f8, 32($sp)
 
 - 单精度 
- add.s, sub.s, mul.s, div.s
 - e.g. add.s $f0, $f1, $f6
 
 - 双精度 
- add.d, sub.d, mul.d, div.d
 - e.g. mul.d $f4, $f4, $f6
 
 - 比较 
- c.xx.s, c.xx.d (xx is eq, lt, le, …)
 - Sets or clears FP condition-code bit 
- e.g. c.lt.s $f3, $f4
 
 
 - 分支 
- bclt, bclf
 - e.g. bc1t TargetLabel
 
 
示例
float f2c (float fahr) {
   return ((5.0/9.0)*(fahr - 32.0));
 }

一个注意点
我们常用sll实现乘二的幂,但是用srl实现除二的幂会出现问题,对于无符号数是相同的,但是对于有符号,算数右移需要补入符号位才相同,如果补零则不同
