amine / 电力 / IEC 60870-5-4规一化带符号定点数与浮点数...

分享

   

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

2012-05-04  amine

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。

    来自: amine > 《电力》

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多

    ×
    ×

    ¥.00

    微信或支付宝扫码支付:

    开通即同意《个图VIP服务协议》

    全部>>