← Resources
Instructions·6 min read·

MOV, ADD and the rest: maths in ladder logic

Arithmetic in a rung is conditional, which changes how you have to think about it.

Short answer

Maths instructions in ladder sit on the output side, so they execute only while the rung is true. A MOV copies a source to a destination; ADD, SUB, MUL and DIV take two operands and a destination. Because they are conditional, an unconditional calculation needs an always-true rung, and integer division truncates rather than rounding.

How wide each type isBOOLone bitINT-32,768 to 32,767DINT±2.1 billionREALfloating pointA DINT holding a BOOL wastes 31 bits, and nobody notices until the tag count does.

Maths instructions live on the output side of a rung, which means they are conditional. That single fact accounts for most of the surprises.

Conditional by default

MOV(Setpoint, Target) behind a contact copies only while the contact conducts. Behind nothing, on an unconditional rung, it copies every scan.

Both are useful. Continuous scaling wants every scan. Capturing a value at a moment wants a condition and usually a one shot.

Integer division truncates

This catches everyone once. 5 / 10 in integer maths is 0. Scaling code written as (raw - offset) / span * range produces zero for almost every input, because the division happens first and throws away everything.

Multiply before you divide, or do the calculation in a REAL and convert at the end. The instruction order is the fix, not the data type alone.

Overflow is silent

An INT holds up to 32,767. Multiply two values that each look reasonable and the result wraps into a negative number with no error and no indication. If the operands can be large, use a DINT for the destination and the intermediate.

Where ladder stops being the right tool

Three nested calculations across six rungs is harder to read than four lines of Structured Text. Most platforms let you call an ST routine from ladder, and a calculation is exactly the thing worth moving.

Common questions

Why is my PLC division returning zero?
Integer division truncates. Dividing 5 by 10 in integer maths gives 0, not 0.5. Either multiply before you divide, so the intermediate value stays large, or use a REAL data type for the calculation and convert at the end.
Does a MOV instruction run every scan?
Only while its rung is true. A MOV on an unconditional rung runs every scan, which is usually what you want for continuous calculations. A MOV behind a condition runs only when that condition holds, which is what you want for latching a value.

Keep reading