Learn PLCs free
Programming Guides12 min read2,300 words

PLC Math Instructions: ADD, SUB, MUL, DIV, and CPT Explained

PLC math instructions explained — ADD, SUB, MUL, DIV, MOD, and the compute (CPT) instruction, integer vs float pitfalls, overflow, and ladder examples.

PPI
PLC Programming IO Editorial Team
Sourced guidance with documented review and correction standards

PLC math instructions are the backbone of every calculation a controller performs — from simple tank-level totals to multi-variable PID setpoint conversions. Yet they trip up more engineers than almost any other instruction type, because the rules for integer truncation, division order, and overflow behavior are subtle and platform-specific. This guide walks through every core arithmetic instruction, shows you exactly where precision disappears and why, and gives you tested ladder rung patterns you can adapt today.

PLC Math Basics

A PLC executes math instructions during the output scan — the processor evaluates the rung condition (normally an XIC or always-true rung), performs the operation, and writes the result to a destination tag before moving on. Two things govern every math result:

  • Data type of the destination tag. The processor does not automatically promote operands to a wider type. If your destination is INT (16-bit signed), the result is truncated to fit — silently.
  • Math status flags. After every math instruction, the processor updates status bits: Carry (C), Overflow (V/OV), Zero (Z), and Sign (S). These sit in the processor status file (Allen-Bradley: S2:0; Siemens: stored per block in the accumulator flags). If you are not reading them, you may never know a result was clipped.

Understanding these two points before writing a single rung saves hours of late-night troubleshooting.

PLC math instruction ADD SUB MUL DIV MOD overview with Source A Source B Dest structure Horizontal flow showing the six core PLC arithmetic instructions, each with Source A and Source B inputs and a Dest output, arranged across the viewBox with colour-coded operation symbols. Core PLC Math Instructions — Source A OP Source B → Dest ADD + Src A + Src B → Dest Watch: overflow SUB Src A − Src B → Dest Watch: sign type MUL × Src A × Src B → Dest Use DINT dest! DIV ÷ Src A ÷ Src B → Dest (truncates) MUL before DIV! MOD % Remainder of Src A ÷ Src B Batch triggers CPT Full expr one rung AB Logix All instructions share the same structure: Enable contact — [ ADD/SUB/MUL/DIV ] — Source A: tag — Source B: tag — Dest: tag (data type determines range)
PLC math instruction overview: ADD, SUB, MUL, DIV, MOD, and CPT all share the Source A / Source B / Dest structure. The destination data type governs the result range — use DINT or REAL when overflow is possible.

The Basic Instructions (ADD, SUB, MUL, DIV, MOD, NEG, ABS)

Every IEC 61131-3-compliant PLC supports a standard set of arithmetic instructions. In Allen-Bradley (Logix) ladder, each appears as a box on the rung. Siemens TIA Portal uses equivalent FC blocks or inline Structured Text. The inputs are labeled Source A, Source B, and Dest (destination).

ADD — Addition

|----[  ]----------[ ADD ]----------|
|  Start_PB    Source A: Tank_Liters |
|              Source B: Fill_Liters |
|              Dest:     Total_Liters|

Adds Source A and Source B, stores the sum in Dest. Simple — until the sum exceeds the destination data type's maximum. For a 16-bit signed INT, that maximum is 32,767. Add 20,000 + 15,000 into an INT destination and you get –30,537 with the Overflow flag set.

Rule: If accumulated values can exceed 32,767, use DINT (32-bit, max 2,147,483,647) or REAL (32-bit float).

SUB — Subtraction

Source A: Setpoint_Temp
Source B: Actual_Temp
Dest:     Error_Temp

Subtracts Source B from Source A. Watch the sign: if Actual exceeds Setpoint, Error becomes negative. Make sure your destination tag is a signed type — an unsigned UINT destination wraps around on negative results.

MUL — Multiplication

Multiplication is the instruction most likely to overflow silently. Two INT values multiplied together can produce a result requiring 32 bits.

Source A: RPM_Scaled   (INT, max 3,000)
Source B: Gear_Ratio   (INT, max 12)
Dest:     Output_RPM   (INT)

3,000 × 12 = 36,000. That overflows a 16-bit signed INT. Always promote at least one operand or the destination to DINT before multiplying.

DIV — Division

Integer division discards the fractional remainder entirely — it does not round, it truncates toward zero.

Source A: 7   (INT)
Source B: 2   (INT)
Dest:     3   (INT)   ← not 3.5

