Floating point 关于ieee754浮点运算的一个问题

Floating point 关于ieee754浮点运算的一个问题,floating-point,precision,ieee-754,Floating Point,Precision,Ieee 754,我想问一个关于IEEE 754浮点运算的操作问题: (以IEEE 754单精度浮点数为例:1符号位,8指数位,23尾数位) 计算两个浮点数的加减运算时,指数较小的尾数应与指数较大的尾数对齐 也就是说,它取决于两个浮点数之间的指数差来确定尾数的偏移量 我的问题来了:如果指数较小的尾数超出了移位后尾数可以表示的范围 我们应该将超出范围的位一起计算,还是必须丢弃它们 例如: 我想计算两个浮点数的减法 第一个操作数: “0”(符号)10010011(指数)0000 0000 111111111(尾数)

我想问一个关于IEEE 754浮点运算的操作问题:

(以IEEE 754单精度浮点数为例:1符号位,8指数位,23尾数位)

计算两个浮点数的加减运算时,指数较小的尾数应与指数较大的尾数对齐

也就是说,它取决于两个浮点数之间的指数差来确定尾数的偏移量

我的问题来了:如果指数较小的尾数超出了移位后尾数可以表示的范围

我们应该将超出范围的位一起计算,还是必须丢弃它们

例如: 我想计算两个浮点数的减法

第一个操作数: “0”(符号)10010011(指数)0000 0000 111111111(尾数)

第二个操作数: “1”(符号)“10001110”(指数)“0000 0000 011111111”(尾数)

第一个数字的十进制指数为147,第二个数字的十进制指数为142,147-127(偏差)=​​20142-127=15

因此,事实上,上述两个数字可以变成:

第一个操作数:1.0000 1111 111*2^20

第二个操作数:-1.0000 0111 1111 111*2^15

