概述:
由于浮点数的定义规则,导致浮点数不能通过二进制精确表示,所以在浮点数计算过程中,会出现两个值一样的浮点数进行比较相等计算时结果并不相等的情况。下面先设计一个实例说明该问题,并给出解决问题的方法。
第1步:
添加 PLC 设备。
选择西门子 CPU 1214C DC/DC/DC。
设置 IP 地址:192.168.0.1。
子网掩码:255.255.255.0
图1添加 PLC 设备
第2步:
1. 添加全局数据块。命名为:GdbData。
图 2 浮点数全局数据块
在以上全局数据块中添加浮点数类型变量,tagA、tagB、tagC 和 tagSum,分别设置起始值 0.02、0.03、0.05 和 0.0。
2. 在主程序 Main 中添加接口变量。
图 3 主程序 Main 的接口变量
3. 编写程序,进行浮点数加法计算并将结果进行相等比较。
图 4 编写程序
可以看到浮点数 tagA + tagB = 0.05,和 tagC = 0.05 作相等比较,比较结果并不相等。
4. 在监控表中监视变量值。
图 5 变量监视 - 浮点数
图 6 变量监视 - 十六进制
可以看到监视到变量 tagSum 和 tagC 的浮点数值均为 0.05,值相等,而十六进制数值却为 16#3D4C CCCC 和 16#3D4C CCCD,值不相等。在以上程序中浮点数相等的比较过程中实际上比较的是十六进制数,所以得到的结果并不相等。
第3步:
鉴于以上原因,在进行两个浮点数相等比较计算时,可以先计算两个数的差值,然后判断该差值是否在一个很小的数值范围以内,比如在 ±1.0E-6 以内,则认为这 两个浮点数相等。
图 7 比较两个浮点数相等
第4步:
功能封装。
定义一个 FC,命名为:RealEqual, 对以上功能进行封装,在以后浮点数相等判断时方便直接调用。
图 8 功能封装
封装后的调用结果。
图 9 功能调用