C/C++ 16进制转IEEE754

转载地址:单片机

将(32位)16进制IEEE-754标准浮点数就是用十六进制表示浮点,称为单精度浮点数。
举例:已知一个数为2.5,IEEE-754标准浮点数表示为 40200000H。
16进制浮点数与十进制的转化步骤:
对于大小为32-bit的浮点数(32-bit为单精度,64-bit浮点数为双精度,80-bit为扩展精度浮点数),
1、其第31 bit为符号位,为0则表示正数,反之为复数,其读数值用s表示;
2、第30~23 bit为幂数,其读数值用e表示;
3、第22~0 bit共23 bit作为系数,视为二进制纯小数,假定该小数的十进制值为x;
则按照规定,该浮点数的值用十进制表示为:= (-1)^s * (1 + x) * 2^(e - 127)

例如:对于16进制浮点数49E48E68H来说,
1、其第31 bit为符号位,为0则表示为正数;
2、第30~23 bit依次为100 1001 1,读成十进制就是147,即e = 147。
3、第22~0 bit依次为110 0100 1000 1110 0110 1000,也就是二进制的纯小数0.110 0100 1000 1110 0110 1000,其十进制形式为0.78559589385986328125,即x = 0.78559589385986328125。即x = 0.78559589385986328125。

可知:16进制浮点数49E48E68H的10进制表示:
=(-1)^s * (1 + x) * 2^(e - 127)
=(-1)^0 * (1+ 0.78559589385986328125) * 2^(147-127) = 1872333。
 

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
float hextofloat (unsigned int number) 
{
    //符号位
    unsigned int sign = number >>31;
    //幂数
    int exponent = ((number >> 23) & 0xff) - 0x7F;
    //尾数
    unsigned int mantissa = number << 9; 
    float value = 0; 
    float mantissa2;
    value = 0.5f;
    mantissa2 = 0.0f; 
    while (mantissa) 
    {
        if (mantissa & 0x80000000) 
            mantissa2 += value; 
        mantissa <<= 1; 
        value *= 0.5f; 
    }
    value = (1.0f + mantissa2) * (pow (2, exponent)); 
    if (sign) value = -value;
    return value; 
}

int main() 
{
    unsigned int a=0x42CA3F44;
    float ans=hextofloat (a); 
    printf("%.3f\n",ans);
    return 0;
}

### 将16进制数值换为IEEE 754标准的浮点数 对于将16进制数值换成IEEE 754单精度或双精度浮点数的过程,可以分为几个部分来理解。 #### 解析16进制字符串并提取位模式 给定一个16进制字符串表示的浮点数,首先需要解析该字符串并将它化为对应的二进制形式。例如,假设有一个代表单精度浮点数的16进制串`0x42F90000`: ```cpp unsigned int hexValue = strtoul("42F90000", NULL, 16); ``` 这一步骤会得到一个整型变量保存着原始数据流中的比特序列[^1]。 #### 提取符号(S)、指数(E)以及尾数(M) 接着按照IEEE 754的规定拆分这些比特位: - **符号位 (S)**: 最高位决定数值是正是负(0为正,1为负) - **指数偏移量 (E')**: 对于单精度来说是从第8到第31位共8位;而对于双精度则是从第12至第63位共11位。实际使用的指数值等于读取出的无符号整数减去特定偏置(单精度情况下为127,双精度则为1023)[^2]. - **尾数 (M)** 或者称为分数部分,在单精度中占据剩下的23位而双精度占有52位。需要注意的是这里隐含了一个前导'1.'因此实际上有效长度更长一些[^3]. #### 计算最终浮点数值 有了上述三个组成部分之后就可以通过下面公式计算出真正的浮点数值\(V\): \[ V=(-1)^{S}\times2^{(E'-Bias)}\times M \] 其中\( Bias\) 是指针对不同类型的浮点数所设定的不同偏置值。 下面是具体的C++实现代码用于展示这一过程: ```cpp #include <iostream> #include <cmath> union FloatBits { float f; unsigned long ul; }; float HexToFloat(const char* hexStr){ union FloatBits fb; fb.ul = strtoul(hexStr, nullptr, 16); // Convert from hexadecimal string to bit pattern bool signBit = ((fb.ul >> 31) & 0x1); // Extract the sign bit. int exponent = static_cast<int>((fb.ul >> 23) & 0xFF); // Get biased exponent bits and convert them into an integer value. double mantissa = 1 + ((fb.ul & 0x7FFFFF)/pow(2.,23)); // Calculate normalized significand. if(exponent == 0 && mantissa == 1){ // Special case for zero or denormalized numbers not covered here. return 0.f; } exponent -= 127; // Unbiasing the exponent by subtracting bias of single precision format which is 127. return pow(-1,signBit)*mantissa*pow(2,exponent); // Compute final floating point number according to IEEE 754 standard formula. } int main(){ const char *hexString="42f90000"; std::cout << "The decimal representation of " << hexString << " as a float is : " << HexToFloat(hexString)<<std::endl; return 0; } ``` 这段程序展示了如何将指定的16进制字符串解释为遵循IEEE 754标准的单精度浮点数,并打印其十进制表示形式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值