打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
IEC 60870-5-4规一化带符号定点数与浮点数的转换

IEC 60870-5-4规一化带符号定点数与浮点数的转换  

2009-05-23 22:54:21|  分类: 编程技术 |  标签: |字号 订阅

IEC 60870-5-4中对于定点数F16的定义如下:

F16:=F16[1..16]<-1..+1-2-15>

其最高位为符号位,第14~0为分别表示2的负1~负15次幂。当最高位为1而其后所有位均为0时表示-1。整个数据的表示范围为-1~1-2的负15次幂。可以用下面的函数直观地将该定点数转换为浮点数:

        /// <summary>
        /// F16定点数转换为浮点数
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static float F16ToFloat(byte[] data)
        {
            double result = 0f;
            byte tmpByte = data[0];
            for (int i = 0; i < 8; i++)
            {
                if (GetBit(tmpByte, i))
                {
                    result += Math.Pow(2, i - 15);
                }
            }
            tmpByte = data[1];
            for (int i = 0; i < 7; i++)
            {
                if (GetBit(tmpByte, i))
                {
                    result += Math.Pow(2, i - 7);
                }
            }
            if (GetBit(tmpByte, 7)) result += -1;
            return (float)result;

        }
        /// <summary>
        /// 获取字节某一位的状态
        /// </summary>
        /// <param name="data">字节</param>
        /// <param name="index">偏移</param>
        /// <returns>位状态</returns>
        public static bool GetBit(byte data, int index)
        {
            Debug.Assert(index >= 0 && index < 8);

            byte tmpByte = (byte)(0x1 << index);
            return (data & tmpByte) == tmpByte;
        }
上述方法虽然可行,但由于进行了大量的运算,效率较低。经过恶补浮点数在内存中的表示方法,更主要的是学习了小数部分的表示方法,将上述方法改进如下:

        /// <summary>
        /// F16定点数转换为浮点数
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static float F16ToFloat(byte[] data)
        {
            Debug.Assert(data.Length == 2);
            //提取符号位
            bool sign = GetBit(data[1], 7);
            //移除符号位
            data[1] &= 0x7f;
            UInt32 holder = (UInt32)BitConverter.ToUInt16(data, 0);
            //浮点数的尾数部分在第0~22位,因此需要平移
            holder = holder << 8;
            holder = holder | (0x7f << 23);
            float result = BitConverter.ToSingle(BitConverter.GetBytes(holder), 0);
            //由于固定数的值在0~1之间,而浮点数的尾数在1~2之间,需要对其进行转换
            //符号位
            if (sign)
            {
                return result - 2;
            }
            else
            {
                return result - 1;
            }
        }
        /// <summary>
        /// 浮点数转换为F16
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] FloatToF16(float data)
        {
            bool sign = (data < 0);
            if (sign)
            {
                data += 2;
            }
            else
            {
                data += 1;
            }
            UInt32 holder = BitConverter.ToUInt32(BitConverter.GetBytes(data),0);
            holder = holder >> 8;
            if (sign)
                holder |= 0x8000;
            else
                holder &= 0x7fff;
            byte[] result = new byte[2];
            Array.Copy(BitConverter.GetBytes(holder), 0, result, 0, 2);
            return result;
        }

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
扫描局域网mac地址
unity3D实现录音功能,并将真实录音时长保存至本地(不能用可私信,附可执行文件下载地址)
简单高效的短链接生成服务C#实现
【Java】BitConverter(数字转字节数组工具类)
C#编程总结(十)字符转码
IoTClient开发3 - ModBusTcp协议客户端实现
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服