← 所有文章

FIELD NOTES / PLC 程式與控制

百分比變更率遇到前值為零 如何定義結果

PLC 程式與控制作者:站長預估 7 分鐘閱讀

以 本例 說明百分比變更率、零前值、負前值、極小基準與百分點的分離,保留 delta 與狀態原因。

本文目錄

一 先分辨變更量 相對百分比與百分點

百分比變更率要先寫清楚分母。當 old>0,本篇採 change_percent=(new-old)/old×100。100 變成 120 是 +20%,100 變成 80 是 -20%。這個數字描述相對於前值的比例,不是差值本身;同一筆資料還應保存 delta=new-old,避免使用者把 +20% 與 20 個單位混在一起。

old=0 時傳統公式沒有定義。0 變成 10 的 delta 是 +10,但百分比變更率不能自動寫 0%、100% 或 infinity。0 變成 0 同樣沒有傳統百分比分母,雖然 delta=0 且可標記 NoChange。系統應輸出明確狀態,例如 BaselineZero,並將 delta、old、new 與規則版本一併留存。

百分點用在兩個比例或比率的差值。20% 變成 25% 是 +5 percentage points;若以原比例作相對變更,則是 (25-20)/20×100=+25%。兩者回答不同問題,欄位名稱不可只叫 change。顯示介面應分開呈現 delta_units、relative_percent 與 percentage_points。

old new delta 相對變更率 狀態
100 120 +20 +20% Defined
100 80 -20 -20% Defined
0 10 +10 未定義 BaselineZero
0 0 0 未定義 NoChange/BaselineZero
20% 25% +5個百分點 +25% 兩種指標並列

計算前應把欄位狀態分成 HasBaseline、Defined、Undefined 與 Rejected,而不是只用一個布林值。old=0、new=10 是有前值且 delta 有定義,但 relative_percent 未定義;沒有前值則連 delta 的變更語義也不成立。這個區分可避免介面把「零基準」誤畫成通訊故障。

第一個有效值沒有可比較的前值時,也應使用 BaselineMissing,而不是拿 0 當基準。缺少前值時delta也未定義;報表可另顯示目前new值,但delta與變更率均維持未建立狀態。這樣下游不會把尚未建立基準誤認為製程沒有變動。

二 負前值與方向解讀

當 old<0,傳統公式仍可計算,但方向直覺可能改變。例:old=-10、new=-5,delta=+5,代入 (−5−(−10))/−10×100 得 -50%。數學上結果是 -50%,但實際數值向零移動;若操作員把負號解讀成下降,就會得到錯誤結論。報表要同時顯示 delta 的符號與分母正負。

若需求是保留數值增減方向、以舊值幅度作尺度,可以另定signed_normalized_percent=delta/abs(old)×100。它不是幅度本身的相對變更;幅度變更需另算(abs(new)-abs(old))/abs(old)。上述例子會得到 +50%,但這是另一個明確命名的指標,不能把它偷偷取代傳統公式。old=-10、new=-15 時 delta=-5,abs 分母指標為 -50%,表示距離零點增加而數值更負。兩種規則都要在資料契約中固定。

對溫度、壓差、偏差量等可能為負的資料,先問清楚工程意義:是比較有號數值,還是比較幅度、能量或距離?若單位或量測零點改變,跨版本直接算百分比也可能失真。應保存 unit、scale、calibration_version 與 baseline_source,拒絕把不同定義硬接成一條曲線。

案例 old→new delta 傳統公式 可選幅度指標
偏差A -10→-5 +5 -50% +50%
偏差B -10→-15 -5 +50% -50%
電流 4→6 A +2 A +50% 同值
不同版本 10→12,scale改變 +2 需先換同單位 不可直接比較

負值還要考慮零點校正造成的符號翻轉。若同一設備先以 -0.2 bar 讀值,校正後變成 +0.1 bar,傳統百分比會被小負分母放大;報表應先比對校正版本與物理零點,再決定是否只呈現 delta 與跨零事件。跨零可另標 CrossingZero,不用單一百分號承擔方向解釋。

驗收時把負值案例放進測試矩陣,明確確認顯示欄位的名稱與符號。不要用「百分比必須向上就是正」這類口號修正結果;應回到公式、分母與指標語義,並讓操作員能看到原始 old、new、delta。

百分比需要有意義的比例尺度。攝氏溫度零點是約定,10°C到20°C不能直接宣稱物理溫度加倍;即使算出100%,也不代表適合的工程指標。溫度可先報差幾°C,需要絕對溫度比值時再用適當的絕對尺度。

三 極小基準 單位與版本

即使 old 不等於零,極小基準也會放大噪聲。假設 old=0.01、new=0.02,公式給 +100%;若感測器解析度是 0.01,這可能只是由一個量化階跳到下一階,不能直接當重大製程變化。規格可設定 baseline_floor,例如 abs(old)<0.05 時只輸出 delta 並標 SmallBaseline,但門檻要由工程需求決定,不能把 0.05 當通用標準。

單位換算要在計算前完成。若 old 是 1000 mL、new 是 1.2 L,先轉成相同單位後 delta=200 mL、相對變更 +20%;若把數字直接代入,會得到 -99.88% 的錯誤結果。資料欄位需帶 unit,並拒絕將版本不同的縮放係數當成同一量測。

