简单的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);
}
~