轉換前先決定哪些資訊可以丟掉
溫度 2.9 轉成整數,應該得到 2 還是 3?兩種答案都可能符合某種需求,卻不能在同一個控制程式裡隨意交換。先寫出要截斷、取最近整數,或保留一位小數,再選指令。這篇以 CODESYS 文件中的 REAL_TO_INT 與 TRUNC_INT 為對照,帶你把型別、範圍、有效旗標一起設計。
我們的虛擬來源是 REAL 量測值,目的欄位是 16 位有號 INT,範圍 −32768~32767。轉換後還要輸出 Valid 與 Error,讓下一段程式知道這次數字可不可用。案例不連接輸出,也不把這些函式名稱當成三菱 Q 系列可直接使用的指令。
| 需求 | 做法 | 會失去什麼 |
|---|---|---|
| 只要整數部分 | 向零截斷 | 正負小數部分 |
| 取最接近的整數 | 按明訂規則取整 | 小數細節,中點另有規則 |
| 保留0.1單位 | 先定義倍率與整數存法 | 低於0.1的解析度 |
| 解碼原始位元 | 依原型別重新解讀 | 不能用數值轉換代替解碼 |
例如 IEEE 754 單精度 1.0 的位元圖樣是 16#3F800000。把這些位元當成無號整數,會得到 1065353216;真正做 1.0 的數值轉換則得到整數 1。兩者不是精度差,而是你問了不同的問題。通訊讀到兩個暫存器時,先確認資料型態與字組排列,再決定如何解碼。
用正負小數看懂兩種轉換
CODESYS 官方 TRUNC_INT 說明只取整數部分,正負值都向零。例如 −2.9 截斷後是 −2,不是 −3。REAL_TO_INT 依其文件進行取整;本表選用不在中點的值,避免把中點策略和一般取整混為一談。
| 輸入 | TRUNC_INT | REAL_TO_INT文件預期 | 要學會的判斷 |
|---|---|---|---|
| 2.9 | 2 | 3 | 截斷與取整不同 |
| −2.9 | −2 | −3 | 負數截斷往零靠近 |
| 2.1 | 2 | 2 | 部分值看不出差異 |
| −2.1 | −2 | −2 | 不能只測一組正數 |
| 0.9 | 0 | 1 | 小值轉換可能變成零 |
| −0.9 | 0 | −1 | 正負都要驗收 |
先在紙上填完兩欄,再在目標工程軟體中建立來源與結果監看。如果只測 2.1,兩種函式都得到 2,你可能誤以為它們一樣。一定要包含 2.9、−2.9 與接近零的數,才會看到資訊怎麼消失。若平台提供不同名稱,照同一組測試輸入驗收,不靠函式名字猜。
參考:CODESYS TRUNC_INT 整數部分與負數示例
參考:CODESYS REAL LREAL Conversion 與 Rounding
先做範圍檢查 再允許轉換
本例採保守接受規則:來源必須有效、有限,而且位於 −32768~32767,才執行轉換。32767.9 即使截斷有機會落回範圍,本例仍拒絕,讓兩種轉換共用清楚的輸入契約。若你的規格需要接受這種邊界,必須另外定義取整後檢查的安全方法。
先檢查來源品質,通訊失敗或感測器無效時,不執行正常數值轉換。
確認來源是有限數,處理 NaN 與正負無限大;使用目標平台有文件支持的檢查方式。
依本例先比對上下界,超出便令 Valid=0、Error=RANGE,不更新結果。
範圍通過後才呼叫選定的轉換,令 Valid=1,清除本次錯誤。
後續程式同時使用結果與 Valid;若保留上一筆數值,畫面應明示那是舊值。
| 測試輸入 | 本例接受 | 預期處理 |
|---|---|---|
| 32767 | 是 | 可轉成32767 |
| −32768 | 是 | 可轉成−32768 |
| 32767.9 | 否 | 先拒絕,不呼叫轉換 |
| 40000 | 否 | RANGE錯誤 |
| NaN/無限大 | 否 | INVALID錯誤 |
| 來源品質無效 | 否 | 保留原因,不把舊值冒充新值 |
不要先把 REAL 轉成 INT,再用 INT 看有沒有大於 32767:超範圍的資訊可能已經消失。官方文件指出超出目標範圍可能產生未定義或目標系統相關結果,因此不能把某次觀察到的負數當成可靠的溢位通知。
讓錯誤值不再偷偷參與計算
設計結果介面時,把 Converted、Valid、Error 與原始值保留在同一個可觀察區域。假設上一筆 12.8 成功轉為13,下一筆收到40000,這次Converted可以仍是13,但Valid必須為0。使用者看到「13 目前無效」和看到正常13,意思完全不同。
| 次序 | 原始值 | Converted | Valid | 說明 |
|---|---|---|---|---|
| 1 | 12.8 | 13 | 1 | 使用最近整數策略 |
| 2 | 40000 | 13 保留 | 0 | 拒絕新值,禁止當作新量測 |
| 3 | −2.9 | −3 | 1 | 來源恢復且在範圍內 |
若把結果寫成0當作錯誤替代,也必須保留無效旗標;因為正常的0.1截斷也會變成0,單靠數字無法分辨。控制策略要另定義無效時停止、保持或降級,本篇不替任何機械指定安全動作。這裡只要求錯誤與正常資料不能混在一起。
失敗時先查運算型別和選用函式,再查來源是否已被前一段縮放、截斷或字組交換。監看上顯示2.9不一定代表儲存值剛好2.9;需要看足夠有效位數與原始型別。尤其是多次放大縮小後的數,應回到最初來源逐段核對,不要再加一個常數修正結果。
動手建立轉換驗收紀錄
先建立一張測試紀錄,左側依序放來源值、來源型別、來源有效性,中間放所選策略,右側放結果、結果有效性與錯誤原因。不要只留一個轉換後的數字。假如改用截斷,表格標題也應同步改成截斷,避免下一位維護人員拿取最近整數的答案來判斷程式。
第一輪只使用範圍內資料。先輸入正的小數,再輸入其負值,最後輸入零附近的正負小數。每次都先在紙上寫答案,再觀察目標系統結果。若答案不同,先確認實際呼叫的是哪一個函式,以及來源是否在進入函式之前就被別的運算轉成整數。
第二輪測試有效性切換。先送入正常資料,再送入超界資料,最後恢復正常。觀察的重點是錯誤當下有效旗標是否立即清除,以及恢復後錯誤是否依本次結果更新。保留的舊值應帶時間或序號,讓畫面能說明它不是剛收到的新值,不能只靠顏色讓操作員猜。
第三輪才測上下界。邊界測試應從已知有效值走向邊界,再跨出邊界,記錄是哪一個條件拒絕資料。本文採原始值先檢查的保守規則,因此某些轉換後看似可容納的輸入也會被拒絕。這是介面契約的選擇,不是轉換指令故障;驗收表要清楚註明。
若來源是一個十六位無號通訊欄位,不能直接套用本例的有號上下界。先查資料字典,再決定要接成無號整數、有號整數或固定小數。相同位元在不同型別下可以有不同意思;例如全一位元在無號解讀下是最大正值,在十六位二補數解讀下則是負一。
最後把轉換規則放進欄位說明:來源單位、來源型別、目標型別、取整規則、允許範圍與無效時的處理都要齊全。這份說明能讓通訊、畫面與控制程式使用相同定義。日後量程改大,先重新計算範圍與解析度,再修改程式,不要只把錯誤旗標關掉。
完成驗收與適用限制
完成後應得到表中的六組正負小數結果,所有超界和無效輸入都被拒絕,且下游不使用Valid=0的結果。測試記錄至少包含CPU、Runtime與編譯器版本、來源型別、轉換函式、原值與結果;只有手算表完成,不等於PLC驗證已完成。
常見問題
TRUNC 是往下取整嗎?本篇的 TRUNC_INT 是向零取整;−2.9變−2。若需求是數學上的floor,必須另選正確方法。
轉成較大整數就能保留小數嗎?不能。較大位寬增加的是整數範圍,小數仍要靠浮點或明訂倍率保存。
把顯示小數位改成0算轉換嗎?不算。畫面可能只改格式,PLC內儲存值仍含小數。請檢查真正送到下一個運算的資料。
適用型號與限制:具體函式依據為 CODESYS Development System 線上文件,查閱2026-09-17;Q06UDVCPU/GX Works2、其他PLC或Runtime的函式與例外行為須另核對。本例只教轉換設計與離線驗收,未指定任何設備暫存器或已編譯程式。