16进制浮点数转换

背景

  在IEEE标准754之前,业界并没有一个统一的浮点数标准,相反,很多计算机制造商都设计自己的浮点数规则,以及运算细节。那时,实现的速度和简易性比数字的精确性更受重视。

  直到1985年Intel打算为其的8086微处理器引进一种浮点数协处理器的时候,聪明地意识到,作为设计芯片者的电子工程师和固体物理学家们,也许并不能通过数值分析来选择最合理的浮点数二进制格式。于是Intel在请加州大学伯克利分校的 William Kahan教授──最优秀的数值分析家之一来为8087 FPU设计浮点数格式; 而这个家伙又找来两个专家来协助他,于是就有了KCS组合(Kahn, Coonan, and Stone)。 他们共同完成了Intel的浮点数格式设计,而且完成地如此出色,以致于IEEE组织决定采用一个非常接近KCS的方案作为IEEE的标准浮点格式。目前,几乎所有计算机都支持该标准,大大改善了科学应用程序的可移植性。

浮点数表示

S(符号位) E(指数位) M(有效数字位)
31 (共1位) 30 – 23 (共8位) 22 – 0 (共23位)

浮点数n的公式如下

$$
n=(-1)^s \times m \times 2^e
$$

  • S(sign)表示N的符号位。对应值s满足:n>0时,s=0; n<0时,s=1
  • E(exponent)表示N的指数位,位于S和M之间的若干位。对应值e值也可正可负。
  • M(mantissa)表示N的尾数位,恰好,它位于N末尾。M也叫有效数字位(sinificand)、系数位(coefficient), 甚至被称作“小数”。

计算方式

下面是C语言的计算方式

#include <stdio.h>
#include <math.h>

typedef unsigned long u32;

// 十六进制数转浮点数通用方法
float HexToFloat(unsigned long number)
{
    // 计算符号
    u32 sign = (number & 0x80000000) ? -1 : 1;
    // 计算指数
    u32 exponent = ((number >> 23) & 0xff) - 127;
    // 计算有效数字
    float mantissa = 1 + ((float)(number & 0x7fffff) / 0x7fffff);
    // 组合计算结果
    return sign * mantissa * pow(2, exponent);
}
// 测试用例
int main()
{
    unsigned long a = 0x40490FD0;
    float result = HexToFloat(a);

    printf("结果 = %f \n",result);
    return 0;
}
上一篇
下一篇