SCL Mathematics: Arithmetic, Comparison, Logic, and Conversion Operators
Complete SCL operator reference: arithmetic (+, -, *, /, MOD, **), comparison (<, >, =, <>), logic (AND, OR, XOR, NOT), type conversion (INT_TO_REAL, DINT_TO_REAL), and numeric functions (ABS, SQRT, SIN, COS). With precedence rules and data type behavior.
SCL Mathematics: Arithmetic, Comparison, Logic, and Conversion Operators
This reference covers all mathematical and logical operators available in Siemens SCL (Structured Control Language), including operator precedence, data type rules, and type conversion functions. SCL follows the IEC 61131-3 Structured Text standard with Siemens-specific extensions.
Arithmetic Operators
| Operator | Meaning | Example | Result Type |
|---|---|---|---|
+ | Addition | a + b | Larger of the two operand types |
- | Subtraction | a - b | Larger of the two operand types |
* | Multiplication | a * b | Larger of the two operand types |
/ | Division | a / b | Larger type; INT / INT = INT (truncated) |
MOD | Modulo (remainder) | 17 MOD 5 → 2 | INT or DINT |
DIV | Integer division | 17 DIV 5 → 3 | INT or DINT |
** | Power (exponent) | 2.0 ** 3.0 → 8.0 | REAL |
+ (unary) | Positive sign | +a | Same as operand |
- (unary) | Negative sign | -a | Same as operand |
Data type rules for arithmetic:
- INT + INT = INT
- INT + DINT = DINT (result takes the larger type)
- REAL + INT = REAL (floating-point wins)
- REAL + REAL = REAL
- INT / INT = INT (truncated, not rounded: 7 / 2 = 3, not 3.5)
- To get a REAL result from INT division: convert first, then divide
Example — Integer vs. REAL division:
// WRONG: integer division truncates
result_int := 7 / 2; // result_int = 3 (not 3.5)
// RIGHT: convert to REAL first
result_real := INT_TO_REAL(7) / INT_TO_REAL(2); // result_real = 3.5
Comparison Operators
All comparison operators return BOOL (TRUE or FALSE).
| Operator | Meaning | Example |
|---|---|---|
= | Equal to | IF a = 10 THEN |
<> | Not equal to | IF a <> 0 THEN |
< | Less than | IF temp < 100.0 THEN |
> | Greater than | IF pressure > 5.0 THEN |
<= | Less than or equal | IF level <= max_level THEN |
>= | Greater than or equal | IF count >= preset THEN |
Data type rules for comparison:
- Both operands must be compatible types
- INT can be compared with DINT (implicit conversion)
- REAL comparisons: beware of floating-point precision (use a tolerance band for equality checks)
Example — Floating-point comparison with tolerance:
// WRONG: exact equality on REAL is unreliable
IF temperature = 100.0 THEN ... // may never be exactly 100.0
// RIGHT: use tolerance band
IF ABS(temperature - 100.0) < 0.1 THEN ... // within 0.1 degrees
Logical Operators
Logical operators work on BOOL values. When applied to WORD/DWORD, they operate bitwise.
| Operator | Meaning | Example | Precedence |
|---|---|---|---|
NOT | Negation | NOT a | Highest (7) |
AND or & | Logical AND | a AND b | 8 |
XOR | Exclusive OR | a XOR b | 9 |
OR | Logical OR | a OR b | Lowest (10) |
BOOL examples:
// Motor runs if start pressed AND no fault AND not stopped
Motor := Start AND NOT Fault AND NOT Stop;
// Alarm if temperature too high OR pressure too high
Alarm := (Temp > 80.0) OR (Pressure > 6.0);
// Toggle: changes state on each call when trigger is TRUE
IF Trigger AND NOT Trigger_Old THEN
Toggle := NOT Toggle;
END_IF;
Trigger_Old := Trigger;
Bitwise example (WORD):
// Mask bits 0-3 of a WORD
masked := input_word AND W#16#000F; // keeps only lower 4 bits
// Set bit 7
output_word := input_word OR W#16#0080;
// Toggle bit 4
output_word := input_word XOR W#16#0010;
Operator Precedence (Highest to Lowest)
| Priority | Operator | Category |
|---|---|---|
| 1 | ( ) | Parentheses |
| 2 | + - (unary) | Sign |
| 3 | NOT | Negation |
| 4 | ** | Power |
| 5 | * / MOD DIV | Multiplicative |
| 6 | + - | Additive |
| 7 | < > <= >= | Relational |
| 8 | = <> | Equality |
| 9 | AND & | Logical AND |
| 10 | XOR | Exclusive OR |
| 11 | OR | Logical OR |
| 12 | := | Assignment (lowest) |
Rule of thumb: Arithmetic first, then comparison, then logic. When in doubt, use parentheses — they make the code more readable and prevent precedence errors.
Type Conversion Functions
SCL requires explicit conversion between incompatible types. On S7-1500, many conversions happen implicitly, but explicit conversion is best practice for portability and clarity.
Numeric Conversions
| Function | From → To | Example |
|---|---|---|
INT_TO_REAL | INT → REAL | r := INT_TO_REAL(i); |
INT_TO_DINT | INT → DINT | d := INT_TO_DINT(i); |
DINT_TO_REAL | DINT → REAL | r := DINT_TO_REAL(d); |
REAL_TO_INT | REAL → INT | i := REAL_TO_INT(r); (rounded) |
REAL_TO_DINT | REAL → DINT | d := REAL_TO_DINT(r); (rounded) |
DINT_TO_INT | DINT → INT | i := DINT_TO_INT(d); (truncated if > 32767) |
BCD Conversions (Legacy Compatibility)
| Function | From → To | Use Case |
|---|---|---|
BCD_TO_INT | BCD WORD → INT | Reading S5-style counter/timer values |
INT_TO_BCD | INT → BCD WORD | Writing to BCD displays |
DINT_TO_BCD_DWORD | DINT → BCD DWORD | Large BCD values |
Bit/Byte Conversions
| Function | From → To |
|---|---|
BOOL_TO_BYTE | BOOL → BYTE |
BYTE_TO_WORD | BYTE → WORD |
WORD_TO_DWORD | WORD → DWORD |
BYTE_TO_INT | BYTE → INT |
WORD_TO_INT | WORD → INT |
DWORD_TO_DINT | DWORD → DINT |
S7-1500 universal conversion: On S7-1500, you can also use the CONVERT instruction or implicit conversion in many cases.
Numeric Functions (Math Library)
| Function | Description | Example | Result |
|---|---|---|---|
ABS(x) | Absolute value | ABS(-5) | 5 |
SQR(x) | Square (x²) | SQR(4.0) | 16.0 |
SQRT(x) | Square root | SQRT(16.0) | 4.0 |
EXP(x) | e^x | EXP(1.0) | 2.7183 |
EXPD(x) | 10^x | EXPD(2.0) | 100.0 |
LN(x) | Natural logarithm | LN(2.7183) | ~1.0 |
LOG(x) | Common logarithm (base 10) | LOG(100.0) | 2.0 |
SIN(x) | Sine (x in radians) | SIN(1.5708) | ~1.0 |
COS(x) | Cosine (x in radians) | COS(0.0) | 1.0 |
TAN(x) | Tangent (x in radians) | TAN(0.7854) | ~1.0 |
ASIN(x) | Arc sine | ASIN(1.0) | ~1.5708 |
ACOS(x) | Arc cosine | ACOS(0.0) | ~1.5708 |
ATAN(x) | Arc tangent | ATAN(1.0) | ~0.7854 |
All trigonometric functions use radians, not degrees. To convert: radians := degrees * 3.14159 / 180.0;
Practical Example: Analog Scaling
A common real-world application combining arithmetic, conversion, and comparison:
// Scale raw analog input (0–27648) to engineering units (0.0–100.0 bar)
VAR
raw_value : INT; // From analog input module
pressure : REAL; // Engineering units
high_alarm : BOOL;
END_VAR
pressure := INT_TO_REAL(raw_value) * 100.0 / 27648.0;
high_alarm := pressure > 85.0; // Alarm at 85 bar
Analyze Your S5 Arithmetic Code
PLCcheck Pro converts S5 arithmetic operations (+F, -F, ×F, :F) to clean SCL with correct type handling and overflow protection.
Upload code for conversion → | S5→S7 Migration Guide →
Part of the SCL Reference. Maintained by PLCcheck.ai. Not affiliated with Siemens AG.
Related Articles
Converting Ladder Logic to Structured Text: Why and How
When and how to convert PLC ladder logic (LD/KOP/LAD) to Structured Text (ST/SCL). Covers the benefits, conversion patterns, what to keep in ladder, and practical examples.
8 min read
migration-guideSTL/AWL Deprecation in S7-1500: Why You Must Convert to SCL
Why AWL/STL runs only in emulation mode on S7-1500, what that means for performance and maintainability, and how to convert your STL code to SCL. Includes conversion strategy and code examples.
10 min read
thought-leadershipTIA Portal vs. STEP 7 Classic: Key Differences for Migrators
Side-by-side comparison of Siemens TIA Portal and STEP 7 Classic (SIMATIC Manager). Interface, programming, hardware support, licensing, and migration path.
10 min read
Analyze your PLC code with AI
PLCcheck Pro explains, documents, optimizes, and migrates PLC code — automatically.
Try PLCcheck Pro →Not affiliated with Siemens AG. S5, S7, STEP 5, STEP 7, and TIA Portal are trademarks of Siemens AG.