Chapter 9 Arithmetic(9)
Chapter 9 Arithmetic(9)
这一章是很难的,不过我打的就是精锐。😎
Contents of this lecture
内容 | English |
---|---|
对齐 | Alignment |
加法/减法规则 | Add/Subtract Rule |
乘法规则 | Multiply Rule |
除法规则 | Divide Rule |
浮点运算中需要考虑的问题 | Problems Considerable in FP Arithmetic |
保护位 | Guard Bits |
截断 | Truncation |
标准化 | Normalization |
溢出 | Overflow |
对齐 (Alignment)
加法和减法运算的第一步:
浮点数的加法和减法运算需要先进行对齐操作。对齐的过程:
- 在进行加法/减法之前,如果两个浮点数的指数不同,就需要对这两个数的尾数部分进行调整,使得它们的指数相等。
例子:十进制加法运算
$ (123 ^0) + (456 ^2) $步骤 1:调整尾数,使得两个数的指数相同:
- $ (123 ^0) + (456 ^2) $
- 通过将尾数调整,使得两个数的指数相同:
- $ (123 ^0) + (4.56 ^0) $
- 或者
- $ (12300 ^2) + (456 ^2) $
对齐方法:
对齐是通过将尾数的大小部分右移一位,并增加指数值,直到两个指数相等为止。
加法/减法规则 (Add/Subtract Rule)
对于 IEEE 单精度浮点数:
选择指数较小的数,并将其尾数右移,移动的步数等于两个指数的差值。
设置结果的指数为较大的指数。
对尾数进行加法或减法运算,并确定结果的符号。
如果需要,进行标准化,使得尾数符合标准化格式。
乘法规则 (Multiply Rule)
对于 IEEE 单精度浮点数:
加法运算指数,然后减去偏移量 127,得到结果的指数。
乘法运算尾数,并确定结果的符号。
如果需要,进行标准化,使得结果符合标准化格式。
除法规则 (Divide Rule)
对于 IEEE 单精度浮点数:
减去指数,然后加上偏移量 127,得到结果的指数。
除法运算尾数,并确定结果的符号。
如果需要,进行标准化,使得结果符合标准化格式。
浮点运算中需要考虑的问题
浮点运算中需要考虑的问题 (1)
保护位 (Guard Bits)
提高浮点运算精度:
为了提高浮点运算的精度,使用了保护位(Guard Bits)。保护位的定义:
保护位是尾数部分中额外保留的位,这些位用于在浮点数尾数的右端填充 0。保护位的重要性:
在计算过程中,保留保护位是非常重要的,这样可以确保在中间步骤中的运算精度,从而在最终结果中获得最大的准确度。
浮点运算中需要考虑的问题 (2)
保护位 (继续)
例子:
假设有两个浮点数 $ X = 1.0000 ^1 $ 和 $ Y = 1.1111 ^0 $,计算它们的乘积
$ Z = X Y $。
假设 $ X $ 和 $ Y $ 都是 IEEE 单精度格式。
- 没有保护位的情况:
- $ X = 1.00000 ^1 $
- $ Y = 0.11111 ^1 $
- 计算得:
$ Z = 0.00001 ^1 = 1.00000 ^{22} $
- $ X = 1.00000 ^1 $
- 有保护位的情况:
- $ X = 1.00000 ^1 $
- $ Y = 0.11111 ^1 $
- 计算得:
$ Z = 0.00000 ^1 = 1.00000 ^{23} $
- $ X = 1.00000 ^1 $
通过使用保护位,可以减少舍入误差,提高结果的精度。
浮点运算中需要考虑的问题 (3)
截断 (Truncation)
尾数长度限制:
尾数部分的位数是有限制的,单精度浮点数为 23 位,双精度浮点数为 52 位。运算可能产生更高精度的尾数:
在进行浮点数运算时,尾数可能会有更多的有效位数。存储前的截断:
在将浮点数存储之前,超出的位数必须被丢弃,这就是截断操作。截断方法应该是无偏的:
截断过程中,误差应互相抵消,不应该系统性地偏向某一方向。
截断方法
截断法 (Chopping):
将尾数部分直接截断,去掉多余的位数。冯·诺依曼舍入 (Von Neumann Rounding):
根据尾数的下一位决定是否将尾数增加 1,如果该位大于等于 5,则加 1。四舍五入 (Rounding):
将尾数舍入到指定的位数,通常是最接近的整数。
浮点运算中需要考虑的问题 (4)
截断法 (Chopping)
- 操作方法: 截断法直接去除保护位(guard bits),并且不对保留的位进行任何修改。
- 实现简便: 截断法非常容易实现,因为它不需要复杂的舍入规则。
- 有偏差: 由于截断法始终将尾数值向下舍入(即总是向较小的尾数值舍入),因此它是有偏的。
- 误差范围: 截断法的误差范围从 0 到几乎 1(在保留的位的最低有效位处)。
- 不是最佳方法: 截断法不是最优的方法,因为它会导致系统性的误差。
浮点运算中需要考虑的问题 (5)
截断法 (Chopping) 继续
例子:将 $ 0.b1b2b3b010 $ 截断到三位。
截断过程:
给定的二进制数是 $ 0.b1b2b3b010 $,截断到三位后得到 $ 0.b1b2b3 $。截断范围:
实际上,所有位于 $ 0.b1b2b3b000 $ 到 $ 0.b1b2b3b111 $ 之间的分数都会被截断为 $ 0.b1b2b3 $。误差范围:
在三位结果中,误差范围从 0 到 $ 0.000111 $,即最小值到最大截断误差。浮点运算中需要考虑的问题 (6)
冯·诺依曼舍入 (Von Neumann Rounding)
舍入规则:
冯·诺依曼舍入方法通过区分精确表示和向下舍入到下一个奇数边界来执行舍入。具体规则如下:- 如果要移除的位全是 0:直接删除这些位,不改变保留的位。
- 如果要移除的位中有 1:则将保留位的最低有效位(LSB)设置为 1。
实现难度:
相对于截断法,冯·诺依曼舍入法仍然比较容易实现。无偏性:
该舍入方法是无偏的,因为它将舍入结果平均分布在正值和负值之间。误差范围:
误差范围在保留位的最低有效位(LSB)位置之间,范围从 -1 到 +1。优于截断法:
相比于截断法,冯·诺依曼舍入方法具有更高的精度,并且其绝对误差较大。浮点运算中需要考虑的问题 (7)
冯·诺依曼舍入 (Von Neumann Rounding) 继续
例子:将 $ 0.b1b2b3b000 $ 和 $ 0.b1b2b3b111 $ 截断到三位。
情况 ①:
给定的二进制数 $ 0.b1b2b3b000 $ 去掉尾部的 0 后得到 $ 0.b1b2b3 $,因为要移除的位全是 0。情况 ②:
给定的二进制数 $ 0.b1b2b3b001-0.b1b2b3b111 $ 由于移除的位中有 1,因此将保留位的最低有效位(LSB)设置为 1,最终结果是 $ 0.b1b2b31 $。
冯·诺依曼舍入方法通过这种方式,在处理舍入时保证了无偏性,并且使误差在正负方向上平均分布。
浮点运算中需要考虑的问题 (8)
舍入 (Rounding)
舍入操作将数值映射到其最接近的可表示值,区分以下三种情况:
当尾数部分需要截断的最高有效位(MSB)为 0:
直接进行截断(chopping),即不做任何更改。当尾数部分需要截断的最高有效位(MSB)为 1,且其他被截断的位中有 1:
将保留的最低有效位(LSB)加 1。当尾数部分需要截断的最高有效位(MSB)为 1,且其他被截断的位全为 0:
- 如果保留的最低有效位(LSB)为 0,则直接截断。
- 如果保留的最低有效位(LSB)为 1,则将其加 1。
实现难度:
相比截断法,舍入方法实现起来稍有难度。无偏性:
舍入方法是无偏的,舍入的结果在正值和负值之间平均分布。误差范围:
误差范围在保留位的最低有效位(LSB)位置之间,误差从 -1/2 到 +1/2。浮点运算中需要考虑的问题 (9)
舍入 (Rounding) 续
示例:截断 0.b1b2b3 000 到三位:
情况 1:
输入:0.b1b2b3 000 → 输出:0.b1b2b3 011
结果:0.b1b2b3情况 2:
输入:0.b1b2b3 101 → 输出:0.b1b2b3 111
结果:0.b1b2b3 + 0.001情况 3:
输入:0.b1b2b3 100 → 输出:0.b1b2 0100
结果:0.b1b2 0输入:0.b1b2b3 1100 → 输出:0.b1b2 1 + 0.001
结果:0.b1b2b3 + 0.001
舍入是IEEE浮点数标准中默认的截断模式。
浮点运算中需要考虑的问题 (10)
归一化 (Normalization)
- IEEE 单精度归一化浮点数
- 指数 E ≠ 000...0 (8位) 且 E ≠ 111...1 (8位)
- 指数 E 使用偏移值编码
- 归一化的有效数字形式为 1.M(即尾数部分以 1 开头)
- 非归一化的数字
- 如果数字不是归一化的,可以通过右移尾数并调整指数来将其转换为归一化形式。
浮点运算中需要考虑的问题 (12)
溢出 (Overflow)
- 溢出
- 随着计算的进行,可能会生成一个超出正常数字可表示范围的数值。
- 指数溢出
- 当正指数超过最大可能的指数值时,发生指数溢出。
- 例如,在 IEEE 单精度中,当指数 e > 127 时,发生溢出。
- 在某些系统中,溢出的结果可能表示为正无穷大或负无穷大。
- 指数下溢
- 当负指数小于最小可能的指数值时,发生指数下溢。
- 例如,在 IEEE 单精度中,当指数 e < 126 时,发生下溢。
- 这意味着该数字太小,无法表示,可能会被报告为 0。
浮点运算中需要考虑的问题 (13)
溢出 (Overflow) 续
- 尾数溢出 (Mantissa Overflow)
- 当两个尾数的符号相同时,它们的相加可能导致最左侧的有效位发生进位。
- 如果发生进位,则结果的尾数会右移,指数值会增加。
- 当两个尾数的符号相同时,它们的相加可能导致最左侧的有效位发生进位。
- 尾数下溢 (Mantissa Underflow)
- 在对尾数进行对齐时,数字可能会从尾数的右端流出。
- 这种情况可以通过使用保护位(guard bits)以及某种截断方法来解决。
- 在对尾数进行对齐时,数字可能会从尾数的右端流出。
浮点运算的实现
实现方法
- 软件例程 (Software Routines)
- 硬件例程 (Hardware Routines)
计算机将提供用于浮点运算的机器指令。
注意
无论是使用软件例程还是硬件例程,计算机都必须能够将输入和输出从用户的十进制表示转换到浮点数表示,反之亦然。
硬件实现示例
- 32 位操作数:
- {A: \(S_A\), \(E_A'\), \(M_A\)}
- {B: \(S_B\), \(E_B'\), \(M_B\)}
- {A: \(S_A\), \(E_A'\), \(M_A\)}
Quiz
习题 (1)
题目: 对错题: 尾数部分的溢出意味着浮点数发生了真实的溢出。
答案: 错。
解释: 浮点数的尾数部分溢出并不是真正的溢出。尾数溢出可以通过移位来解决,即将尾数向右移动,同时调整指数部分。真正的溢出发生在指数部分,当指数超出可表示的范围时,才会导致浮点数的真实溢出。
习题 (2)
题目:
考虑一个简化的 8 位 IEEE 浮点格式,其中 1 位用于符号位,3 位用于指数,4
位用于尾数。请注意尾数是标准化的,意味着二进制小数点左边隐含有 1。
- 表示 A = 2.38 和 B = 1.6 在此浮点格式中。
- 写出 A 和 B 的计算过程,并将结果写成标准化形式。必要时使用舍入方法。