最近碰到个项目需要用到浮点数与16进制互转,记录一下。
下面是双精度浮点数转16进制代码:
符号位:63,指数位:62 ~ 52,尾数位: 51 ~ 0;
单精度转16进制同理,位数不同:
符号位:31,指数位:30 ~ 23,尾数位: 22 ~ 0;
unsigned long long double2hex(double db, string& strHex)
{
map<int,char> buf;
buf.clear();
//符号位s
int s = db > 0 ? 0 : 1;
buf[0] = s;
db = fabs(db);
//算出指数位e
int a = abs(db);
int e = 0;
if (a >= 1)
{
while (a / 2 > 0)
{
a = a / 2;
e++;
}
}
else
{
do
{
db *= 2;
e--;
} while (db < 1);
}
e += 1023;
//将e换算为11位指数位
vector<int> vT;
vT.clear();
while (e / 2 > 0) //整数转二进制取余
{
vT.push_back(e%2);
e = e / 2;
}
vT.push_back(e);
reverse(vT.begin(), vT.end()); //余数反向
while (vT.size() < 11)
{
vT.insert(vT.begin(),0);
}
int i = 1; //buf[1-11]
for (auto it = vT.begin(); it != vT.end(); it++)
{
buf[i] = *it;
i++;
}
//52位尾数位
vT.clear();
a = abs(db);
while (a / 2 > 0) //整数部分转二进制:除以2取余数
{
vT.push_back(a % 2);
a = a / 2;
}
vT.push_back(a);
reverse(vT.begin(), vT.end()); //余数反向
vT.erase(vT.begin()); //去掉第一位隐藏位
double b = db - int(db);
for (int i = 0; i < 52; i++) //小数部分转二进制:每次循环用小数部分乘以2取整数部分
{
double b2 = b * 2;
int T = b2;
b = b2 - T;
vT.push_back(T);
}
i = 12; //buf[12-63]
for (auto it = vT.begin(); it != vT.end(); it++)
{
buf[i] = *it;
i++;
}
//转成16进制
unsigned long long lHex = 0;
for (int i = 0; i < 64; i++)
{
lHex = (lHex << 1) | buf[i];
}
//转成16进制字符串
std::string _strHex;
for (int i = 0; i < 64; i=i+8)
{
byte byteT = 0;
for (int j = i; j < i+8; j=j++)
{
byteT = (byteT << 1) | buf[j];
}
_strHex += byteT;
}
strHex = _strHex;
return lHex;
}