PLC中浮点数比较的精度问题处理
为什么浮点数比较会出错
PLC在处理模拟量信号时,普遍采用IEEE 754标准的32位单精度浮点数(REAL类型)。这种存储方式用二进制近似表示十进制小数,导致固有精度损失。
典型场景:温度设定值 20.0℃ 与实测值 20.0℃ 直接比较,判断结果可能为"不相等"。根源在于 20.0 在PLC内存中并非精确存储为20,而是 19.999999046... 或 20.000000954... 这类近似值。
当程序写成 IF 实际温度 = 20.0 THEN ...,两个近似值的二进制位模式 slightest 差异就会使等式失效。这种隐性故障在恒温控制、液位联锁、速度同步等关键工艺中可能引发设备误动作或安全事故。
精度问题的三大根源
根源一:十进制转二进制的截断误差
十进制小数 0.1 转换为二进制是无限循环小数 0.0001100110011...,PLC只能存储前23位有效位,后续无限截断。单次运算误差约 $1.19 \times 10^{-7}$,多次累积后显著。
根源二:运算过程的舍入累积
连续进行加、减、乘、除运算时,每次中间结果都会按"就近舍入"原则处理。例如液位计算:
液位高度 = (当前电流 - 4mA) × 量程 / 16mA
若电流采样值经滤波、线性化、温度补偿等多步处理,最终结果的误差可能达到量程的0.1%以上。
根源三:不同来源数据的表示差异
同一物理量的不同测量通道(如双冗余传感器),因硬件电路差异,A/D转换后的浮点值极少完全一致。直接比较会频繁触发"偏差报警",导致系统无法稳定运行。
解决方案一:绝对误差容限法(最常用的工程方法)
设定一个可接受的误差范围 $\epsilon$,当两数差的绝对值小于 $\epsilon$ 时视为相等。
数学表达
$$|A - B| < \epsilon$$
PLC实现(梯形图/结构化文本通用逻辑)
- 计算 两数差值的绝对值:使用
ABS(A - B) - 比较 该绝对值与容限
EPSILON - 判定 若
ABS(A - B) < EPSILON则为相等,否则为不等
容限选取原则
| 应用场景 | 推荐容限 $\epsilon$ | 设置依据 |
|---|---|---|
| 温度控制(0-200℃) | 0.1 或 0.05 |
传感器精度±0.5℃的1/5 |
| 压力显示(0-10MPa) | 0.001 |
显示分辨率0.01MPa的1/10 |
| 速度闭环(0-3000rpm) | 1.0 |
机械系统响应滞后量 |
| 液位保护(联锁动作) | 0.5% 量程 |
安全裕度优先 |
关键代码示例(IEC 61131-3 结构化文本)
VAR
SetTemp : REAL := 120.0; // 设定温度
ActTemp : REAL; // 实际温度(来自AI模块)
TempTol : REAL := 0.5; // 温度容限 ±0.5℃
TempEqual : BOOL; // 温度到达标志
END_VAR
// 核心比较逻辑
TempEqual := ABS(SetTemp - ActTemp) < TempTol;
解决方案二:相对误差容限法(宽量程场景)
当比较值本身跨度极大(如流量从 0.1m³/h 到 1000m³/h),固定绝对容限会导致小值时过严、大值时过松。
数学表达
$$\frac{|A - B|}{\max(|A|, |B|, 1)} < \epsilon_{rel}$$
分母取 MAX(|A|, |B|, 1) 防止除零,且保证最小比较基准为1。
PLC实现步骤
- 计算 两数的绝对值
ABS_A和ABS_B - 取 两者的较大值
MAX(ABS_A, ABS_B, 1.0) - 计算 相对误差
ABS(A - B) / MaxVal - 比较 与相对容限
0.001(即0.1%)
适用场景:财务结算、比率控制、配方配比等精度要求随数值比例变化的场合。
解决方案三:整数化比较法(高速/高可靠场景)
将浮点物理量乘以一个固定系数,转换为整数后比较。彻底规避浮点误差,但损失部分精度。
转换公式
$$\text{整数表示值} = \text{ROUND}\left(\frac{\text{物理量}}{\text{最小分辨率}}\right)$$
实施步骤
- 确定 工艺允许的最小分辨率,如温度
0.1℃ - 设定 转换系数
SCALE := 10.0(即10倍) - 转换 所有参与比较的量为整数:
INT_Set := REAL_TO_INT(SetTemp * 10.0) - 直接 用整数比较
=或>=
优势:整数运算在PLC中执行周期更短,且完全可预期。适合高速计数比较、安全联锁等关键回路。
注意事项:转换时注意溢出保护,32位有符号整数上限为 2147483647,对应物理量上限为 2.147×10^8 倍最小分辨率。
解决方案四:多周期确认法(抗干扰增强)
模拟量信号常叠加噪声,单次采样值可能瞬间偏离。即使采用容限法,噪声尖峰仍可能导致误判。
实现机制
VAR
CompareResult : BOOL; // 当前周期比较结果
ConfirmCounter : INT := 0; // 确认计数器
CONFIRM_TIMES : INT := 3; // 需连续3周期确认
StableEqual : BOOL; // 稳定相等输出
END_VAR
// 每周期执行
CompareResult := ABS(A - B) < EPSILON;
IF CompareResult THEN
ConfirmCounter := MIN(ConfirmCounter + 1, CONFIRM_TIMES);
ELSE
ConfirmCounter := 0;
END_IF;
StableEqual := (ConfirmCounter >= CONFIRM_TIMES);
参数选择:CONFIRM_TIMES 结合PLC扫描周期设定。若扫描周期 10ms,3次确认即 30ms 延迟,可滤除大多数高频噪声而不影响工艺响应。
边界条件与特殊处理
处理无穷大与NaN
PLC运算可能产生 +INF、-INF(除零溢出)或 NaN(无效运算)。这些特殊值与任何数(包括自身)比较都返回假,必须前置检测:
IF NOT(IsValidReal(A) AND IsValidReal(B)) THEN
ErrorFlag := TRUE;
// 执行故障安全处理
END_IF;
跨零比较的对称性
当比较值跨越零点时,ABS(A-B) 方法依然有效,但需注意 A=0.0001 与 B=-0.0001 的差值为 0.0002,相对误差极大。若工艺关注相对精度,应采用相对容限法。
多变量协同比较
复杂工况需同时满足多个条件,例如:
温度达标 AND 压力达标 AND 时间达标 → 进入下一阶段
建议每个条件独立采用容限法判定,最终逻辑与运算。禁止写成复合表达式如 ABS(Temp-Set)<0.5 AND ABS(Pres-Set)<0.01,因短路求序可能导致部分变量未检测。
工程实践检查清单
| 检查项 | 验证方法 |
|---|---|
| 所有浮点比较均使用容限法 | 代码审查搜索 = > < 运算符,确认配合 ABS 或范围判断 |
| 容限值与传感器精度匹配 | 对比仪表数据手册,容限 ≥ 2×传感器重复性误差 |
| 特殊值有保护处理 | 模拟除零、开方负数等场景,确认 IsValidReal 检测存在 |
| 关键联锁采用多周期确认 | 安全回路强制 CONFIRM_TIMES >= 2 |
| 调试期间记录实际偏差分布 | 在线监控 ABS(A-B) 的最大值,验证容限设置合理性 |
典型故障案例分析
案例:反应釜温度联锁误触发
- 现象:设定
160℃保温,PLC偶发判定温度未达标,持续加热导致超温。 - 根因:程序使用
ActTemp >= SetTemp直接比较,实际温度159.99997时判定为假。 - 修复:改为
ActTemp >= (SetTemp - 0.2),预留0.2℃回差,同时满足控制精度与可靠性。
结论性原则
浮点数比较的精度处理不是"精度越高越好",而是在工艺允许误差、系统响应速度、代码可维护性之间取得平衡。优先采用绝对容限法,宽量程场景补充相对容限,关键安全回路叠加多周期确认,特殊高速场景考虑整数化转换。所有容限参数应作为可调整变量而非硬编码常数,便于现场调试优化。

暂无评论,快来抢沙发吧!