← 所有文章

累加器長時間運算如何檢查回捲與精度損失

· 站長

以uint32回捲、old 4294967290到new 7與binary32在2^24附近精度損失案例,建立整數權威、reset epoch與顯示分離流程。

一 累加器先分整數與顯示值

長時間累加常見兩種錯誤:把有限寬度的計數器當成永遠不會回捲,或把浮點顯示值當成計數權威。本篇案例 先採 uint32 計數器,最大值 4294967295;若計數器沒有 reset 且真實增量小於 2^32,差值可用模 2^32 計算。

整數權威欄位保存 raw_counter、last_counter、delta、total_uint64 或更寬的工程累計值;display_value 只是格式化結果。若設備只提供 uint32 回讀,長期 total 仍需由應用層保存回捲次數或更寬資料,不能把畫面上的十進位字串再轉回浮點當權威。

回捲公式成立有前提:沒有中途 reset,且兩次讀取間真實增加量小於模數。若停機時間太久或事件速率太高,增加量可能已達模數,單次 new-old 無法判斷。此時應標記 Ambiguous,要求縮短取樣週期或使用硬體提供的更寬計數。

欄位 型別角色 用途 限制
raw_counter uint32 設備目前計數 可能回捲
last_counter uint32 上次有效快照 reset後不可直接相減
delta uint32/uint64 本次增量 需檢查模數前提
total_authoritative 更寬整數 長期累計 需保存回捲/重啟狀態
display_value 格式化數值 HMI/報表 不可反作權威

計數器讀取要盡可能形成一致快照。若高低字分開讀取,回捲或更新可能發生在兩次讀取之間,組合值未必是某一時刻的真值。本文不指定廠牌讀取指令,實作前需查目標設備是否提供鎖存、雙讀比對或一致性旗標;沒有證據時應標記 snapshot_uncertain。

資料快照要帶 sample_time、quality、reset_marker 和 counter_epoch。若來源品質無效,不更新 last_counter;若發現 reset,重新建立基線,不能把重啟後的小值當成巨大負差。

二 模數回捲逐步計算

本篇案例 的邊界案例是 old=4294967290、new=7。若期間真實只增加 13,模數差為 (7-4294967290) mod 4294967296=13。計算可以拆成 new>=old 的普通差,或 new<old 時以 (MAX-old+1)+new;本例new<old才附帶wrap_detected=1;普通增加分支不設定回捲。這仍以無reset且真增量小於模數為前提。

另一案例 old=100、new=80。若另有可信速率上限,能證明這段間隔不可能增加4294967276,這筆資料才與模型不符,不能把 2^32-20 當成真實增量。先查 reset、通訊快照一致性、來源代號和讀取順序,再決定是否拒收。

old new 假設 delta 狀態
4294967290 7 真增量13且未reset 13 ValidWrap
100 130 普通增加 30 Valid
100 80 速率上限排除巨量增量 拒收 UnexpectedDecrease
50 5 發現重啟 不計算 ResetBaseline
4294967290 10 可能跨多次回捲 不確定 Ambiguous

如果來源可能在一次取樣間跨過兩次回捲,即使算式得到一個小正數,也不能宣稱正確。驗收應先用最大事件速率與最長取樣間隔估計上限,要求真實增量遠小於 4294967296;否則改用更寬計數或縮短週期。

回捲判斷還要用最大速率做上限估算。假設來源每秒 1000 次、最長 10 分鐘未讀,可能增加 600000,尚小於 2^32;若來源每秒 10000000 次,同樣 10 分鐘可能增加6000000000,超過模數,模數差的唯一解前提失效;是否跨幾次邊界還取決於起點。這個計算應列入取樣週期設計。

回捲事件應寫入事件紀錄,包含 old、new、epoch、sample_time、delta_rule 和 reset evidence。不要因畫面總量連續就刪掉 raw,因為回捲判斷需要原始快照。

模數差是數學公式,實作前須先確保減法不會在有號三十二位元中溢位。可使用經核對的更寬型別或平台明訂的無號模數運算;不能先算錯再取餘數,也不能假設所有PLC整數溢位都自動回捲。

三 binary32 精度損失

IEEE 754 的浮點格式不是所有 REAL 都相同。以 binary32 為例,有效精度有限;當數值接近 2^24=16777216 時,加 1 可能不改變儲存結果。這不表示每個 PLC 的 REAL 都一定是 binary32,而是提醒必須依目標型別與手冊核對,不能用「REAL 都一樣」推論。