因为第二个数字比第一个数字的幂小5,所以它需要右移5位,那么我的问题是,它会变成:

  • 所有位都是保留的,因此总共需要28位来表示尾数 -0.0000 1000 0000 0011 111“1111”(这五位超过23位)*(2^20)

  • 超过23位后直接截断,所以满足23位意味着尾数 -0.0000 1000 0000 0011111*(2^20)

  • P>添加三位圆形、防护和粘性考虑,因此使用25位表示尾数。 -0.0000 1000 0000 0011 111=>最后两位(位24和位25)是保护位和圆位,并设置S=1(因为最后三个1被切断)


    上述选项中哪一个是正确的,或者没有一个是正确的?

    根据IEEE 754,始终考虑所有位。该操作产生的结果与使用实数算术计算完整结果,然后使用有效的舍入规则对其进行舍入以适应浮点格式的结果相同。(四舍五入到最接近,与偶数低位/数字相连是常见的,但还有其他四舍五入选项,例如始终向上、始终向下、向零,以及始终将任何非零量四舍五入到奇数低位。)

    这并不意味着计算机总是要计算完整的实数结果。对于加法和减法,使用舍入位、保护位和粘性位就足以得到所需的答案。对于其他操作,可能需要更复杂的算法。要求仅仅是计算机必须计算出如果计算出全实数结果并对其进行四舍五入,您将得到什么结果,而实际上不必计算出全实数结果


    (“有效位”是浮点表示法分数部分的首选术语。“尾数”是对数分数部分的旧术语。尾数是对数的;加在尾数上会乘以表示的数字。有效位是线性的;加在有效位上会增加表示的数字。)根据IEEE 754,始终考虑所有位。该操作产生的结果与使用实数算术计算完整结果,然后使用有效的舍入规则对其进行舍入以适应浮点格式的结果相同。(四舍五入到最接近,与偶数低位/数字相连是常见的,但还有其他四舍五入选项,例如始终向上、始终向下、向零,以及始终将任何非零量四舍五入到奇数低位。)

    这并不意味着计算机总是要计算完整的实数结果。对于加法和减法,使用舍入位、保护位和粘性位就足以得到所需的答案。对于其他操作,可能需要更复杂的算法。要求仅仅是计算机必须计算出如果计算出全实数结果并对其进行四舍五入,您将得到什么结果,而实际上不必计算出全实数结果


    (“有效位”是浮点表示法分数部分的首选术语。“尾数”是对数分数部分的旧术语。尾数是对数的;加在尾数上会乘以表示的数字。有效位是线性的;加在有效位上会增加表示的数字。)

    我的(删除的)评论指向了错误的方向

    现在,虽然每个实现都可能受到规范和错误的不正确解释的影响(历史上有很多浮点实现错误,不仅仅是intel一次),但我们可以或可以尝试检查一个实现。(我的电脑)

    从一个操作数1.0开始

    0x3F800000
    
    001111111000...
    0 01111111 000...
    1.0000000 no shift
    
    然后选择一个必须按顺序移动尾数的操作数 进行加法和减法

    0x3BFFFFFF
    
    00111011111111
    0 01110111 11111
    
    这将右移8,所以看看第二个操作数

    0x3BFFFFFF
    
      1.000000000000000...00 0000...
    + 0.000000011111111...11 1111...
    ==============================
      1.000000011111111...11
    
      1.000000000000000...00 0000...
    - 0.000000011111111...11 1111...
    ==============================
      1.111111100000000...00
    
    0x3BFFFF00  
    
      1.000000000000000...00 0000...
    + 0.000000011111111...11 0000...
    ==============================
      1.000000011111111...11
    
      1.000000000000000...00 0000...
    - 0.000000011111111...11 0000...
    ==============================
      1.111111100000000...10
    
    0x3BFFFF80  
    
      1.000000000000000...00 0000...
    + 0.000000011111111...11 1000...
    ==============================
      1.000000011111111...11
    
      1.000000000000000...00 0000...
    - 0.000000011111111...11 1000...
    ==============================
      1.111111100000000...01
    
    0x3BFFFFC0  
    
      1.000000000000000...00 0000...
    + 0.000000011111111...11 1100...
    ==============================
      1.000000011111111...11
    
      1.000000000000000...00 0000...
    - 0.000000011111111...11 1100...
    ==============================
      1.111111100000000...00
    
    0x3BFFFF01  
    
      1.000000000000000...00 00000000
    + 0.000000011111111...11 00000001
    =================================
      1.000000011111111...11
    
      1.000000000000000...00 00000000
    - 0.000000011111111...11 00000000
    =================================
      1.111111100000000...00 00000001
    
    对于加法(不四舍五入),需要填充未移位的基数(用零)。所以尾数的末尾有两位

    0+0 = 0 carry 0
    0+1 = 1 carry 0
    
    您不能在尾数后的第一位(粘滞位)进行携带。所以对于加法,并没有理由在第一位之后增加逻辑,但需要第一位进行舍入。只需要一点点就可以圆

    虽然你可以看减法
    0x3BFFFF80
    
      1.000000000000000...00 0000...
    - 0.000000011111111...11 1000...
    ==============================
      1.111111100000000...01
    
                                    1
      1.000000000000000...00 00000000
    + 1.111111100000000...00 01111111
    ====================================
     10.111111100000000...00 10000000
    hardware gives
      1.111111100000000...01
    
    0x3BFFFF80  
    
      1.000000000000000...00 0000...
    - 0.000000011111111...11 1000...
    ==============================
      1.111111100000000...01
    
    0x3BFFFFC0  
    
      1.000000000000000...00 0000...
    - 0.000000011111111...11 1100...
    ==============================
      1.111111100000000...00
    
                                    1
      1.000000000000000...00 00000000
    + ?.111111100000000...00 00111111
    =================================
    
                              1111111
      1.000000000000000...00 00000000
    + ?.111111100000000...00 00111111
    =================================
      1.111111100000000...00 01000000
    hardware gives
      1.111111100000000...00