浮点数的加法运算

浮点数的IEEE 754的表示方式在之前的帖子中已经总结了,此处描述浮点数的加法是如何做的;
浮点数的加法,主要分成如下几个步骤:

  •  零操作数检查;
  •  对阶;
  •  尾数相加;
  •  规格化;
  •  舍入处理;
  •  阶码溢出判断;

下面针对每个阶段,做详细的描述,以及为什么这样做,以单精度浮点数为例;
        x=2001×(0.1101),y=2011×(-0.1010), 求x+y;

  • 零操作数检查;
    • 此处其实就是特殊值,优先处理而已,因为0和其他值相加,都等于其他值,所以拿出来单独处理下;
    • 如果某个源操作数是0,则相加的和,就是另一个操作数;
  • 对阶
    o 何为对阶?
            所谓对阶,以10进制为例,一个数是1.2 x 10^3, 一个数是1.5 x 10^5, 这两个数相加;
    从数学中可以得知,这两个数都转换成一个幂次,则加法只需要将幂次前面的数据相加即可,即:
     1.2 x 10^3 + 1.5 x 10^5 = 0.012 x 10^5 + 1.5 x 10^5 = 1.512  x 10^5;
    这样,可以很轻松的得出结果;

         在2进制中也是一样的道理,不同阶乘的数据相加,也需要先对阶;

  • 采用的方式是小阶对大阶;
    1. 为什么?
         -------因为如果大阶对小阶,那么就需要将数据左移,很可能会将高位的数据给以掉,这样会引发数据的错误;
          -------而小阶对大阶,数据右移,丢失的是最右侧的数据,是最小的,只会影响数据的精度,不会影响数据的大小;

        2. 对阶方式:

        ----首先,数据的阶码位和尾数位,都需要转换成补码,这个比较好理解,计算机看不到有无符号数,只是对补码进行计算;

        ----假设上述的x,y,都是补码,则x的阶码为:001, y的阶码为:011;

        ----此处,我们采用双符号位的表示方式,即在数据的高2bit, 都是符号位:00 001, 00 011;

        ----为什么要用双符号位?---因为可以通过符号位的变化,判断是否有溢出;

        

       ------具体可以看这个帖子:溢出以及判断溢出的两种方法(单符号位和双符号位)_一位符号位判断溢出-CSDN博客

        3. 判断谁大谁小,小阶对大阶,则y-x = 00 011 - 00 001 = 00 010 = 2, 所以x的阶码需要+2,尾数右移动;
            ----x = 2001×(0.1101) = 2011×(0.001101), 删除线代表该2bit被移出;

  • 尾数求和

        此时阶数已经对齐,此处我们对尾数部分进行求和,同样的道理,都是补码,也采用双符号位的做法;

        M(x) = 0011 = 00 0011, M(y) = 1010, 因为是负数,所以M(y)= 11 1010;

        M(x) + M(y) = 00 0011 + 11 1010 = 11 1101; 

  • 规格化;

        1. 什么是规格化?

       ------在科学计数法中,考虑这样一个数:0.003 x 10^3, 是不是觉得前面的数很没有必要?明明那么小,还要使用这种高阶的方式;
       ------那么,我们将其转换成:0.3 x 10^1, 这样可以在有限的位数上,表示更多的数据;
       ------同样,对于2进制,也是一样的道理,浮点数规格化的公式为:V = (-1)^s *(1+M)* 2^(E-127)(单精度),其中(1+M)中的1为默认添加的;
       ------因此,我们计算出数据后,还需要进行规格化,也就是尾数的最高位,需要是一个有效值,对于正数,最高位需要是1, 对于负数,最高位需要是0;

    

        可以参考该文档:【细碎知识1】浮点数的规格化_浮点数规格化-CSDN博客

        ----可以进一步推出,对于补码而言:
                 ● 符号位是00,11,说明没有溢出;
                 ● 符号位是01,10,则表示有溢出;
                         ● 第一个比较好理解,00,11说明没溢出;
                         ● 符号位是01,则是正溢出;
                         ● 符号位是10,说是负溢出,说明两个负数相加,为什么会出现10的场景?
                         ● 比如11 010 + 11 100 = 10 110;此时010+100,明明没有溢出,为什么判断是溢出呢??
                         ● 原因是,此处是补码!!,这个就是最基本的原因,如果是源码,则判断方式又要相反了,这个在前面判断溢出的帖子中有部分描述;

       ------基于上面的尾数结果,发现符号位11,数据最高位1;
                 ● 什么情况下左规?---可能会多次左规;
                         ● 当符号位和最高位不是如下两种场景时,需要左规,左规阶码-1;
                                 ● 00.1xxxxx, 这种方式不需要左规,已经是规格化的表达方式;
                                 ● 11.0xxxxx, 这种方式不需要左规;(为什么是0? 因为这里是补码~)
                 ● 什么情况下右规?
                         ● 当两个符号位不同时,需要右规;右规阶码+1;----可能会多次右规;
                                 ● 例如,01.xxxx和10.xxxx的两个符号位不相同,需要进行右归。
                                 ● 01.xxxx右移一位结果为00.1xxx,阶码加1;
                                 ● 10.xxxx右移一位结果为11.0xxx,阶码加1;
                                 ● 此处注意,有规高位是补充0,还是1,是看之前的最高位;
                                 ● 右规后,尾数最低位会移出;

  •  舍入处理;

        在对阶向右规格化时,尾数都要进行算术右移操作,为了保证运算结果的精度,运算过程中需保留右移中移出的若干位数据,称为保护位。在运算结果进行规格化后再按照某种规则进行舍入处理以去除这些数据。舍入处理就是消除保护位数据并按照某种规则调整剩下的部分,舍入处理总要影响到数据的精度。

       ● 截断法;
          ---直接将右移的尾数低位丢弃;
       ●末位恒1法;
          ---不管右移丢弃的是0还是1, 都直接将尾数最低为设置位1;
       ●0舍1入法
          ---此方法类似于十进制的四舍五入法,即在尾数右移时,被移去的最高数值位为0,则舍去。
          ---被移去的最高数值位为1,则在尾数末尾加1.这样做可能使尾数又溢出,此时需要再做一次右规。
          ---例子:浮点加减运算之0舍1入法与恒置1法_0舍1入法怎么用-CSDN博客

  •  阶码溢出判断;

       ● 判断阶码的双符号位是否相同,相同则无溢出,否则,溢出;
       ● 阶码上溢,一般将其认为是+无穷和一无穷。阶码下溢,则数值为0。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。针对你的问题: (1) 将 A、B 表示为规格化浮点数形式 首先,我们需要将 A、B 转换为二进制数。A 的二进制表示为 1.111,B 的二进制表示为 -10.01。 接下来,我们需要将 A、B 转换为规格化浮点数形式。规格化浮点数形式的特点是尾数的最高位为 1,阶码需要根据科学计数法的规则来计算。 对于 A,我们把它写成科学计数法的形式:1.111 = 1.111 * 2^0。因此,A 的阶码为 0,尾数为 11100000。 对于 B,我们把它写成科学计数法的形式:-10.01 = -1.001 * 2^1。因此,B 的阶码为 1,尾数为 00100000。 因此,A 的规格化浮点数形式为 0 0000 0001 11100000,B 的规格化浮点数形式为 1 0000 0010 00100000。 (2) 实现浮点数加法运算 A+B,并写出用二进制编码表示的运算结果 在进行浮点数加法运算之前,我们需要将两个浮点数的阶码对齐。由于 A 的阶码为 0,B 的阶码为 1,我们需要将 A 的阶码加 1,即将 A 的尾数左移一位。 将 A 的尾数左移一位后,A 的规格化浮点数形式为 0 0000 0001 11000000。 现在,我们可以将 A 和 B 相加了。首先,我们需要确定两个浮点数的符号位。由于 A 和 B 的符号位都为 0,因此它们的和的符号位也为 0。 接下来,我们需要将 A 和 B 的尾数相加。由于 A 和 B 的阶码已经对齐,我们可以直接将它们的尾数相加。在相加时,我们需要将尾数右移一位,以便将进位加到阶码上。具体的计算过程如下: ``` 0 0000 0001 11000000 A +1 0000 0010 00100000 B ------------------ 1 0000 0010 11100000 和 ``` 接下来,我们需要将和的阶码计算出来。由于 A 和 B 的阶码已经对齐,因此和的阶码也等于 A 和 B 的阶码。在本例中,和的阶码为 1。 最后,我们需要对和的尾数进行规格化,即将尾数最高位的 1 移动到尾数的最高位。在本例中,和的尾数已经是规格化的了。 因此,A+B 的规格化浮点数形式为 0 0000 0010 11100000,转换为十进制数为 0.625。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值