(unsigned __int16 to float) 和 float to (unsigned __int16) typecast vs union in C++
(unsigned __int16 to float) and float to (unsigned __int16) typecast vs union in C++
我有 3000 个浮点型(4 字节)变量和 2000 个无符号 __int16(2 字节)变量。这些变量存储来自 plc 的数据。
我有一个常量结构数组,用于存储每个 plc 标签的信息。
struct strPLCtags
{
unsigned short id ; //plc tag id
unsigned __int16 mbaddress ; //plc Modbus address
String name ; //plc tag name
String description ; //plc tag description
Byte datatype ; // 2 = ushort ; 4 = float
Byte plcaccess ; //Read, Write, Read/Write Tag
};
const strPLCtags plcTags[5000] = {{....},{....},.................,{....}};
我想将上述所有变量 (3000 float + 2000 ushort) 分组为一个数组 [5000]。因此,我可以根据标签索引访问 plc 标签的值。
我想到了两个解决方案。但不确定哪个是正确的。
解决方案一:根据plc标签id声明float数组[5000]和访问值
float PLCDataArray1[5000] ;
//Get PLC data and assign to array
PLCDataArray1[0] = static_cast<float>(GetU16ValueFromPLC(addr)) ;
PLCDataArray1[1] = GetFloatValueFromPLC(addr) ;
.
.
PLCDataArray1[4999] = GetFloatValueFromPLC(addr) ;
//To read back above data as String and show it on form.
String GetPLCData(unsigned short tid) //tid is plc tag id
{
if(plcTags[tid] == 2)
{
return IntToStr(PLCDataArray1[tid]) ;
}
else
{
return FloatToStrF(PLCDataArray1[tid],ffFixed,6,2) ;
}
}
解决方案二:
union uFltOrUS16
{
unsigned __int16 usVal;
float fltVal;
};
uFltOrUS16 PLCDataArray2[5000] ;
//Get PLC data and assign to array
PLCDataArray2[0].usVal = GetU16ValueFromPLC(addr) ;
PLCDataArray2[1].fltVal = GetFloatValueFromPLC(addr) ;
.
.
PLCDataArray2[4999].fltVal = GetFloatValueFromPLC(addr) ;
//To read back above data as String and show it on form.
String GetPLCData(unsigned short tid) //tid is plc tag id
{
if(plcTags[tid] == 2)
{
return IntToStr(PLCDataArray2[tid].usval) ;
}
else
{
return FloatToStrF(PLCDataArray2[tid].fltval,ffFixed,6,2) ;
}
}
你能建议我上面哪种类型的解决方案更适合我的问题吗?
如果以上两个都不好用,请给我一个更好的实施方案。
谢谢。
您尝试使用 union
执行的操作称为 Type Punning, and is undefined behavior in C++:
因为联合经常被滥用因为 union
基于类型双关所提供的速度所以大多数 C++ 编译器 支持这样的行为。
简而言之,如果您打算编写符合标准的可移植c++,则需要使用解决方案1;但是,根据您的编译器,您可能会发现 解决方案 2 是您编译器上更快的解决方案。
我有 3000 个浮点型(4 字节)变量和 2000 个无符号 __int16(2 字节)变量。这些变量存储来自 plc 的数据。
我有一个常量结构数组,用于存储每个 plc 标签的信息。
struct strPLCtags
{
unsigned short id ; //plc tag id
unsigned __int16 mbaddress ; //plc Modbus address
String name ; //plc tag name
String description ; //plc tag description
Byte datatype ; // 2 = ushort ; 4 = float
Byte plcaccess ; //Read, Write, Read/Write Tag
};
const strPLCtags plcTags[5000] = {{....},{....},.................,{....}};
我想将上述所有变量 (3000 float + 2000 ushort) 分组为一个数组 [5000]。因此,我可以根据标签索引访问 plc 标签的值。
我想到了两个解决方案。但不确定哪个是正确的。
解决方案一:根据plc标签id声明float数组[5000]和访问值
float PLCDataArray1[5000] ;
//Get PLC data and assign to array
PLCDataArray1[0] = static_cast<float>(GetU16ValueFromPLC(addr)) ;
PLCDataArray1[1] = GetFloatValueFromPLC(addr) ;
.
.
PLCDataArray1[4999] = GetFloatValueFromPLC(addr) ;
//To read back above data as String and show it on form.
String GetPLCData(unsigned short tid) //tid is plc tag id
{
if(plcTags[tid] == 2)
{
return IntToStr(PLCDataArray1[tid]) ;
}
else
{
return FloatToStrF(PLCDataArray1[tid],ffFixed,6,2) ;
}
}
解决方案二:
union uFltOrUS16
{
unsigned __int16 usVal;
float fltVal;
};
uFltOrUS16 PLCDataArray2[5000] ;
//Get PLC data and assign to array
PLCDataArray2[0].usVal = GetU16ValueFromPLC(addr) ;
PLCDataArray2[1].fltVal = GetFloatValueFromPLC(addr) ;
.
.
PLCDataArray2[4999].fltVal = GetFloatValueFromPLC(addr) ;
//To read back above data as String and show it on form.
String GetPLCData(unsigned short tid) //tid is plc tag id
{
if(plcTags[tid] == 2)
{
return IntToStr(PLCDataArray2[tid].usval) ;
}
else
{
return FloatToStrF(PLCDataArray2[tid].fltval,ffFixed,6,2) ;
}
}
你能建议我上面哪种类型的解决方案更适合我的问题吗? 如果以上两个都不好用,请给我一个更好的实施方案。
谢谢。
您尝试使用 union
执行的操作称为 Type Punning, and is undefined behavior in C++:
因为联合经常被滥用因为 union
基于类型双关所提供的速度所以大多数 C++ 编译器 支持这样的行为。
简而言之,如果您打算编写符合标准的可移植c++,则需要使用解决方案1;但是,根据您的编译器,您可能会发现 解决方案 2 是您编译器上更快的解决方案。