最近在做一些接收机的数据处理,需要将16进制数据转换为需要的数据,其中需要将64位的十六进制数转化为浮点数,查看了下浮点数存储的标准IEEE754标准 ,将其进行解析,可以直接通过串口接收的数据进行解析。
双精度(64位)浮点数的结构
名称 长度 比特位置
符号位 Sign (S) : 1bit (b63)
指数部分Exponent(E) : 11bit (b62-b52)
尾数部分Mantissa (M) : 52bit (b51-b0)
双精度的指数部分(E)采用的偏置码为1023
双精度(64位)浮点数的结构
名称 长度 比特位置
符号位 Sign (S) : 1bit (b63)
指数部分Exponent(E) : 11bit (b62-b52)
尾数部分Mantissa (M) : 52bit (b51-b0)
双精度的指数部分(E)采用的偏置码为1023
求值方法:(-1)^S*(1.M)*2^(E-1023)
//64位16进制转十进制浮点数测试程序
#include "stdafx.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
char fltable[][65] = {
"0000000000000000000000000000000000000000000000000000000000000000", /* (Zero) */
"5000000000000000000000000000000000000000000000000000000000000000", /* (2^-1) */
"2500000000000000000000000000000000000000000000000000000000000000", /* (2^-2) */
"1250000000000000000000000000000000000000000000000000000000000000", /* (2^-3) */
"0625000000000000000000000000000000000000000000000000000000000000", /* (2^-4) */
"0312500000000000000000000000000000000000000000000000000000000000", /* (2^-5) */
"0156250000000000000000000000000000000000000000000000000000000000", /* (2^-6) */
"0078125000000000000000000000000000000000000000000000000000000000", /* (2^-7) */
"0039062500000000000000000000000000000000000000000000000000000000", /* (2^-8) */
"0019531250000000000000000000000000000000000000000000000000000000", /* (2^-9) */
"0009765625000000000000000000000000000000000000000000000000000000", /* (2^-10) */
"0004882812500000000000000000000000000000000000000000000000000000", /* (2^-11) */
"0002441406250000000000000000000000000000000000000000000000000000", /* (2^-12) */
"0001220703125000000000000000000000000000000000000000000000000000", /* (2^-13) */
"0000610351562500000000000000000000000000000000000000000000000000", /* (2^-14) */
"0000305175781250000000000000000000000000000000000000000000000000", /* (2^-15) */
"0000152587890625000000000000000000000000000000000000000000000000", /* (2^-16) */
"0000076293945312500000000000000000000000000000000000000000000000", /* (2^-17) */
"0000038146972656250000000000000000000000000000000000000000000000", /* (2^-18) */
"0000019073486328125000000000000000000000000000000000000000000000", /* (2^-19) */
"0000009536743164062500000000000000000000000000000000000000000000", /* (2^-20) */
"0000004768371582031250000000000000000000000000000000000000000000", /* (2^-21) */
"0000002384185791015625000000000000000000000000000000000000000000", /* (2^-22) */
"0000001192092895507812500000000000000000000000000000000000000000", /* (2^-23) */
"0000000596046447753906250000000000000000000000000000000000000000", /* (2^-24) */
"0000000298023223876953125000000000000000000000000000000000000000", /* (2^-25) */
"0000000149011611938476562500000000000000000000000000000000000000", /* (2^-26) */
"0000000074505805969238281250000000000000000000000000000000000000", /* (2^-27) */
"0000000037252902984619140625000000000000000000000000000000000000", /* (2^-28) */
"0000000018626451492309570312500000000000000000000000000000000000", /* (2^-29) */
"0000000009313225746154785156250000000000000000000000000000000000", /* (2^-30) */
"0000000004656612873077392578125000000000000000000000000000000000", /* (2^-31) */
"0000000002328306436538696289062500000000000000000000000000000000", /* (2^-32) */
"0000000001164153218269348144531250000000000000000000000000000000", /* (2^-33) */
"0000000000582076609134674072265625000000000000000000000000000000", /* (2^-34) */
"0000000000291038304567337036132812500000000000000000000000000000", /* (2^-35) */
"0000000000145519152283668518066406250000000000000000000000000000", /* (2^-36) */
"0000000000072759576141834259033203125000000000000000000000000000", /* (2^-37) */
"0000000000036379788070917129516601562500000000000000000000000000", /* (2^-38) */
"0000000000018189894035458564758300781250000000000000000000000000", /* (2^-39) */
"0000000000009094947017729282379150390625000000000000000000000000", /* (2^-40) */
"0000000000004547473508864641189575195312500000000000000000000000", /* (2^-41) */
"0000000000002273736754432320594787597656250000000000000000000000", /* (2^-42) */
"0000000000001136868377216160297393798828125000000000000000000000", /* (2^-43) */
"0000000000000568434188608080148696899414062500000000000000000000", /* (2^-44) */
"0000000000000284217094304040074348449707031250000000000000000000", /* (2^-45) */
"0000000000000142108547152020037174224853515625000000000000000000", /* (2^-46) */
"0000000000000071054273576010018587112426757812500000000000000000", /* (2^-47) */
"0000000000000035527136788005009293556213378906250000000000000000", /* (2^-48) */
"0000000000000017763568394002504646778106689453125000000000000000", /* (2^-49) */
"0000000000000008881784197001252323389053344726562500000000000000", /* (2^-50) */
"0000000000000004440892098500626161694526672363281250000000000000", /* (2^-51) */
"0000000000000002220446049250313080847263336181640625000000000000", /* (2^-52) */
};
void asciiNumAdd_aDecimal(char a, char b, char *sum, char *Hcarry, char Lcarry)
{
int ta = a - 0x30;
int tb = b - 0x30;
int tLc = Lcarry - '0';
*sum = (ta + tb + tLc) % 10 + 0x30;
if (ta + tb > 9 || ta + tLc > 9 || tb + tLc > 9 || ta + tb + tLc > 9)
{
*Hcarry = 0x31; //1
}
else
{
*Hcarry = 0x30; //0
}
}
void ascStrAdd(char *a, char *b, char *sum)
{
int i;
char Lcarry = 0x30;
for (i = 63; i >= 0; i--)
{
asciiNumAdd_aDecimal(a[i], b[i], &sum[i], &Lcarry, Lcarry);
}
}
double HexToFloat64(long long hex) {
char buf[65];
int i = 0;
int exponent = 0;
char mantissa[65] = "0000000000000000000000000000000000000000000000000000000000000000";
char *buf2 = buf + 12;
double tmpflt;
char tmpMant[68];
buf[64] = 0;
for (i = 63;i>=0;i--)
{
buf[i] = (char)(hex % 2 + 0x30);
hex >>= 1;
}
mantissa[64] = '\0';
for (i = 0; i < 52; i++) // 计算尾数
{
if (buf2[i] != '0')
{
ascStrAdd(mantissa, fltable[i + 1], mantissa);
}
}
mantissa[64] = '\0';
for (i = 1; i < 12; i++) // 计算阶码
{
if (buf[i] != '0') {
exponent += pow(2, 11 - i);
}
}
exponent -= 1023;
tmpMant[1] = '.';
tmpMant[0] = '0';
strcpy(tmpMant + 2, mantissa);
tmpflt = atof(tmpMant) + 1;
tmpflt = tmpflt * pow(2, exponent);
return tmpflt;
}
double ArrayToFloat64(int* a) {
char buf[65];
int i = 0,j = 0;
int exponent = 0;
char mantissa[65] = "0000000000000000000000000000000000000000000000000000000000000000";
char *buf2 = buf + 12;
double tmpflt;
char tmpMant[68];
buf[64] = 0;
for (i = 7; i >= 0; i--)
{
for (j = 7; j >= 0; j--)
{
buf[j + i * 8] = (char)(a[i] % 2 + 0x30);
a[i] >>= 1;
}
}
mantissa[64] = '\0';
for (i = 0; i < 52; i++) // 计算尾数
{
if (buf2[i] != '0')
{
ascStrAdd(mantissa, fltable[i + 1], mantissa);
}
}
mantissa[64] = '\0';
for (i = 1; i < 12; i++) // 计算阶码
{
if (buf[i] != '0')
{
exponent += pow(2, 11 - i);
}
}
exponent -= 1023;
tmpMant[1] = '.';
tmpMant[0] = '0';
strcpy(tmpMant + 2, mantissa);
tmpflt = atof(tmpMant) + 1;
tmpflt = tmpflt * pow(2, exponent);
return tmpflt;
}
int main()
{
long long k = 0x419a90c96624d04c;
int a[8] = {0x41,0x9a,0x90,0xc9,0x66,0x24,0xd0,0x4c };
printf("%f", ArrayToFloat64(a));
printf("\n");
printf("%f",HexToFloat64(k));
return 0;
}