This matters enormously in scaling calculations. See the Integer vs Floating-Point section for the full impact.

MOD — Modulo (Remainder)

MOD returns what DIV discards — the integer remainder after division.

Source A: 17  (INT)
Source B: 5   (INT)
Dest:     2   (INT)   ← because 17 = (5 × 3) + 2

Practical uses include batch counting (trigger every N cycles: MOD(Cycle_Count, Batch_Size)), converting a raw second counter into minutes and seconds, and distributing product across lanes.

NEG — Negate

Flips the sign of Source A. Equivalent to multiplying by –1 but faster and cleaner. Useful when subtracting a value that is already computed as a negative error.

ABS — Absolute Value

Returns the magnitude of Source A regardless of sign. Essential for dead-band comparisons:

ABS(Error) < Deadband → inhibit output

The CPT/Compute Instruction (Full Expression)

The Compute (CPT) instruction (Allen-Bradley Logix) lets you write a full mathematical expression in a single rung rather than chaining multiple math boxes. The expression evaluates left-to-right with standard algebraic precedence unless you add parentheses.

|----[  ]----[ CPT ]-------------------------------------|
|            Dest: Scaled_EU                             |
|            Expression:                                 |
|            (Raw_Input - Raw_Min) * EU_Span /           |
|            (Raw_Max - Raw_Min) + EU_Min                |

This is the canonical analog scaling formula — the same one used in PLC analog input scaling. Written as five separate math boxes it requires five tags and five rungs; the CPT collapses it to one.

Key CPT rules:

  • The CPT destination data type governs the final result type, but the expression evaluates internally at the widest type used — mix a REAL operand and the entire expression promotes to REAL.
  • Parentheses are fully supported and strongly recommended.
  • Division-before-multiplication pitfalls still apply if all operands are integers — see the next section.
  • Siemens TIA Portal has no direct CPT equivalent; use an inline Structured Text assignment instead (see Structured Text programming guide).

Integer vs Floating-Point (Truncation, Division Order Pitfalls)

This is the section that saves production lines.

The Classic Integer Division Pitfall

Suppose you need to convert a raw 0–4095 ADC count to 0–100% and you write:

CPT Expression: Raw_Count / 4095 * 100

With integer operands, this evaluates left-to-right:

  1. Raw_Count / 4095 → truncates to 0 for any Raw_Count below 4095
  2. 0 * 1000

Your scaling output is 0% for the entire range except exactly full-scale. The fix is to multiply before dividing:

CPT Expression: Raw_Count * 100 / 4095

Now step 1 produces a number up to 409,500, and step 2 performs a meaningful division. The result is still an integer (no decimal places), but the error is at most ±1 count rather than losing the entire value.

The golden rule: in integer math, multiply before dividing.

Integer division truncation pitfall in PLC ladder logic — divide before multiply loses precision Side-by-side comparison showing wrong order divide-then-multiply giving zero output versus correct multiply-then-divide preserving value across the 0-4095 raw ADC count range. WRONG — Divide First CPT: Raw_Count / 4095 * 100 500 / 4095 INT truncates = 0 0 × 100 = 0 Output across full range (0–4095): 0% output for ALL inputs below 4095 Integer truncation: 500÷4095 = 0 Entire scaling range lost Result: always 0% CORRECT — Multiply First CPT: Raw_Count * 100 / 4095 500 × 100 = 50,000 50000 ÷ 4095 ≈12 Output across full range (0–4095): ~12% for input=500 Max error: ±1 count only Scaling preserved across range Use REAL() cast for decimal places
Integer division pitfall: dividing before multiplying (Raw/4095*100) truncates to zero for all inputs below 4095. The fix is to multiply before dividing (Raw*100/4095) — or cast to REAL for decimal precision.

Doing It Right with REAL

For any measurement that needs decimal precision, declare your destination tag as REAL and cast at least one operand:

CPT Expression: REAL(Raw_Count) / 4095.0 * 100.0

The REAL() conversion instruction promotes Raw_Count to a 32-bit float. The division now yields a true fractional result. The destination Scaled_EU receives a value like 73.486...

REAL limitations to know:

  • REAL uses IEEE 754 single precision: 7 significant decimal digits. For values above ~10,000,000 with decimal fractions, precision degrades.
  • Never compare REAL values with equal-to (EQU) — use a dead-band (ABS(A - B) < Tolerance).
  • Conversion from REAL back to DINT truncates, not rounds. Add 0.5 before converting if you need rounding: TRUNC(Value + 0.5).

