cornsea

简单的ieee754单精度浮点数加法实现

ieee754单精度浮点数的格式如下:

31     30         23 22                                    0

Sign |   exponent   |             fraction                  |

如果 0 < exponent < 0xff, 那这个就是规范normalized number.

  value = -1**S X 2 **(exponent - 127) X (1.fraction)

 

考虑简单的情况,计算两个单精度浮点数的基本过程如下:

1. 把两个浮点数的指数对齐,就是把指数变换为其中较大的一个

2. 取mantissa的和

3. 处理结果(rounding, error之类的处理)

 

c语言例子如下:

#include <stdio.h>

 

float a = 2.4;
float b = 3.5;

// simple ieee 754 single precision float number
// addition arithmetic.
// format:
// S  E   F
// 1  8   23
float test1(float a, float b)
{
        float c = 0;
        unsigned int p1 = *((unsigned int *) &a);
        unsigned int p2 = *((unsigned int *) &b);

        // compute exponent difference
        // essentially, we must let two number's exponent be same
        int e1 = (p1 << 1) >> 24;
        int e2 = (p2 << 1) >> 24;
        int diff = e1 - e2;

        if (diff < 0) {
                diff = 0 - diff;
                p2 = p1 ^ p2;
                p1 = p1 ^ p2;
                p2 = p1 ^ p2;
                e1 = e2;
        }
        //convert mantissa to signed integer

        // there is a hidden bit
        //:) i do not want to handle minus number here
        //
        int p3 = p1 | 0x00800000;
        p3 = p3 & 0x00ffffff;
        int p4 = p2 | 0x00800000;
        p4 = p4 & 0x00ffffff;
        //mantissa should be shift right according to difference of
        //exponent.
        unsigned int result = p3 + (p4 >> diff);
        if (result > 0x00800000) {
                result = result >> 1;
        }
        // combination
        result = result | (e1 << 23);
        c = *((float *)&result);
        return c;
}

int main(void)
{
        float c = test1(a, b);
        printf("%x, %x, %x, %f\n", *((int *)&a), *((int *)&b), *((int *)&c), c);
}
~                    

posted on 2010-09-18 19:48  cornsea  阅读(2649)  评论(0编辑  收藏  举报

导航