64位双精度浮点数转为IEEE 754 16进制编码
因为做机械臂项目需要提取机械臂坐标,所以当初为了把64位双精度浮点数转换为十六进制为可累死我了,看了挺多博客。但后来学长告诉我其实指针地址就是IEEE 754 16进制编码,C可以直接调用就不用写函数计算了,😭还是自己见识少了。在此分享大家,不用像我一样浪费时间。
原理可参考这里:IEEE 754 16进制编码转为64位双精度浮点数
doubleToHex:
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
double x;
char str[16];
cout << "输入浮点数: ";
cin >> x;
sprintf(str, "%p", x);
cout << "十六进制编码:" << str << endl;
}
HexToDouble:
找不到当时参考哪位大佬的了,在此谢谢大佬。我稍微把函数都封装成一个类。
#include <iostream>
#include <bitset>
#include <cmath>
#include <stdio.h>
#include <string>
using namespace std;
class HexToDouble
{
public:
static double putin(string temp1)
{
int i;
string temp;
temp = temp1;
string S_Bin = "";//转化后的二进制字符串
//cout<<temp.length()<<endl;//字符串长度16位
for (int i = 0; i < temp.length(); i++)
{
char temp1 = temp[i];
S_Bin = S_Bin + charToBin(temp1);//十六进制转二进制串
}
// cout<<"转化后的二进制串 "<<S_Bin<<endl;//
int sign = 0;//符号位
if (S_Bin.at(0) == '1')//判断符号位
{
sign = 1;
}
string exponent = ""; //定义指数部分Exp
for (i = 1; i < 12; i++)
{
if (S_Bin.at(i) == '1')
{
exponent = exponent + '1';
}
else
exponent = exponent + '0';
}
int exponent_double = 0;//阶码
exponent_double = stringToDouble(exponent);
// cout<<"偏移位数 "<<exponent_double<<endl;
exponent_double = exponent_double - 1023;//计算出偏移位数 ,64位双精度浮点数的偏置码为1023
// cout<<"偏移位数 "<<exponent_double<<endl;
string mantissa_temp = ""; //定义尾数部分Fraction
for (i = 12; i < 64; i++)
{
if (S_Bin.at(i) == '1')
{
mantissa_temp = mantissa_temp + '1';
}
else
mantissa_temp = mantissa_temp + '0';
}
double mantissa = 0;
mantissa = BenToDex(mantissa_temp); //二进制串到double(小数)
// cout<<"小数点 "<<mantissa<<endl;
mantissa = mantissa + 1.0;
double res = 0;
double a, c;
a = pow((-1), sign);
c = pow(2, exponent_double);
res = a * mantissa * c;
return res;
}
static string charToBin(char temp)//十六进制转二进制串
{
switch (temp)
{
case '0':
return "0000";
break;
case '1':
return "0001";
break;
case '2':
return "0010";
break;
case '3':
return "0011";
break;
case '4':
return "0100";
break;
case '5':
return "0101";
break;
case '6':
return "0110";
break;
case '7':
return "0111";
break;
case '8':
return "1000";
break;
case '9':
return "1001";
break;
case 'A':case 'a':
return "1010";
break;
case 'B':case 'b':
return "1011";
break;
case 'C':case 'c':
return "1100";
break;
case 'D':case 'd':
return "1101";
break;
case 'E':case 'e':
return "1110";
break;
case 'F':case 'f':
return "1111";
break;
default:
return "WRONG!";
}
}
static int stringToDouble(string temp)//二进制串到double(整数)
{
double res = 0;
for (int i = 0; i < temp.length(); i++)
{
res = res * 2 + (temp[i] - '0');
}
return res;
}
static double BenToDex(string temp)//二进制串到double(小数)
{
int m = temp.length();
double res = 0;
for (int i = 0; i < m; i++)
{
res = res + (temp[i] - '0') * pow(2, -i - 1);
}
return res;
}
};
int main()
{
string x, y, z;
cin >> x;//输入十六进制
// cin>>z;
double x1 = HexToDouble::putin(x);
cout << x1 << endl;
cin >> y;
double y1 = HexToDouble::putin(y);
//double z1=HexToDouble::putin(z);
cout << y1 << endl;
// cout<<"z "<<z1<<endl;
return 0;
}
doubleToHex:
也是找不到当时参考哪位大佬的了,谢谢大佬。我也稍微把函数都封装成一个类了。
#include <iostream>
#include <cmath>
#include <bitset>
#include <string.h>
#include <string>
using namespace std;
class doubleToHex
{
public:
static void TestDouble(double value)
{
int count = 0;
string x;
if (value > 0)
{
x += "0"; //判断符号
}
else
{
x += "1";
value = -value;
}
while (2 <= value) //获得小数点后值
{
value = value / 2.0;
count++;
}
while (value < 1)
{
value = value * 2;
count--;
}
count = count + 1023;
bitset<11>code(count);//将阶码变成二进制表示
x += code.to_string();//前半部分二进制表示
int digit = -1;
value -= 1.0;
//将数值用二进制表示/
double posval = 0.0;
double tempval = 0.0;
while (value != 0 && digit > -54)
{
posval = pow(2, digit);
tempval = value - posval;
if (tempval > 0)
{
x += "1";
value = tempval;
}
else if (tempval == 0)
{
x += "1";
break;
}
else
x += "0";
--digit;
}
int size = 64 - x.size();
if (size > 0)
{
char* temp = new char[size];
memset(temp, '0', size);
x.append(temp, size);
delete temp;
}
cout << binTohexstr(x) << endl;
}
static string binTohexstr(string temp)
{
string value = "";
if (temp.size() % 4 != 0)
{
return NULL;
}
while ((temp.size() - 4) > 0)
{
value += binTohex(temp.substr(0, 4));
temp = temp.substr(4, temp.size() - 4);
}
value += binTohex(temp);
return value;
}
static char binTohex(string temp)
{
if ("0000" == temp)
return '0';
else if ("0001" == temp)
return '1';
else if ("0010" == temp)
return '2';
else if ("0011" == temp)
return '3';
else if ("0100" == temp)
return '4';
else if ("0101" == temp)
return '5';
else if ("0110" == temp)
return '6';
else if ("0111" == temp)
return '7';
else if ("1000" == temp)
return '8';
else if ("1001" == temp)
return '9';
else if ("1010" == temp)
return 'A';
else if ("1011" == temp)
return 'B';
else if ("1100" == temp)
return 'C';
else if ("1101" == temp)
return 'D';
else if ("1110" == temp)
return 'E';
else if ("1111" == temp)
return 'F';
else
return 'G';
}
};
int main()
{
double x;
cin >> x;
doubleToHex::TestDouble(x);
return 0;
}