Overflow and Math Status Flags

Every arithmetic instruction sets processor status bits on completion. In Allen-Bradley ControlLogix, these are in the Math Status Flags area of the GSV instruction or accessible via the Controller Status file. In RSLogix 5/500 (SLC/MicroLogix), they live in S2:0.

Flag Name Set when
S Sign Result is negative
Z Zero Result is exactly zero
V / OV Overflow Result exceeds destination range
C Carry Unsigned overflow (carry out of MSB)

How to use them in ladder:

|----[ ADD ]----[ OSR ]----[ SET ]------|
|              OV_Flag    Math_Alarm    |

Read the Overflow flag immediately after the math instruction using a One-Shot Rising (OSR) to latch a Math_Alarm bit. This prevents silent data corruption from propagating to downstream logic.

Siemens S7: the ENO (Enable Out) output of a math block goes low on overflow or divide-by-zero. Wire it to a fault coil or use #RET_VAL for structured error handling in function blocks.

PLC math overflow status flags Sign Zero Overflow Carry bits in Allen-Bradley ControlLogix Diagram showing the four math status flag bits set after each arithmetic instruction, with explanation of when each flag activates and how to use the Overflow flag to detect silent integer overflow in ladder logic. Math Status Flags — Set After Every Arithmetic Instruction S Sign Flag Set when result is negative AB: S2:0 bit 3 Z Zero Flag Set when result equals exactly 0 AB: S2:0 bit 2 V/OV Overflow Flag Result exceeds destination range Critical — check this! C Carry Flag Unsigned carry out of MSB AB: S2:0 bit 0 Recommended pattern — read OV flag immediately after math instruction: [ ADD ] → [ OSR OV_Storage OV_Pulse ] → [ OTL Math_Overflow_Alarm ] Flags reset on every math instruction — read on same or very next rung or they are overwritten
Math status flags: the Overflow (V/OV) flag is the most critical to monitor — it activates silently when the result exceeds the destination type's range. Read it on the same rung using an OSR to latch a fault alarm before the next instruction resets it.

Order of Operations in CPT Expressions

CPT expressions follow standard algebraic precedence — but knowing the exact order prevents surprises:

PLC CPT compute instruction analog scaling formula 4-20mA raw count to engineering units Flow diagram showing the CPT compute instruction evaluating the analog scaling expression from raw ADC integer input through REAL casting, subtraction, multiplication, division and addition to produce engineering unit output. CPT Analog Scaling: (REAL(Raw) − RawMin) × EU_Span ÷ (RawMax − RawMin) + EU_Min Raw_AI INT 0–32767 4–20 mA REAL() cast to float − RawMin 6554.0 (= 4 mA) × EU_Span 10.0 m (range) ÷ RawSpan 26213.0 (20−4 mA) + EU_Min 0.0 (offset) CPT Dest: Level_Metres (REAL) Result: 0.0 m at 4 mA → 10.0 m at 20 mA — full decimal precision, no truncation All operands are REAL — REAL() cast on Raw_AI promotes the entire expression to floating-point arithmetic
CPT analog scaling pipeline: casting the raw integer to REAL first ensures all subsequent operations (subtract, multiply, divide, add offset) execute in floating-point, preserving decimal precision from 0.0 to 10.0 m.
  1. Parentheses — evaluated innermost first
  2. FunctionsABS(), SQRT(), SIN(), LN(), etc.
  3. Unary negation-x
  4. Exponentiation** or XPY
  5. Multiplication, Division, Modulo — left to right
  6. Addition, Subtraction — left to right

When in doubt, use parentheses. A rung that reads (A + B) * C / D is unambiguous; A + B * C / D may not do what you expect.

Common mistake:

CPT: Average = A + B / 2       ← computes A + (B/2)
CPT: Average = (A + B) / 2     ← correct

Worked Examples

Example 1 — Averaging Three Tank Levels

Problem: Average three level transmitter readings (0–100%, stored as REAL) to get a blended fill level.

CPT Dest:       Avg_Level_PCT
CPT Expression: (Tank1_PCT + Tank2_PCT + Tank3_PCT) / 3.0

Using 3.0 (a float literal) ensures the division is floating-point even if the source tags were integers. Store result in a REAL destination.

Example 2 — Unit Conversion (PSI to Bar)

Problem: Convert a pressure reading in PSI to Bar for display on an HMI using the European convention.

