代码之家  ›  专栏  ›  技术社区  ›  user2913869

二进制浮点加法算法

  •  2
  • user2913869  · 技术社区  · 8 年前

    我试着在二进制级别理解IEEE 754浮点加法。我遵循了一些我在网上找到的示例算法,大量的测试用例与一个经过验证的软件实现相匹配。我的算法目前只处理正数。但是,我没有得到与此测试用例匹配的结果:

    00001000111100110110010010011100 (1.46487e-33)
    00000000000011000111111010000100 (1.14741e-39)
    

    我把它分成符号位,指数,尾数。我在尾数后面加上隐含的1

    0 00010001 1.11100110110010010011100
    0 00000000 1.00011000111111010000100
    

    我从较小的指数中减去较大的指数,以确定重新校准移位量:

     00010001 (17)
    -00000000 (0)
     =============
               17
    

    我在尾数上加了一个护卫位、一个圆形位和一个粘性位:

    1.11100110110010010011100 000
    1.00011000111111010000100 000
    

    我将较小值的尾数向右移动17次,LSb一旦收到1:

    0.00000000000000001000110 001
    

    我把大尾数加在移动的小尾数上:

    1.11100110110010010011100 000 +
    0.00000000000000001000110 001
    ================================
    1.11100110110010011100010 001
    

    由于没有溢出,并且保护位是0,所以我可以直接使用求和尾数和更大的指数(重新删除隐式“1”):

    0 00010001 11100110110010011100010
    

    给出最终值:

    00001000111100110110010011100010 (1.46487e-33)
    

    但根据我的验证实施,我应该得到:

    00001000111100110110010010101000 (1.46487e-33)
    

    如此接近,但并不确切。我的算法有错误吗?

    1 回复  |  直到 8 年前
        1
  •  2
  •   chux    8 年前

    在计算中似乎有两个问题,都与将一个低于正常值的数字视为正常值有关:

    1. 换档计算不正确。指数是-126,不是-127。
    2. 在二进制点之前错误地插入一位。

    以下是修改后的计算:

    0 00010001 1.11100110110010010011100
    0 00000000 0.00011000111111010000100
    

    在尾数上钉上一个保护位、圆形位和粘性位:

    1.11100110110010010011100 000
    0.00011000111111010000100 000
    

    较小数字的16位右移。

    0.00000000000000000001100 001
    

    将较大尾数添加到移动的较小尾数:

    1.11100110110010010011100 000 +
    0.00000000000000000001100 001
    ================================
    1.11100110110010010101000 001