PC_浮点数加减运算
机器数_浮点数加减运算
-
浮点数计算特点是阶码和尾数分开计算
-
根据假设条件/给定条件:
- 阶码一般为整数,可能使用的是移码或者补码来表示
- 尾数一般为绝对值小于1的规格化数(定点原码表示或者定点补码)
-
🎈一般默认阶码和尾数都是用补码来表示
对阶
-
使得两个操作数的小数点位置对齐
- 表现为两个数的阶码相等
-
步骤:
-
设两个规格化浮点数(强调规格化是为了便于讨论)为:(书面书写,就不必使用严格的机器标准IEEE 754)
-
a = E a S a a=E_aS_a a=EaSa
-
b = E b S b b=E_bS_b b=EbSb
-
设 E a < E b 设E_a<E_b 设Ea<Eb
-
基数默认为2,浮点数的阶码和尾数分别用E,S表示
-
-
求阶差 δ \delta δ
-
然后小阶向大阶看齐
- 尾数 S a 向右移 1 位 , E a 更新为 E a + 1 尾数S_a向右移1位,E_a更新为E_a+1 尾数Sa向右移1位,Ea更新为Ea+1
- 重复执行 δ 次 , 就可以使得 a , b 的阶对齐 ( E a = E b ) 重复执行\delta次,就可以使得a,b的阶对齐(E_a=E_b) 重复执行δ次,就可以使得a,b的阶对齐(Ea=Eb)
-
尾数求和
- 按照定点数的加减方法进行求和
- 相当于做连个定点数加/减法
- 此阶段得到的结果不一定是规格化的
规格化
- 前一步操作得到的结果进行规格化,其手法在浮点数的表示中介绍过
- 但是这里考虑规格化数的补码形式
舍入
- 依然以补码的角度考虑
0舍1入
-
类似于十进制(真值)的四舍五入
-
只有右归(末尾(若干)小数)被移丢时,才有考虑舍入的必要(有意义)
-
基本原理是,补码函数C(x)在正数区间和负数区间内部:
- ∣ C ( x 1 ) ∣ < ∣ C ( x 2 ) ∣ ⇔ x 1 < x 2 |C(x_1)|<|C(x_2)|\Leftrightarrow{x_1<x_2} ∣C(x1)∣<∣C(x2)∣⇔x1<x2
- 假设右移的时候,被移去的小数的位段是
x
m
⋯
x
n
x_m\cdots{x_n}
xm⋯xn
- 那么根据
x
m
x_m
xm:
- 如果 x m = 1 x_m=1 xm=1则+1(入)
- 否则+0
- 那么根据
x
m
x_m
xm:
例
-
假设某个求和结果 : ( x − y ) 补 = 11 , 00 ; 10.110001 根据双符号位的性质 , 上述结果是一个溢出 ( 负溢出 ) 值 需要进行右归 ( x − y ) 补 = 11 , 00 ; 11.011000 1 ♣ ( 注意 , 溢出的双符号位在右移时 , 只有低位参与右移 , 并将缺失的低位符号用高位符号补位 , 得到不溢出的结果 ) 现在发现被右移操作移出去的 ( 最高 ) b i t 是 1 , 于是根据 0 舍 1 入 , 对其进行末尾数码 + 1 处理 11.011000 + 1 11.011001 所以 ( x − y ) 补 = 11 , 00 ; 11.011001 假设某个求和结果: \\(x-y)_补=11,00;10.110001 \\根据双符号位的性质,上述结果是一个溢出(负溢出)值 \\需要进行右归 \\(x-y)_补=11,00;11.011000\ \underset{\clubsuit} 1 \\(注意,溢出的双符号位在右移时,只有低位参与右移, \\并将缺失的低位符号用高位符号补位,得到不溢出的结果) \\现在发现被右移操作移出去的(最高)bit是1,于是根据0舍1入, \\对其进行末尾数码+1处理 \\ \begin{aligned} &&11.011000& \\&+&1& \\\hline &&11.011001& \end{aligned} \\所以(x-y)_补=11,00;11.011001 假设某个求和结果:(x−y)补=11,00;10.110001根据双符号位的性质,上述结果是一个溢出(负溢出)值需要进行右归(x−y)补=11,00;11.011000 ♣1(注意,溢出的双符号位在右移时,只有低位参与右移,并将缺失的低位符号用高位符号补位,得到不溢出的结果)现在发现被右移操作移出去的(最高)bit是1,于是根据0舍1入,对其进行末尾数码+1处理+11.011000111.011001所以(x−y)补=11,00;11.011001
溢出判断
- 舍入操作中的:舍0入1法可能会执行尾码加1操作
- 这可能引发连续进位导致溢出
- 因此,舍入后可能还要在判断溢出
- 如果发现溢出,需要重新规格化(右归)(而不会是左归)
- 规格化可以消除尾数部分的溢出(可以称为伪溢出)现象
- 当规格化完成后,在看看阶码是否处在合理的范围内
- 浮点数的溢出更重要的是规格化尾数后的阶码是否溢出
- 假设阶码用两位符号位表示,那么根据补码的溢出判定方法:
- 浮点数 F = 2 j ⋅ S F=2^{j}\cdot{S} F=2j⋅S
- 阶码(指数)的补码 C ( j ) C(j) C(j)的两位符号位不同时认为发生溢出
-
C
(
j
)
=
01
,
⋯
C(j)=01,\cdots
C(j)=01,⋯
- 这种情况是浮点数发生上溢(对应于阶码正溢出)
- 一般浮点溢出指定是上溢(本情况)
- 这种情况需要溢出处理
-
C
(
j
)
=
10
,
⋯
C(j)=10,\cdots
C(j)=10,⋯
- 这种情况是浮点数发生下溢(对应于阶码负溢出)
- 浮点数F被处理为机器零(真值十分接近0)
- 假设阶码用两位符号位表示,那么根据补码的溢出判定方法:
例
- ( x − y ) 补 = 11 , 00 ; 11.011001 其阶符为 11 因此认定为无溢出 x − y = 2 − 3 ⋅ − 0.100111 (x-y)_补=11,00;11.011001 \\其阶符为11 \\因此认定为无溢出 x-y=2^{-3}\cdot{-0.100111} (x−y)补=11,00;11.011001其阶符为11因此认定为无溢出x−y=2−3⋅−0.100111
双符号位浮点数的补码表示范围
- 下面是规格化后的范围(补码)
- 若机器数为补码,尾数为规格化形式
- 并假设:
- 阶符取2位,
- 阶码的数值部分取7位
- 数符取2位
- 尾数的数值部分取n位
- 则它们能表示的补码在数轴上的表示范围
- $ A 最小负数 2^{+127} \times(-1)$
- B 最大正数 2 + 127 × ( 1 − 2 − n ) B 最大正数 2^{+127} \times\left(1-2^{-n}\right) B最大正数2+127×(1−2−n)
- a 最大负数 2 − 128 × ( − 2 − 1 − 2 − n ) a 最大负数 2^{-128} \times\left(-2^{-1}-2^{-n}\right) a最大负数2−128×(−2−1−2−n)
- b 最小正数 2 − 128 × 2 − 1 b 最小正数 \quad 2^{-128} \times 2^{-1} b最小正数2−128×2−1
- 由于四个临界值都是补码形式,对应的真值范围和之前讨论过的真值(非规格化)浮点数范围有所不同
- 可以发现,它们的阶码部分还是对称的!
- 另外,最大的特点在于,补码能够表示的最大负数(对应于上面的指数部分):
- − 2 − n = − 0.0 ⋯ 01 n − 1 个 0 -2^{-n}=-0.0\cdots{01}_{n-1个0} −2−n=−0.0⋯01n−1个0
- − 2 n = − 10 ⋯ 00 n 个 0 -2^{n}=-10\cdots{00}_{n个0} −2n=−10⋯00n个0
- C ( − 2 − n ) = 1.0 ⋯ 0 0 n 个 0 C(-2^{-n})=1.0\cdots{00_{n个0}} C(−2−n)=1.0⋯00n个0
- C ( − 2 n ) = 1 , 0 ⋯ 0 0 n 个 0 C(-2^n)=1,0\cdots00_{n个0} C(−2n)=1,0⋯00n个0
- 也就是说,给定7个数值位,可以表示最大负数为 − 2 7 = − 2 7 -2^{7}=-2^{7} −27=−27
- 并假设:
examples
例(基于补码的例)
-
x = 0.1101 × 2 01 y = ( − 0.1010 ) × 2 11 两个数的阶码和尾数均以补码形式保存 除了基数 2 , 其余数都是二进制形式 2 个浮点数的补码 : ( 为了便于判断溢出 , 阶码和尾数都采用双符号位形式 ) 以分号分割阶码和尾数 ; E 或者 j 表示阶码 ; S 表示尾数 C ( x ) = 00 , 01 ; 00.1101 C ( y ) = 00 , 11 ; 11 , 0110 x=0.1101\times{2^{01}} \\y=(-0.1010)\times{2^{11}} \\两个数的阶码和尾数均以补码形式保存 \\除了基数2,其余数都是二进制形式 \\\\ 2个浮点数的补码:(为了便于判断溢出,阶码和尾数都采用双符号位形式) \\以分号分割阶码和尾数;E或者j表示阶码;S表示尾数 \\C(x)=00,01;00.1101 \\C(y)=00,11;11,0110 x=0.1101×201y=(−0.1010)×211两个数的阶码和尾数均以补码形式保存除了基数2,其余数都是二进制形式2个浮点数的补码:(为了便于判断溢出,阶码和尾数都采用双符号位形式)以分号分割阶码和尾数;E或者j表示阶码;S表示尾数C(x)=00,01;00.1101C(y)=00,11;11,0110
-
对阶
- 阶差 C ( δ ) = C ( E x ) − C ( E y ) = C ( E x ) + C ( − E y ) = 00 , 01 + 11 , 01 = 11 , 10 T ( δ ) = 11 , 01 + 1 = 11 , 10 δ = − 2 计算阶差的真值方法不唯一 ( 直接从给定的 x , y 真值算更快捷 ) 阶差C(\delta)=C(E_x)-C(E_y)=C(E_x)+C(-E_y)=00,01+11,01=11,10 \\T(\delta)=11,01+1=11,10 \\\delta=-2 \\计算阶差的真值方法不唯一(直接从给定的x,y真值算更快捷) 阶差C(δ)=C(Ex)−C(Ey)=C(Ex)+C(−Ey)=00,01+11,01=11,10T(δ)=11,01+1=11,10δ=−2计算阶差的真值方法不唯一(直接从给定的x,y真值算更快捷)
-
真值+浮点数+定点数的转问题
基本规格化问题
十进制数的浮点数和定点数的表示形式示例
基于原码的规格化数(单符号位)
🎈浮点数加减规格化综合
浮点数加减法预处理分析小结
-
由于浮点数尾数的小数点均固定在第一数值位前,所以尾数的加减运算规则与定点数的完.全相同。
-
但由于其
阶码的大小
又直接反映尾数有效值小数点的实际位置
,- 因此当两浮点数阶码不等时,因两尾数小数点的实际位置不一样,尾数部分无法直接进行加减运算。
- 为此,浮点数加减运算必须按以下几步进行
(1) 对阶,使两数的小数点位置对齐。(阶数决定小数点实际位置)
- 对阶的目的是使两操作数的小数点位置对齐,即使两数的阶码相等。
- 为此,首先要求出
阶差
,再按小阶向大阶看齐
的原则,使阶小的尾数
向右移
位,- 每右移一位,阶码加1,直到两数的阶码相等为止。
- 右移的次数正好等于阶差。
- 尾数右移时可能会发生数码丢失,影响精度。
(2) 尾数求和,将对阶后的两尾数按定点加减运算规则求和(差)
(3) 规格化,为增加有效数字的位数,提高运算精度,必须将求和 (差)后的尾数规格化。
(4) 舍入,为提高精度,要考虑尾数右移时丢失的数值位。
(5) 溢出判断, 即判断结果是否溢出
- 设两个浮点数
x = S x ⋅ r j x y = S y ⋅ r j y \begin{array}{l} x=S_{x} \cdot r^{j_{x}} \\ y=S_{y} \cdot r^{j_{y}} \end{array} x=Sx⋅rjxy=Sy⋅rjy
- S为尾数,其余部分为阶数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2022-12-12 CN_@TCP可靠机制@差错控制@流量控制@拥塞控制
2021-12-12 java_Fabonacci斐波那契数列
2021-12-12 CN_TCP_协议分析_wireShark分析报文(reserve+flags)