一、浮点数16进制转10进制原理
浮点数有两种:单精度float(4字节) 和 双精度double(8字节)。
1、单精度结构表
符号位 Sign (S) | 指数部分 Exponent (E) | 尾数部分 Mantissa (M) |
---|---|---|
31 | 30 ~ 23 | 22 ~ 0 |
1bit | 8bit | 23bit |
2、双精度结构表
符号位 Sign (S) | 指数部分 Exponent (E) | 尾数部分 Mantissa (M) |
---|---|---|
63 | 62 ~ 52 | 51 ~ 0 |
1bit | 11bit | 52bit |
3、浮点数 16进制转10进制原理
公式:
(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 |
十进制计算 V | V = (-1)^S * M * 2^E = 1 * 1.291497707366943359 * 64 |
十进制结果 V | 82.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();
}