电力101/104规约中遥测量类型转换

引言

DL/T634.5101-2002和DL/T634.5104-2009标准中遥测量的标识类型有归一化值NVA,标度化值SVA,短浮点数R32-IEEE STD 754,本文介绍利用union数据类型完成字节数组向这三种类型转换的方法。

方法

定义union数据类型,该union类型定义了多种不同数据类型的内部变量,但各个内部变量共享一段内存,在不同时间里保存不同的数据类型和长度的变量,此处共只占用4个字节。

typedef unsigned char       BYTE;
typedef unsigned long       DWORD;
typedef union  // 4 bytes
{
    bool  bBool;            //  int value
    BYTE  byBuf[4];         //  Buffer
    short int nInt;         //  16 bits integer
    unsigned short int snInt;//  16 bits unsigned integer
    long  l;                //  32位有符号  2,147,483,648 to 2,147,483,647
    DWORD dw;               //  32位无符号整数 0 to 4,294,967,295
    float f;                //  32位 3.4E +/- 38 (7 digits)
} EXC_DataType;

归一化值

NVA:=F16[1…16]< 1 +1215 >

D7D6D5D4D3D2D1D0
28 29 210 211 212 213 214 215
S 21 22 23 24 25 26 27

归一化值由两个字节组成。1位符号位,0表示正数,1表示负数。15位数据位,正数是原码,负数是补码。

float Bytes2Float_NVA( const QByteArray &bytes )
 {
     float fVal;
     EXC_DataType  unDataType;
     unDataType.dw = 0; //初始化清零

     unDataType.byBuf[0] = bytes[0];  //低位
     unDataType.byBuf[1] = bytes[1];  //高位

     if (unDataType.snInt<0) //负数
     {
         //负数:补码转换,取反加一
         unDataType.byBuf[1] = unDataType.byBuf[1] & 0x7F;//除符号位外按位异或,取反
         unDataType.usnInt ^=0xffff;
         unDataType.usnInt++;
         unDataType.byBuf[1] = unDataType.byBuf[1] & 0xFF;
         fVal = (float)unDataType.snInt; //-32768--0
     }
     else //正数:原码
         fVal = (float)unDataType.snInt;  // 0--32767

     return fVal/32768;//2**15=32768
 }

标度化值

SVA:=I16[1…16]< 215 …+ 2151 >
标度化值也由两个字节组成。1位符号位,0表示正数,1表示负数。15位数据位,正数是原码,负数是补码。

float Bytes2Float_SVA( const QByteArray &bytes )
 {
     float fVal;
     EXC_DataType  unDataType;
     unDataType.dw = 0; //初始化清零

     unDataType.byBuf[0] = bytes[0];  //低位
     unDataType.byBuf[1] = bytes[1];  //高位

     if (unDataType.snInt<0) //负数
     {
         //负数:补码转换,取反加一
         unDataType.byBuf[1] = unDataType.byBuf[1] & 0x7F;//除符号位外按位异或,取反
         unDataType.usnInt ^=0xffff;
         unDataType.usnInt++;
         unDataType.byBuf[1] = unDataType.byBuf[1] & 0xFF;
         fVal = (float)unDataType.snInt; //-32768--0
     }
     else //正数:原码
         fVal = (float)unDataType.snInt;  // 0--32767

     return fVal;
 }

短浮点数

R32-IEEE STD 754:=R32.23{Fraction,Exponent,Sign}
小数Fraction:=U32,23[1…23]< 0 1223>
指数Exponent:=U32,8[24…31]< 0 255>
符号Sign:=BS1[1]

D7D6D5D4D3D2D1D0
216 217 218 219 220 221 222 223
28 29 210 211 212 213 214 215
E 20 21 22 23 24 25 26 27
S 27 26 25 24 23 22 21

短浮点数由四个字节组成。1位符号位,0表示正数,1表示负数。
由于C语言中浮点数本身就是采用IEEE格式来存储的,可巧妙利用union数据类型实现两者之间的转换,如下

float Bytes2Float_IEEE754( const QByteArray &bytes )
 {
     EXC_DataType  unDataType;
     unDataType.dw = 0; //初始化清零

     unDataType.byBuf[0] = bytes[0];  //低位
     unDataType.byBuf[1] = bytes[1];
     unDataType.byBuf[2] = bytes[2];
     unDataType.byBuf[3] = bytes[3];  //高位

     return unDataType.f;//直接返回float类型即为IEEE格式
 }

参考

电力101/104规约中遥测数据归一化问题
C程序中用union实现浮点数与IEEE格式转换

  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值