简体   繁体   中英

(unsigned __int16 to float) and float to (unsigned __int16) typecast vs union in C++

I have 3000 floating type(4 byte) variables and 2000 unsigned __int16(2 byte) variables. These variables stores data from plc.

I have a constant struct array which stores the information of each plc tag.

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] = {{....},{....},.................,{....}};

I want to group all of the above variables(3000 float + 2000 ushort) as a single array[5000]. So, I can access value of plc tag based on tag index.

I came up with two solutions. But not sure which one is correct to use.

Solution 1: declare float array[5000] and access value based on plc tag id.

  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) ; 
     }
 }

Solution 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) ; 
     }
 }

Could you please suggest me which type of above solution is better to use for my problem? If both of above aren't good to use, please suggest me a better idea to implement.

Thank you.

What you're attempting to do with the union is called Type Punning , and is undefined behavior in C++: https://stackoverflow.com/a/11996970/2642059

Because unions are frequently abused because of the speed afforded by union based Type Punning so most C++ compilers do support such behavior.

In short if you intend to write portable which conforms to the standard, you'll need to use Solution 1 ; however depending upon your compiler, you may find Solution 2 to be a faster solution on your compiler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM