双精度浮点数转换单精度浮点数
双精度浮点数转换整型数
最近经常需要读取流量计数据,但流量计总量通常采用64位双精度浮点数(double)储存,但无论是电脑组态软件还是触摸屏组态软件,都只能读取32位数据,查询大量资料,不得其法。只能自己动手!
经过研究,通过威纶触摸屏宏指令,可以将双精度浮点数转为单精度浮点数或整型数据,转换过程分享给大家,希望对遇到相同问题的难兄难弟有帮助。
(没有转换的数据截图)
(转换后的数据截图)
以下为doule转float原程序:
双精度浮点数转换单精度浮点数比较容易,将以下代码复制到宏文件即可。
macro_command main()
bool bit[48],ba[8]
short e[2]
GetData(bit[0], "Local HMI", LW_Bit, 1000, 48)
SetData(bit[4], "Local HMI", LW_Bit, 1400, 11)
GetData(e[0], "Local HMI", LW, 14, 1)
e[1]=e[0]-1023+127
SetData(e[1], "Local HMI", LW, 15, 1)
GetData(ba[0], "Local HMI", LW_Bit, 1500, 8)
SetData(bit[45], "Local HMI", LW_Bit, 1600, 3)
SetData(bit[16], "Local HMI", LW_Bit, 1603, 16)
SetData(bit[0], "Local HMI", LW_Bit, 1703, 4)
SetData(ba[0], "Local HMI", LW_Bit, 1707, 8)
SetData(bit[15], "Local HMI", LW_Bit, 1715, 1)
end macro_command
如果看不懂,以下是加标注的完整原程序,供大家参考。
以下为doule转float原程序及标注:
//威纶屏双精度浮点数(doule)转换为单精度浮点数(float)
//最近经常碰到用威纶屏读取流量计数据,但流量计总量数据经常采用双精度浮点数储存,无法直接读
取,只能将双精度浮点数转换为单精度浮点数,虽然转换后的数值有点差异,但基本能满足用户使用。
//单精度浮点和双精度浮点主要差异在指数部分和尾数位数
//单精度(32位)浮点数的结构:
//符号位Sign(S): 1bit (b31)
//指数部分Exponent(E): 8bit (b30-b23)
//尾数部分Mantissa(M) : 23bit (b22-b0)
//单精度的指数部分(E)采用的偏置码为127(E-127)
//双精度(64位)浮点数的结构:
//符号位Sign(S): 1bit (b63)
//指数部分Exponent(E): 11bit (b62-b52)
//尾数部分Mantissa(M): 52bit (b51-b0)
//双精度的指数部分(E)采用的偏置码为1023(E-1023)
//转换原理:单精度浮点和双精度浮点符号位相同,将双精度的指数转换为单精度的指数,取双精度浮点数尾数部分52位的前23位作为单精度浮点数的尾数部分
//*******************************************
//将流量计总量双精度浮点数按4个16位无符号整型(unsigned short)数据储存在LW10、LW11、LW12、LW13寄存器,计算后的单精度浮点数储存在LW16、LW17(顺序CDAB)。
macro_command main()
bool bit[48],ba[8] //bit-原浮点数位;ba-
short e[2] //e-指数值
支持小数点的进制转换器GetData(bit[0], "Local HMI", LW_Bit, 1000, 48) //按位提取前48位,注意,每个字节提取的16位二进制数与需要的数相反,即:二进制数为1111000001010101,排序1010101000001111,后16位舍弃
SetData(bit[4], "Local HMI", LW_Bit, 1400, 11) //将双精度浮点数指数部分按位储存到LW14寄存器
GetData(e[0], "Local HMI", LW, 14, 1) //读取双精度浮点数指数数值
//计算单精度浮点数指数
e[1]=e[0]-1023+127
SetData(e[1], "Local HMI", LW, 15, 1) //将单精度浮点数指数数值写入LW15寄存器
GetData(ba[0], "Local HMI", LW_Bit, 1500, 8) //按位读取单精度浮点数指数部分
//按位将单精度浮点数写入到LW16、LW17寄存器。LW16、LW17即为屏可以读取的float值(屏读取float值时,读取顺序是CDAB,所以AB写入LW17,CD写入LW16)
SetData(bit[45], "Local HMI", LW_Bit, 1600, 3)
SetData(bit[16], "Local HMI", LW_Bit, 1603, 16)
SetData(bit[0], "Local HMI", LW_Bit, 1703, 4)
SetData(ba[0], "Local HMI", LW_Bit, 1707, 8)
SetData(bit[15], "Local HMI", LW_Bit, 1715, 1)
end macro_command
//位计算方法如下
//单精度浮点[0]=bit[45]
//单精度浮点[2]=bit[47] //单精度浮点[3]=bit[16] //单精度浮点[4]=bit[17] //单精度浮点[5]=bit[18] //单精度浮点[6]=bit[19] //单精度浮点[7]=bit[20] //单精度浮点[8]=bit[21] //单精度浮点[9]=bit[22] //单精度浮点[10]=bit[23] //单精度浮点[11]=bit[24] //单精度浮点[12]=bit[25] //单精度浮点[13]=bit[26] //单精度浮点[14]=bit[27] //单精度浮点[15]=bit[28] //单精度浮点[16]=bit[29] //单精度浮点[17]=bit[30] //单精度浮点[18]=bit[31] //单精度浮点[19]=bit[0] //单精度浮点[20]=bit[1] //单精度浮点[21]=bit[2] //单精度浮点[22]=bit[3] //单精度浮点[23]=ba[0] //单精度浮点[24]=ba[1] //单精度浮点[25]=ba[2] //单精度浮点[26]=ba[3] //单精度浮点[27]=ba[4] //单精度浮点[28]=ba[5] //单精度浮点[29]=ba[6]
//单精度浮点[31]=bit[15]
(原程序截图)