先說清楚底數與輸入單位
對數常用於跨大範圍顯示或比例指標,但輸入零、負值或底數錯誤時,可能把資料問題帶到後續計算。本篇帶你先寫對數的條件,再用一組可重算測試值驗收,避免用任意很小正數取代所有錯誤輸入。
實數對數log_b(x)要求x大於零,底數b大於零且不等於一。自然對數ln使用底數e,常用對數log10使用底數十。ln(1)與log10(1)都等於零,但相同其他輸入通常不同,因此只用一測試會漏掉選錯函式的問題。
對數中的比值應有明確的量綱處理。例如以壓力P與參考壓力P0相除,先確保兩者使用相同單位,再對無因次比值P/P0取對數。不要一個用bar、一個用kPa就直接相除,否則可能多出固定倍率偏移。
本例先採log10(x),x為已正規化且有效的正比值。輸出允許為負,因為0<x<1的常用對數本來就是負數。不能把輸出負值誤判成運算失敗;要檢查的是輸入與結果狀態,而不只是數字是否大於零。
本文為實數數學與資料流程教學,不指定通用PLC對數指令。不同CPU與語言對無效輸入、非有限數與例外的反應不同,外部函式庫的行為不能直接套到Q系列,實作前仍要查實際指令手冊。
對數資料的原始比值與輸出應分欄保存,欄位名稱不要都叫Value。若同一條通訊路徑先由感測器取對數,再由PLC取一次,數字可能仍在可計算範圍內,卻已變成錯誤的二次轉換。資料字典應指定由哪一層負責這項運算。
先用四個正常值驗證底數
常用對數的基本向量是x=0.1得到−1,x=1得到0,x=10得到1,x=100得到2。每個輸入相差十倍,輸出相差一。先以這四筆檢查使用的是log10,避免把ln結果拿去套本來以十為底的公式。
自然對數則ln(1)=0、ln(e)=1、ln(10)約2.302585、ln(100)約4.605170。若x=10時讀到約2.302585,先查選用函式,不要先把結果用經驗常數壓成1。若需要換底,公式應明確寫log_b(x)=ln(x)/ln(b)。
換底公式也有前置條件。b=1時ln(b)=0,會造成除零;b小於或等於零不在這個實數定義域。0<b<1則仍是合法底數,例如log_0.1(10)=−1,只是函數隨x增加而下降,工程需求若不允許再另加限制。
練習反算以檢查底數是否一致:常用對數輸出y=2,反算10^2=100;y=−1反算10^−1=0.1。若正算用ln、反算卻用10的次方,即使每一步都有數學結果,也不能還原原輸入。
浮點反算通常採允差比對而非逐bit相同。測試表記輸入、底數、預期值、允差和實際值;允差要依格式與應用需要決定,不能為了讓錯底數通過而設得很寬。輸入與輸出量程也應在表中清楚列出。
零負值與過小正值分開回報
x=0沒有有限的實數對數,x<0在本文實數模型也不成立;主策略是回報DomainError,不產生本次有效結果。畫面若保留上次值,要附上過期時間與錯誤原因,不能讓保留值看起來像是零或負輸入的正確對數。
有些設計會把x小於某下限時夾到正值epsilon,但那改變了資料。若epsilon=0.001,log10的輸出下限會是−3;它不是log10(0)的真實結果。若產品需求採此顯示策略,應保存原輸入、夾限狀態與epsilon版本。
本例嚴格拒絕零與負值,並把過小但正的數值依工程門檻另行判定。例子x=0.0001在數學上log10等於−4;若工程有效下限明訂0.001,則回報BelowEngineeringRange,原因不能混寫成數學定義域錯誤。
接近零的正輸入對相對誤差可能敏感,來源量測解析度也可能不足。先確認正值是實際有效資料,還是通訊無效碼、初始化預設或浮點下溢結果。若前一步已丟失資訊,對數函式無法把真實量測救回來。
底數非常接近一時,ln(b)很小,換底結果可能非常大且對誤差敏感。除了b不等於一的數學檢查,工程上可另定允許底數區間與結果範圍。門檻需有用途依據,不應把所有接近一的底數都通用判成非法。
對自訂底數的工程設定,核對輸入值與底數是否屬同一設定版本。若計算途中底數被另一來源改寫,結果可能不能重現;先取得一致的計算輸入,再把使用的底數版本保存到結果紀錄。
完成後的結果與排查順序
驗收順序先確認資料品質和比值單位,再確認x與b的定義域,接著計算,最後檢查結果是否有限且可用。記錄第一個失敗原因與原值,不讓後續運算繼續使用未更新結果。每次計算的狀態應和數值一起交付。
測試表至少包含常用對數四個正常值、零、負一、數學合法但工程過小的正值,以及底數一。換底版本再測底數0.1與十,確認方向和倍率。錯誤列標無有效結果,不用零占位後讓下游誤以為輸入是比值一。
如果正常值差固定倍率,先查ln與log10混用;如果差固定偏移,查輸入是否多乘或少乘倍率,因log10(100x)=log10(x)+2。若只在很小值出現極端結果,查輸入量程、解析度、epsilon與下溢處理。
若處理分貝或其他專用量,不要僅因需要對數就自行選10或20倍。具體公式取決於物理量與參考定義,必須另查應用規格。本篇只驗證一般對數流程,不把某一倍率宣稱成所有壓力、功率與振動訊號都通用。
完成後應讓讀者能說出輸出負值何時正常、零輸入為何不能當合法零結果,以及工程夾限改變了什麼。本文數值可重算;實際型別、完成與錯誤訊號仍待平台確認。
加入一個先成功後失敗的序列:輸入十得到一,下一輪輸入零應使本輪有效旗標失效,第三輪輸入一百才更新為二。若第二輪畫面仍顯示一,必須同時顯示過期與錯誤;不可把保留值誤算成零輸入的本次結果。
常見問題
問:log10輸出負數是不是失敗?答:不是,0到1之間的正輸入會得到負輸出,例如0.1得到−1。
問:log10(0)可以填零嗎?答:不能,零輸出對應輸入一;零輸入應回報無有效實數結果。
問:把所有小值改成epsilon可以嗎?答:只有明訂夾限策略才可,必須保留原值和狀態,不能冒充原始對數。
問:底數小於一都非法嗎?答:大於零且不等於一仍合法,是否適用再由工程需求決定。
參考:Python math官方文件,log、log10及相關數學函式;非PLC API。
參考:NumPy log官方文件,自然對數定義與實數輸入限制;不推定PLC例外行為。