Arithmetic operators
Operators
| Operator | Operand types | Result | Notes |
|---|---|---|---|
+ | ANY_NUM, both same type | same type | Addition |
- (binary) | ANY_NUM | same | Subtraction |
- (unary) | ANY_NUM (signed) | same | Negation. Unsigned types reject unary minus |
* | ANY_NUM | same | Multiplication |
/ | ANY_NUM | same | Division (integer truncates toward zero) |
MOD | ANY_INT | same | Integer remainder. Sign follows dividend |
** | ANY_REAL, exponent ANY_NUM | ANY_REAL | Exponentiation. Right-associative |
ANY_NUM covers the integer types (SINT/INT/DINT/LINT
and unsigned variants) and the real types (REAL/LREAL).
ANY_INT is the integer subset only.
Type-matching rule
Both operands of a binary arithmetic operator must have the
same IEC type. matiec does not promote INT to DINT
or INT to REAL automatically. Use the explicit conversion
functions when types differ:
(* INT + DINT — needs explicit promotion *)
dwSum := INT_TO_DINT(iCount) + dwBig;
(* INT * REAL — needs INT_TO_REAL or REAL division of INT *)
rArea := INT_TO_REAL(iWidth) * INT_TO_REAL(iHeight);
(* unary minus on UINT — illegal *)
(* iN := -uVal; (* fails *) *)
iN := -UINT_TO_INT(uVal);
Integer overflow
Integer arithmetic does not trap on overflow. SINT#127 + 1
silently wraps to SINT#-128. If overflow detection matters,
either use a wider type for the calculation:
diSum := SINT_TO_DINT(iA) + SINT_TO_DINT(iB);
IF diSum > 127 OR diSum < -128 THEN ... END_IF;
…or guard against the operands ahead of time.
REAL precision
REAL is IEEE-754 single precision (~7 decimal digits).
LREAL is IEEE-754 double (~15 digits). Comparing REAL
values with = is unsafe — always use a tolerance:
IF ABS(rA - rB) < 0.0001 THEN ... END_IF;
IEC reference
IEC 61131-3 third edition (2013), clause 6.6.1 Table 55 — “Operators of the ST language”.
matiec conformance
matiec implements the standard arithmetic operators correctly.
The two main pitfalls are documented in llm_signals above:
- Strict type-matching (no implicit promotion).
MODis integer-only.
There is no ** emit-bug but performance of ** on a PLC
is poor (it lowers to a pow() call). Prefer x * x * x
over x ** 3 for small constant exponents in scan-cycle code.