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} xmxn
      • 那么根据 x m x_m xm:
        • 如果 x m = 1 x_m=1 xm=1则+1(入)
        • 否则+0
  • 假设某个求和结果 : ( 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 假设某个求和结果:(xy)=11,00;10.110001根据双符号位的性质,上述结果是一个溢出(负溢出)需要进行右归(xy)=11,00;11.011000 1(注意,溢出的双符号位在右移时,只有低位参与右移,并将缺失的低位符号用高位符号补位,得到不溢出的结果)现在发现被右移操作移出去的(最高)bit1,于是根据01,对其进行末尾数码+1处理+11.011000111.011001所以(xy)=11,00;11.011001

溢出判断

  • 舍入操作中的:舍0入1法可能会执行尾码加1操作
    • 这可能引发连续进位导致溢出
    • 因此,舍入后可能还要在判断溢出
      • 如果发现溢出,需要重新规格化(右归)(而不会是左归)
    • 规格化可以消除尾数部分的溢出(可以称为伪溢出)现象
    • 当规格化完成后,在看看阶码是否处在合理的范围内
  • 浮点数的溢出更重要的是规格化尾数后的阶码是否溢出
    • 假设阶码用两位符号位表示,那么根据补码的溢出判定方法:
      • 浮点数 F = 2 j ⋅ S F=2^{j}\cdot{S} F=2jS
      • 阶码(指数)的补码 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} (xy)=11,00;11.011001其阶符为11因此认定为无溢出xy=230.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×(12n)
      • a 最大负数 2 − 128 × ( − 2 − 1 − 2 − n ) a 最大负数 2^{-128} \times\left(-2^{-1}-2^{-n}\right) a最大负数2128×(212n)
      • b 最小正数 2 − 128 × 2 − 1 b 最小正数 \quad 2^{-128} \times 2^{-1} b最小正数2128×21
    • 由于四个临界值都是补码形式,对应的真值范围和之前讨论过的真值(非规格化)浮点数范围有所不同
      • 可以发现,它们的阶码部分还是对称的!
      • 另外,最大的特点在于,补码能够表示的最大负数(对应于上面的指数部分):
        • − 2 − n = − 0.0 ⋯ 01 n − 1 个 0 -2^{-n}=-0.0\cdots{01}_{n-1个0} 2n=0.001n10
        • − 2 n = − 10 ⋯ 00 n 个 0 -2^{n}=-10\cdots{00}_{n个0} 2n=1000n0
        • C ( − 2 − n ) = 1.0 ⋯ 0 0 n 个 0 C(-2^{-n})=1.0\cdots{00_{n个0}} C(2n)=1.000n0
        • C ( − 2 n ) = 1 , 0 ⋯ 0 0 n 个 0 C(-2^n)=1,0\cdots00_{n个0} C(2n)=1,000n0
        • 也就是说,给定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真值算更快捷)

真值+浮点数+定点数的转问题

基本规格化问题

1646305647184

十进制数的浮点数和定点数的表示形式示例

基于原码的规格化数(单符号位)

1646306839531

🎈浮点数加减规格化综合

浮点数加减法预处理分析小结

  • 由于浮点数尾数的小数点均固定在第一数值位前,所以尾数的加减运算规则与定点数的完.全相同。

  • 但由于其阶码的大小又直接反映尾数有效值小数点的实际位置,

    • 因此当两浮点数阶码不等时,因两尾数小数点的实际位置不一样,尾数部分无法直接进行加减运算。
    • 为此,浮点数加减运算必须按以下几步进行

(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=Sxrjxy=Syrjy

  • S为尾数,其余部分为阶数

浮点数加法例

1646383935018

1646383975809

浮点数减法示例

1646393929643

1646393966485

posted @   xuchaoxin1375  阅读(10)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享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)
点击右上角即可分享
微信分享提示