在上位机与下位机进行通讯的过程中,需要把float类型的数据存入单字节数据流中,形成报文,然后下位机再对报文进行解析,将单字节数据流转换为float型。char类型是单字节,很容易存入单字节数组,但float占4个字节,如何去存?首先,想到的就是float类型数据的编码方式,由于涉及符号和小数位,似乎不是那么简单。实际操作中,我们不需要关注一个浮点数怎么用二进制表示(如果有兴趣也可以了解),只需要用数据结构中的联合体union即可解决问题。下面是案例代码:
#include <iostream>
using namespace std;
typedef union
{
struct
{
unsigned char low_byte;
unsigned char mlow_byte;
unsigned char mhigh_byte;
unsigned char high_byte;
}float_byte;
float value;
}floatUnionType;
void SendMessage(unsigned char id, float fValue, unsigned char data[])
{
data[0] = id; //由于id是单字节,直接存
floatUnionType fut;
fut.value = fValue; //先把要发送的数据存入union构成的模具中
//再把模具中的数据按照单字节,从低位到高为依次取出,存到单字节数组中
data[1] = fut.float_byte.low_byte;
data[2] = fut.float_byte.mlow_byte;
data[3] = fut.float_byte.mhigh_byte;
data[4] = fut.float_byte.high_byte;
}
void ReceiveMessage(unsigned char data[], unsigned char& id, float& fValue)
{
id = data[0]; //由于id是单字节,直接取
floatUnionType fut;
//先把单字节数组中的数据存入模具
fut.float_byte.low_byte = data[1];
fut.float_byte.mlow_byte = data[2];
fut.float_byte.mhigh_byte = data[3];
fut.float_byte.high_byte = data[4];
fValue = fut.value; //再把模具中解析出来的float数据取出来
}
void main()
{
unsigned char info[5];
SendMessage(123, 3.1415, info); //将info发出去
//省略通信模块......
//实际项目中可能需要TCP等协议的通讯,配置IP、端口,服务端发送,客户端接收单字节流的报文
unsigned char t_id = 0;
float t_value = 0;
ReceiveMessage(info, t_id, t_value); //接收到info,并解析出id和value
cout << "id = " << t_id << endl;
cout << "value = " << t_value << endl;
getchar();
}
运行结果如下:
预期id的输出结果是123,怎么会是大括号?!
查看ASSIC码表:
发现 { 就是图形表示的十进制 123,强转一下:
cout << "id = " << (int)t_id << endl;
再看结果:
总结:如果要存两个字节的unsigned short,或者八个字节的double,也可以用这一思路。
比如两个字节就可以这样写:
typedef union
{
struct
{
unsigned char low_byte;
unsigned char high_byte;
}uShort_byte;
unsigned short value;
}uShortUnionType;