C++单、双精度浮点数16进制转10进制原理及代码

一、浮点数16进制转10进制原理

浮点数有两种:单精度float(4字节) 和 双精度double(8字节)。

1、单精度结构表

符号位 Sign (S)指数部分 Exponent (E)尾数部分 Mantissa (M)
3130 ~ 2322 ~ 0
1bit8bit

23bit

2、双精度结构表

符号位 Sign (S)指数部分 Exponent (E)尾数部分 Mantissa (M)
6362 ~ 5251 ~ 0
1bit11bit

52bit

3、浮点数 16进制转10进制原理

公式: \LARGE V = (-1)^{s}*M*2^{E}

(1)、 (-1)^S表示符号位,当S=0,V为正,S=1,V为负。

(2)、 M表示有效数字,大于等于1,小于2。.

        单精度 M = 尾数部分十进制 * 2^(-23) + 1;

        双精度 M = 尾数部分十进制 * 2^(-52) + 1。

(3)、 E表示指数数部分。

        单精度 E = 指数部分十进制 - 127;

        双精度 E = 指数部分十进制 - 1023;

(4)、单精度浮点数16进制转10进制,例(42A54FCC):

十六进制

42 A5 4F CC

二进制01000010 10100101 01001111 11001100 
符号位(S)0
指数部分10000101(十进制:133)
尾数部分0100101 01001111 11001100(十进制:2445260)
M 计算M = 2^(-23) * 2445260 + 1 = 1.291497707366943359
2^E 计算2^E = 2^(133 - 127) = 2^6 = 64
十进制计算 VV = (-1)^S * M * 2^E = 1 * 1.291497707366943359 * 64
十进制结果 V82.65585327148437498

        ·双精度浮点数计算方式同理。

二、代码

代码在Qt上编译的,没有Qt可以将QByteArray替换为unsigned  char*类型。

#include <QtCore/QCoreApplication>
#include <QDebug>

/*单精度浮点数(32位) 16进制转10进制*/
double hex32_10(QByteArray byteDate) {
    char* pData = byteDate.data();
    //符号位 1
    int sign = int(pData[0] >> 7);
    //指数位 8
    int e = int(((pData[0] & 0x7F) << 1) | ((pData[1] >> 7) & 0x01)) - 127;
    //小数位 23
    int im = pData[3] & 0xFF;
    im |= (pData[2] << 8) & 0xFF00;
    im |= (pData[1] << 16) & 0x7F0000;
    double m = pow(2, -23) * im + 1;
    double res = pow(-1, sign) * m * pow(2, e);
    qDebug() << byteDate.toHex() << QString::number(res, 'f', 12);
    return res;
}

/*双精度浮点数(64位) 16进制转10进制*/
double hex64_10(QByteArray byteDate) {
    char* pData = byteDate.data();
    //符号位  1位
    int sign = int(pData[0] >> 7);
    //指数位  11位
    int e = int(((pData[0] & 0x7F) << 4) & 0x0FF0 | (pData[1] & 0xF0) >> 4) - 1023;
    //小数位  52位
    double  m = pow(2, -52) * 
        (pow(256, 6) * double(pData[1] & 0x0F) +
         pow(256, 5) * double(pData[2]) +
         pow(256, 4) * double(pData[3]) +
         pow(256, 3) * double(pData[4]) +
         pow(256, 2) * double(pData[5]) +
         256 * double(pData[6]) +
         double(pData[7])) + 1;
    double res = pow(-1, sign) * m * pow(2, e);
    qDebug() << byteDate.toHex() << QString::number(res, 'f', 24);
    return res;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QByteArray byteArray_0;
    byteArray_0.resize(4);
    byteArray_0[0] = 0x42;
    byteArray_0[1] = 0xA5;
    byteArray_0[2] = 0x4F;
    byteArray_0[3] = 0xCC;
    hex32_10(byteArray_0);

    QByteArray byteArray;
    byteArray.resize(8);
    byteArray[0] = 0x42;
    byteArray[1] = 0xA5;
    byteArray[2] = 0x4F;
    byteArray[3] = 0xCC;
    byteArray[4] = 0xBB;
    byteArray[5] = 0xA8;
    byteArray[6] = 0xD2;
    byteArray[7] = 0xC5;
    hex64_10(byteArray);

    return a.exec();
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

源客V

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值