之前讲过浮点数部分,参看:C语言再学习 – 浮点数
现在程序中要将浮点数,通过TCP发送。那得先将其转换为十六进制才行呀。
那么问题就来了。
参看:C语言:单精度(float)和双精度(double)浮点数 与 十六进制(HEX) 之间转换
扩展:
STM32开发 – 进制与字符串间的转换
一、浮点数 介绍
单精度浮点float:可以精确到小数点后6位双精度浮点double:可以精确到小数点后12位C可以通过f或F后缀是编译器把浮点常量当做float类型,比如2.3f和9.11E9F。
l或L后缀使一个数字成为long double类型,比如54.3l和4.32e4L。
建议使用L后缀,因为字母l和数字1容易混淆
没有后缀的浮点常量为double类型。(重点)。例:sizeof(1.9) = 8;
浮点数二进制表达的三个组成部分
Sign(1bit):表示浮点数是正数还是负数。 0表示正数,1表示负数
Exponent(8bits):指数部分。 类似于科学技术法中的M*10^N中的N,只不过这里是以2为底数而不是10。需要注意的是,这部分中是以2 ^ 7-1即127,也即01111111代表2 ^ 0,转换时需要根据127作偏移调整。
Mantissa(23bits):基数部分。 浮点数具体数值的实际表示。
单精度(float)浮点数----32位
具体结构如下表所示:
双精度(double)浮点数----64位
二、浮点数十六进制转换器
链接:浮点数十六进制转换器v1.1
提取码:775u
浮点数 13.88 单精度(float) 转 十六进制(HEX)为 41 5E 14 7B 双精度(double)转 十六进制(HEX)为
40 2B C2 8F 5C 28 F5 C3
三、C语言实现 浮点数 转 十六进制(HEX)
1、单精度(float) 转 十六进制(HEX)
(1)指针法
具体代码如下:
void Float_HEX (float fdata, unsigned char *hdata){unsigned char* tdata = (unsigned char*)(&fdata);hdata[0] = tdata[0];hdata[1] = tdata[1];hdata[2] = tdata[2];hdata[3] = tdata[3];}
测试用例如下:
int main(int argc, char *argv[]){unsigned char data[4] = {0,0,0,0};float fdata = 13.88;Float_HEX(fdata,data);for(int i=0;i<4;i++)printf("0x%X\n",data[i]);return 0;}
由于我的电脑系统是小端模式,所以低字节在前。
运行结果如下:
(2)共用体法
具体代码如下:
union { float fdata; unsigned char data[4];}temp;
测试用例如下:
int main(int argc, char *argv[]){temp.fdata = 13.88;for(int i=0;i<4;i++)printf("0x%X\n",temp.data[i]);return 0;}
由于我的电脑系统是小端模式,所以低字节在前。
运行结果如下:
(3)memcpy()函数法
具体代码如下:
void Float_HEX (float fdata, unsigned char *hdata){memcpy(hdata,&fdata,sizeof(fdata));}
测试用例如下:
int main(int argc, char *argv[]){unsigned char data[4] = {0,0,0,0};float fdata = 13.88;Float_HEX(fdata,data);for(int i=0;i<4;i++)printf("0x%X\n",data[i]);return 0;}
由于我的电脑系统是小端模式,所以低字节在前。
运行结果如下:
2、双精度(double)转 十六进制(HEX)
(1)指针法
具体代码如下:
void Double_HEX (double Ddata, unsigned char *hdata){unsigned char* tdata = (unsigned char*)(&Ddata);hdata[0] = tdata[0];hdata[1] = tdata[1];hdata[2] = tdata[2];hdata[3] = tdata[3];hdata[4] = tdata[4];hdata[5] = tdata[5];hdata[6] = tdata[6];hdata[7] = tdata[7];}
测试用例如下:
int main(int argc, char *argv[]){unsigned char data[8] = {0,0,0,0,0,0,0,0};double Ddata = 13.88;Double_HEX(Ddata,data);for(int i=0;i<8;i++)printf("0x%X\n",data[i]);return 0;}
由于我的电脑系统是小端模式,所以低字节在前。
运行结果如下:
(2)共用体法
具体代码如下:
union { double Ddata; unsigned char data[8];}temp;
测试用例如下:
int main(int argc, char *argv[]){temp.Ddata = 13.88; for(int i=0;i<8;i++)printf("0x%X\n",temp.data[i]);return 0;}
由于我的电脑系统是小端模式,所以低字节在前。
运行结果如下:
(3)memcpy()函数法
具体代码如下:
void Double_HEX (double Ddata, unsigned char *hdata){memcpy(hdata,&Ddata,sizeof(Ddata));}
int main(int argc, char *argv[]){unsigned char data[8] = {0,0,0,0,0,0,0,0};double Ddata = 13.88;Double_HEX(Ddata,data);for(int i=0;i<8;i++)printf("0x%X\n",data[i]);return 0;}
由于我的电脑系统是小端模式,所以低字节在前。
运行结果如下:
四、十六进制(HEX) 转 浮点数
1、十六进制(HEX) 转 单精度(float)
具体代码如下:
int main(int argc, char *argv[]){char data[4] = {0x7B,0x14,0x5E,0x41};float fdata = 0;memcpy(&fdata,data,sizeof(fdata));printf("fdata=%f\n",fdata);return 0;}
运行结果如下:
2、十六进制(HEX) 转 双精度(double)
具体代码如下:
int main(int argc, char* argv[]){char data[8] = { 0xC3,0xF5,0x28,0x5C,0x8F,0xC2,0x2B,0x40 };double Ddata = 0;memcpy(&Ddata, data, sizeof(Ddata));printf("Ddata=%f\n", Ddata);return 0;}
运行结果如下:
五、浮点二进制转换工具
参看:浮点二进制转换工具