浮点加减运算中关于结果规格化的思考

本文详细介绍了浮点数加减法的过程,包括操作数检查、对阶、尾数加减及结果规格化等步骤,并通过具体例子展示了如何进行规格化处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于两个浮点数x和y满足:
在这里插入图片描述
完成x与y的加减法有四个步骤:

  1. 0操作数检查。即检查是否有一个操作数为0,是的话直接得到结果,一般在计算机中不进行这一步。
  2. 比较阶码大小并完成对阶。要让两个浮点数的尾数能够直接相加减,它们的阶码也就是Mx和MyM_{x}和M_{y}MxMy必须相同,因此必须完成对阶,一般是让小阶向大阶看齐。
  3. 尾数进行加减运算。方法与定点加减运算完全一致,没有什么好说的。
  4. 结果规格化。这一步是重点,也是难点。
    要想知道怎么规格化,肯定得知道什么才是规范的表达方式。浮点数都是近似表示的,精度由尾数决定,数的表示范围大小由R、E决定。为了提高精度需要使尾数的有效位数尽可能占满可用的位数。这种措施称为浮点数的规格化。规格化要求尾数:
              1/R<=|M|<1

    计算机中R = 2,因此实际上我们计算出来得到的尾数必须属于[0.5, 1)。

在浮点数加减运算时,我们采用双符号位,因此,当计算结果为01.XXXX或者10.XXXX时,表示结果溢出,已经大于1了,因此需要规格化。
下面举个具体的例子:
m=22X0.11011011,n=24X(−0.10101100)m = 2^{2}X0.11011011,n = 2^{4}X(-0.10101100)m=22X0.11011011n=24X(0.10101100),求m+n。
逐步分析:

  • 0操作数检查。m和n都不为0。
  • 对阶。小阶2向大阶4对齐,所以m的阶数加2,相应地,m的尾数右移(小数点左移,尾数变小)两位:m=24X0.00110110(11)m = 2^{4}X0.00110110(11)m=24X0.00110110(11),而n保持不变。
  • 由于要进行补码运算,所以将m和n的尾数变成补码表示(双符号位):
    m=24X00.00110110(11),n=24X11.01010100m = 2^{4}X00.00110110(11),n = 2^{4}X11.01010100m=24X00.00110110(11)n=24X11.01010100,其中11.01010100=11.01010011+1(取反再加1)。接下来将尾数相加:
    在这里插入图片描述
    可以看到并未溢出,但是并不一定满足大于0.5, 我们将其转成原码很容易发现第一位为0,也就是说是小于0.5的,必须规格化,由此我们总结出要规格化的几种情形:
  • 若尾数为00.0XXX或者11.1XXX,虽然并未溢出,但是并不满足大于0.5,因此也必须要规格化,由于尾数要变大,阶码变小,即尾数左移(小数点右移),称之为向左规格化,使之最终变成00.1XXXX或者11.0XXXX。
  • 若尾数为10.XXXX或者01.XXXX表明运算结果溢出,必须使尾数变小,阶码变大,尾数右移(小数点左移),称之为向右规格化。
  • 针对例子中的情况,需要进行向左规格化,最终变成:
        m+n=11.00010101(10)X23m + n = 11.00010101(10)X2^{3}m+n=11.00010101(10)X23
  • 将尾数进行舍入处理,最后为10直接加1,变成11.00010110,所以换成原码的尾数为00.11101010,即最终有:
        m+n=0.11101010X2011m + n = 0.11101010X2^{011}m+n=0.11101010X2011
感谢您提供的上下文信息。根据您提供的信息,这段代码的作用是在浮点加法运算器中进行浮点数规格化(normalize)操作。下面是对这段代码的分析: 首先,这段代码包含了一个 if-else 语句。条件判断语句的判断条件是 `sign_big == sign_small && tmp_mant_sum[24]`,其中 `sign_big` 和 `sign_small` 分别表示两个操作数的符号位,`tmp_mant_sum[24]` 表示两个操作数相加后的尾数位是否有进位。如果条件成立,则执行 if 语句后面的代码,否则执行 else 语句后面的代码。 在 if 语句后面的代码中,首先将计数器 `counter` 赋值为 5 个 0。然后将 `tmp_mant_sum` 右移一位,并将右移后的值赋给 `tmp_mant_done[23:0]`。接着将 `tmp_mant_done[23]` 赋值为 1,表示尾数位的最高位已经规格化。最后将 `exp_big` 加 1,表示指数位也需要相应地增加 1。 在 else 语句后面的代码中,首先将计数器 `counter` 赋值为 5 个 0。接着进入一个 while 循环,判断 `tmp_mant_sum[23]` 是否为 0,并且计数器 `counter` 是否小于 24。如果条件成立,则将 `tmp_mant_sum` 左移一位,并将左移后的值赋给 `tmp_mant_done[23:0]`,并将计数器 `counter` 加 1。循环结束后,尾数位的最高位已经被规格化,然后将 `tmp_mant_done[23:0]` 赋值为 `tmp_mant_sum[23:0]`。 综上所述,这段代码的作用是规格化浮点数,使得尾数位的最高位为 1,同时相应地调整指数位的值。这个操作是浮点加法运算器中非常重要的一步,可以保证加法的精度和正确性。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cyril_KI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值