You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TwinCAT3中REAL类型超32768后无法累加小数的问题咨询

TwinCAT3中REAL类型超过32768后无法累加小数值的原因与解决办法

问题复现

以下是触发问题的最简TwinCAT3代码:

// declaration
fTest : REAL := 32700.0;

// implementation
fTest := fTest + 0.001;

运行后fTest会增长到32768,但此后累加0.001、0.0019或0.0011时数值不再变化,只有将增量改为0.002才能继续增长。

原因分析

这不是TwinCAT的BUG,而是32位REAL类型(符合IEC 61131-3/IEC 559/IEEE754标准)的固有精度限制:

  • 32位REAL的结构为:1位符号位、8位偏移指数(实际指数范围-126~+127)、23位尾数。
  • 当数值达到32768(即2^15)时,该数值处于[2^15, 2^16)区间,此时REAL类型的**单位最后一位精度(ULP)**为2^(15-23) = 2^-8 = 0.00390625。
  • 这意味着,该区间内的REAL数值只能以0.00390625为最小步长变化。任何小于该步长的增量(比如0.001、0.002)都会被浮点数的舍入机制丢弃,导致数值无法更新;只有当增量累计超过0.00390625时,才会触发数值变化。

解决办法

针对该问题,可采用以下几种方案:

  • 改用更高精度的浮点类型:使用TwinCAT中的LREAL(64位双精度浮点数),其尾数为52位,在32768数值下的ULP约为1.4e-11,远小于0.001,完全支持小数值的累加操作。只需将变量声明改为fTest : LREAL := 32700.0;即可。
  • 分离基数与累加计数:用整数类型记录累加次数,最后再计算实际数值。例如:
    // declaration
    nAccumCount : INT := 0;
    fBaseValue : REAL := 32700.0;
    
    // implementation
    nAccumCount := nAccumCount + 1;
    fTest := fBaseValue + nAccumCount * 0.001;
    
  • 使用定点数存储:将数值放大为整数(比如放大1000倍),用整数类型存储累加,需要时再转换为REAL:
    // declaration
    iTest : DINT := 32700000; // 32700.0 * 1000
    
    // implementation
    iTest := iTest + 1; // 对应累加0.001
    fTest := iTest / 1000.0;
    

内容的提问来源于stack exchange,提问作者Pablo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:21:37