離線示例:若 float32 累計值已是 16777216,再做 +1,採最近且一半取偶數的binary32捨入時,結果仍是16777216;加2得到可精確表示的16777218。若用它累計脈衝,少量增量會消失,且後續差值看不出哪一輪漏掉。整數計數器應保持權威,浮點只在需要工程單位或畫面格式時轉換。

累計時間也要小心。若每輪用 float32 加 dt=0.001 s,長時間後相鄰可表示值間距可能大於 0.001;應以整數 tick 或更寬型別保存時間,再在計算或顯示時轉換。單位必須明確是秒、毫秒或 tick,不能同時混用。

情境 權威表示 風險 驗收方式
脈衝總數 uint32/uint64 回捲與reset 查epoch與delta
工程累積量 整數原量×比例 浮點小增量消失 抽查原始計數
累計時間 整數tick/更寬整數 dt單位錯或精度不足 核對tick到秒
HMI顯示 格式化REAL 顯示捨入 不可回寫權威

浮點精度測試要指定格式,而不是只寫 REAL。可用離線程式把整數轉成 binary32,測試 16777216、16777217、16777218 的表示結果,再把結果與目標平台實際資料型別文件比對。若平台使用不同精度,應建立另一組測試,不能直接沿用 binary32 結論。

顯示轉換應最後一次完成,並保留原始整數。若工程量是每脈衝 0.01 L,先用整數 total_count,再以 total_count×0.01 產生顯示;不要每輪把顯示後的 12.34 L 再加 0.01,避免捨入漂移。

四 重啟 reset與資料驗收

重啟後不能直接沿用 RAM 中的 last_counter,除非該資料的保持性與一致性已由目標平台和工程設計確認。安全流程是讀取來源計數、取得 reset/epoch 證據,建立新 baseline,將本次delta標示為未建立增量;若內部以零暫存,也必須附baseline-only狀態,不能聲稱期間真增量是零,並在事件中記錄 BaselineAfterRestart。

若設備有明確 reset command,reset 前後應分成兩個 epoch。reset 前最後值不能和 reset 後第一個小值相減;如果 reset 期間仍可能有事件,還要由設備規格定義是否遺失。應用層不能只看數字變小就自動補回 2^32。

長期驗收可用三段:正常增加 100→130 得 30;回捲 4294967290→7 得 13;重啟後 500→12 先建立基線不計算。再加入 binary32 顯示測試,確認畫面格式不會覆寫整數權威。

所有異常都要有 reason:CounterWrap、UnexpectedDecrease、ResetBaseline、AmbiguousGap、InvalidSample 或 PrecisionDisplayOnly。這些狀態應與 delta、total、sample_time 一起交付;只顯示「累計正常」不足以讓人追查。

累計時間積分也要保留原始 dt。若每輪只更新 total_seconds,發生通訊停頓或時鐘倒退後就無法重算。保存 tick_before、tick_after、dt_units、time_epoch 和 quality,可把「資料真實增加」與「計時不可靠」分開。

若總量需要跨重啟保存,應把 epoch、累積回捲次數與保存時間一起備份;只有一個 total 數字不足以判斷它是否曾被reset。

本文是離線數學與資料設計教學,沒有使用特定 PLC 的回捲寄存器或特殊指令。IEC 61131-3 的語言標準不等於某平台的記憶體保持和計數器規格,實作前仍需查目標型號手冊。

五 驗收 FAQ與來源

本篇案例 通過條件是:uint32 最大值寫對;old=4294967290、new=7 得 13;跨多次回捲被標記不確定;reset 後建立新基線;binary32 在 2^24 附近的 +1 不被當成可靠整數累加;整數權威與顯示值分離;累計時間單位與來源明確。

FAQ1:old=4294967290、new=7 為何是 13?答:在沒有 reset 且真實增量小於 2^32 的前提下,(7-4294967290) mod 4294967296=13。

FAQ2:看到 new 比 old 小就一定是回捲嗎?答:不一定。可能是 reset、來源換代、讀取錯序或多次回捲;要先查 epoch、取樣間隔與最大速率。

FAQ3:binary32在2^24加1會怎樣?答:採最近且一半取偶數時會捨回2^24;不同捨入模式需另查。PLC的REAL是否採此格式和運算模式,也要由平台確認。

FAQ4:可以用 HMI 顯示的浮點總量當累加器權威嗎?答:不可以。整數計數與回捲狀態保存為權威,浮點只用於工程單位顯示或明確的計算結果。

參考:NumPy finfo官方文件:浮點精度及格式參數,僅供數值驗算參考。

延伸閱讀


使用 PLC 工具箱 →