CPT Dest:       Pressure_Bar
CPT Expression: Pressure_PSI * 0.0689476

Keep Pressure_Bar as REAL. If you need one decimal place on the HMI, scale the display in the HMI tag rather than truncating the PLC value — preserve precision at the source.

Example 3 — Analog Scaling (Raw Count to Engineering Units)

This is the most common real-world application of CPT. A 4–20 mA level transmitter wired to a 0–32767 count analog input module needs converting to 0–10.0 metres.

CPT Dest:       Level_Metres
CPT Expression: (REAL(Raw_AI) - 6554.0) / (32767.0 - 6554.0) * 10.0

Where 6554 = 20% of 32767 (representing 4 mA). For the full derivation and clamping logic for sensor faults, see the dedicated PLC analog input scaling tutorial.

Example 4 — Batch Counter with MOD

Problem: Signal a batching alarm every 100 cycles without resetting the master counter.

CPT Dest:       Batch_Remainder
CPT Expression: MOD(Cycle_Count, 100)

|---[EQU Batch_Remainder = 0]---[OTE Batch_Alarm]---|

When Cycle_Count reaches 100, 200, 300... the remainder is zero and the alarm fires for one scan.

Siemens and Allen-Bradley Platform Notes

Allen-Bradley (Logix 5000 / Studio 5000)

  • The six individual instructions (ADD, SUB, MUL, DIV, MOD, NEG) and the CPT instruction are all available in ladder and function block diagram.
  • Tag-based addressing: use descriptive tag names (Motor_Speed_RPM) rather than file addresses.
  • For REAL math, ensure the destination tag is declared REAL in the tag database — the instruction does not auto-promote.
  • SQRT, SIN, COS, TAN, LOG, LN, DEG, RAD are available inside CPT expressions.
  • Math overflow sets the Minor Fault bit (Type 4, Code 4) if configured in Controller Properties → Minor Faults.

Allen-Bradley (SLC 500 / MicroLogix)

  • Math instructions write to integer files (N7) by default. Use float files (F8) for REAL operations.
  • CPT is available on SLC 5/03 and higher with OS 302 or later.
  • The math status flags are in S2:0 bits 0–3 and are reset on every math instruction — read them on the same rung or the next rung immediately.

Siemens TIA Portal (S7-1200 / S7-1500)

  • Ladder math blocks are available but most Siemens engineers prefer Structured Text (SCL) for math-heavy code — see Structured Text programming guide.
  • Explicit type casting is required: INT_TO_REAL(), REAL_TO_INT().
  • No CPT equivalent; use a single SCL assignment: Scaled_EU := (REAL(Raw_Input) - Raw_Min) * EU_Span / (Raw_Max - Raw_Min) + EU_Min;
  • The ENO output of each math block goes low on error (overflow, divide-by-zero). Connect it to a diagnostic bit or use structured error handling.

For a broader comparison of how math fits across all IEC 61131-3 languages, see the PLC programming languages complete guide. For the data types that underpin every math decision — signed/unsigned integers, REAL, DWORD — the PLC data types explained article goes deeper.


Frequently Asked Questions

What are PLC math instructions?

PLC math instructions are ladder logic (or function block) commands that perform arithmetic operations — addition, subtraction, multiplication, division, modulo, negation, and absolute value — on tag values stored in the controller's memory. They execute once per scan when their rung condition is true and write the result to a destination tag.

What is the CPT instruction?

The Compute (CPT) instruction, available in Allen-Bradley Logix platforms, evaluates a full algebraic expression (including nested functions like SQRT or SIN) in a single rung and writes the result to one destination tag. It replaces a chain of individual math boxes and supports standard operator precedence with parentheses.

Why does integer division lose precision?

When both operands and the destination are integer types, the PLC discards the fractional part of the quotient — it does not round. 7 / 2 stores 3, not 3.5. For scaling calculations this can produce zero output across most of the input range if you divide before multiplying. The fix is to multiply before dividing (to keep numbers large) or to cast at least one operand to REAL before dividing.

How do you do math in ladder logic?

Place a math instruction box (ADD, SUB, MUL, DIV, or CPT) on a rung with a controlling contact. Set Source A and Source B to the input tags and Dest to the output tag. Ensure the destination tag's data type is wide enough for the largest possible result. For expressions involving division or fractional results, declare the destination as REAL and cast integer sources using REAL() before the operation.

#plcmath#ADDSUB MUL DIV#CPT#compute#integeroverflow#ladderlogic
Share this article:

Related Articles