# CMP — Compare

Source: https://rungs.dev/docs/ladder-logic/instructions/cmp

> CMP (Compare) works out an expression and uses the answer as the rung condition. Any value other than zero passes power. Covers AND versus &&, and why a bare bit needs XIC.

Works out an expression and uses the answer as the rung condition. Any value other than zero passes
power.

`CMP` is an **input** instruction, so it sits on the left of the rung like a contact:

```
CMP(Level > HighSetpoint) OTE(Alarm)
```

Where [`GT`](https://rungs.dev/docs/ladder-logic/instructions/compare) compares exactly two values, `CMP` takes a whole expression, so you can
ask a question that would otherwise need several boxes and a scratch tag.

## Operands [#operands]

`CMP` has one operand: the `expression` itself — tags and typed-in values of type `SINT`,
`INT`, `DINT` or `REAL`, joined by operators. What you can write in it is below.

## How It Works [#how-it-works]

| Answer            | Rung             |
| ----------------- | ---------------- |
| Anything but zero | Power carries on |
| Zero              | Power stops      |

**Any value other than zero is true**, and the sign does not matter:

| `CMP(…)`                       | Rung |
| ------------------------------ | ---- |
| `CMP(5)`                       | on   |
| `CMP(0)`                       | off  |
| `CMP(-1)`                      | on   |
| `CMP(Count)` with `Count = -1` | on   |

So `CMP(Count)` asks "is Count anything other than zero?". A comparison like `Count > 5`
answers 1 or 0, which fits the same rule.

## What you can write in the expression [#what-you-can-write-in-the-expression]

Everything [`CPT`](https://rungs.dev/docs/ladder-logic/instructions/cpt) takes, plus:

- the comparisons `<` `<=` `>` `>=` `=` `<>`
- the logical operators `&&` ("both"), `||` ("either"), `^^` ("exactly one"), `!` ("not")
- `IsINF` and `IsNAN`, which test a `REAL` for infinity or for "not a number"

### `AND` is bitwise, `&&` means "both" [#and-is-bitwise--means-both]

This is the one that catches everybody. `AND` `OR` `XOR` `NOT` work on the **bits inside a
number**, not on conditions.

With `Count = 2` (binary `10`):

| Expression               | What happens                       | Rung |
| ------------------------ | ---------------------------------- | ---- |
| `Count AND 1`            | `10` AND `01` — no bit set in both | off  |
| `(Count > 0) && (1 > 0)` | both comparisons are true          | on   |

Writing `Count > 1 AND Limit < 5` is an **error**, not a slow way of getting the right answer.
To join two comparisons use `&&`:

```
CMP((Count > 1) && (Limit < 5))
```

If you already write Structured Text this will feel wrong — there, `AND` between two
comparisons does mean "both". Inside a ladder box, keep `AND` for bits and `&&` for conditions.

### Testing a single bit [#testing-a-single-bit]

`CMP(Running)` on its own is not allowed. To test one bit, use [`XIC`](https://rungs.dev/docs/ladder-logic/instructions/xic):

```
XIC(Running) OTE(Lamp)
```

A bit is fine inside a larger test, though — `CMP(!Running)` and `CMP(Running && Ready)` both
work.

## Example — Tank Level Alarm [#example--tank-level-alarm]

Raise an alarm when the tank is above the high setpoint **and** the pump is not already running.

```ladder
CMP((In_Level > Cfg_HighSetpoint) && !Sts_PumpRunning)OTE(Out_Alarm)

In_Level = 85
Cfg_HighSetpoint = 80
Sts_PumpRunning = 0
```

The level is 85 and the setpoint is 80, so the first comparison is true; the pump is stopped, so
`!Sts_PumpRunning` is true as well. Both true, so the alarm comes on.

## Common Mistakes [#common-mistakes]

- Using `AND` to join two comparisons. Use `&&`.
- Putting `CMP` at the end of a rung. It is an input, so something has to follow it.
- Testing a single bit with `CMP`. Use [`XIC`](https://rungs.dev/docs/ladder-logic/instructions/xic) or [`XIO`](https://rungs.dev/docs/ladder-logic/instructions/xio).
- Comparing two decimals for exact equality. `REAL` values keep about seven digits, so a
  calculated value rarely lands on the number you expect. Compare against a range instead:
  `CMP(ABS(Measured - Target) < 0.01)`.

## Related [#related]

- [CPT](https://rungs.dev/docs/ladder-logic/instructions/cpt) — the same expressions, used to store a number
- [Expressions in Ladder](https://rungs.dev/docs/ladder-logic/expressions) — operator order, decimals, and the traps
- [Compare instructions](https://rungs.dev/docs/ladder-logic/instructions/compare) — `EQ`, `GT` and friends, one comparison per box