保留 raw_old、raw_new、工程值、conversion_version 與計算時間。當校正係數從 v1 改為 v2,歷史資料可選擇重算,但重算結果要標明 derived_version,不覆蓋原始快照。若前值來自另一批次或另一設備,狀態應是 BaselineMismatch,而不是正常變更率。

情況 old new 處理 狀態
極小基準 0.01 0.02 可算delta,依門檻停用相對率 SmallBaseline
同單位 1000mL 1200mL 先換同單位 Defined +20%
不同單位 1000mL 1.2L 轉成1200mL Defined +20%
校正版本變更 v1值10 v2值12 先核對conversion_version BaselineMismatch/重算
缺前值 10 保存10作基準 BaselineMissing

門檻不應只寫一個數字而沒有單位。對流量可用 0.1 L/min,對有號偏差量可用0.05工程單位;若資料由整數縮放而來,門檻應在轉換後工程單位判斷。當 old=0.04、new=0.06 且門檻為 0.05 時,delta=0.02 可保存,但相對率應標 SmallBaseline;當 old=0.06 才按定義計算。

顯示格式化只在最後一步做。計算時保留足夠精度,避免先把 0.0199 顯示成 0.02 再拿顯示值計算。若 PLC 使用整數縮放,先以整數 raw 計算差值或轉成明確工程型別;不要假定不同控制器的 REAL、LREAL 或除法捨入方式相同。

四 零分母排查與批次驗收

實作流程可分五步:讀取 old/new 與品質;確認兩筆單位和版本一致;計算 delta;本例有號分母版本在old非零且abs(old)不低於門檻時計算relative_percent;old為負時另標NegativeBaseline。正分母限定的報表則應拒絕負基準,不能與本例混用。任何一步失敗都保留原始資料,不能以 0、100 或 infinity 填補。

假設 本例 在 09:00 讀到 old=100,09:05 讀到 new=120,應記錄 delta=20、relative_percent=20%、status=Defined。另一組獨立案例仍以old=100為基準、new=80,才是delta=−20、relative_percent=−20%;若順接120→80,結果應為−33.333…%。若 09:10 讀到 old=0、new=10,輸出 delta=10、relative_percent 未定義、status=BaselineZero;操作畫面可顯示「需建立基準」。

排查一筆異常時先核對 raw 與單位,再看 baseline_source、conversion_version 和時間排序。若看到 infinity,通常是零分母未攔截;若看到 100%,可能是程式把 old=0→new>0 強制視為滿幅變化;若負值方向讓人困惑,檢查是否把 abs 分母指標誤標成傳統百分比。

測試案例 輸入 預期 delta relative_percent reason
正常上升 100→120 20 20% Defined
正常下降 100→80 -20 -20% Defined
零到十 0→10 10 未定義 BaselineZero
零到零 0→0 0 未定義 NoChange/BaselineZero
負前值 -10→-5 5 -50% NegativeBaseline
小基準 0.01→0.02 0.01 依門檻停用 SmallBaseline

驗收時還要測試順序錯亂與重複樣本。09:05 的 new 先到、09:00 的 old 後到,不能把兩者直接當正常前後值;應以 timestamp 或 sequence 判定 OutOfOrder。相同 sequence 重送則只保留一次。這些狀態與零分母狀態不同,分開記錄才能知道是公式問題、資料時間問題,還是來源重送。

若要將結果送往 HMI 或歷史資料庫,建議同時寫入 calculation_rule、baseline_status、delta、relative_percent、unit 與 source_timestamp。relative_percent 未定義時不要寫空白後讓資料庫自動轉零,而應寫 NULL 並以 status 解釋原因。報表排序也要依 timestamp 或 sequence,而不是依完成寫入順序,避免重連後晚到的資料把前值關係倒置。

五 驗收 FAQ 與來源

本題的驗收基準是:100→120 得 +20%,100→80 得 -20%,0→10 只得 delta +10 且變更率未定義,0→0 仍未定義,20%→25% 同時顯示 +5 個百分點與相對 +25%。負前值 -10→-5 使用傳統公式得到 -50%,如採有號差除舊值幅度的指標則另列+50%,不可混名。

完成測試後,將計算結果與 reason 一起寫入稽核紀錄,並以固定的公式版本供報表重現。算例與流程已核對;實際資料型別、時間戳與持久化仍需在選定平台驗證。

FAQ1:old=0、new=10 能否顯示 +100%?答:不能。傳統分母為零,應顯示 delta=+10 與 BaselineZero;是否另定百分比必須建立明確業務指標。

FAQ2:20% 變 25% 是 +5% 還是 +25%?答:差值是 +5 個百分點;以 20% 為分母的相對變更是 +25%。兩欄應分開命名。

FAQ3:負前值 -10 變 -5 為何是 -50%?答:依傳統有號分母公式,delta=+5、分母=-10,所以是 -50%。若要表達有號值增減,可另列delta/abs(old)的+50%;真正幅度由10減到5則是−50%,三者不可混名。

FAQ4:極小 old 可以照算嗎?答:數學上可算,但結果可能被量化噪聲放大。應依資料契約設 baseline_floor,停用或標記 SmallBaseline,保留 delta 與原始資料。

參考:Python math 官方文件:浮點、有限值與數值運算參考,非控制器資料型別保證。

延伸閱讀