概述
- 引言
- 方法
- 归一化值
- 标度化值
- 短浮点数
- 参考
引言
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 … +1−2−15 >
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
2−8 | 2−9 | 2−10 | 2−11 | 2−12 | 2−13 | 2−14 | 2−15 |
S | 2−1 | 2−2 | 2−3 | 2−4 | 2−5 | 2−6 | 2−7 |
归一化值由两个字节组成。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
…+
215−1
>
标度化值也由两个字节组成。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
…
指数Exponent:=U32,8[24…31]<
0
…
符号Sign:=BS1[1]
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
2−16 | 2−17 | 2−18 | 2−19 | 2−20 | 2−21 | 2−22 | 2−23 |
2−8 | 2−9 | 2−10 | 2−11 | 2−12 | 2−13 | 2−14 | 2−15 |
E 20 | 2−1 | 2−2 | 2−3 | 2−4 | 2−5 | 2−6 | 2−7 |
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格式转换
最后
以上就是端庄季节为你收集整理的电力101/104规约中遥测量类型转换引言方法参考的全部内容,希望文章能够帮你解决电力101/104规约中遥测量类型转换引言方法参考所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复