# MOVE / MVM — Copy a Value

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

> MOVE copies a literal or tag into a destination tag every scan in rungs.dev, converting between DINT and REAL when the types differ. MVM is a masked move that copies only selected bits.

Copies a source value (literal or tag) into a destination tag. When the source and destination are different numeric types, `MOVE` is also how you **convert** between them.

## Operands [#operands]

| Name     | Type                                |
| -------- | ----------------------------------- |
| `source` | `DINT` \| `INT` \| `SINT` \| `REAL` |
| `dest`   | `DINT` \| `INT` \| `SINT` \| `REAL` |

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

When the rung is true, `source` is read and written to `dest` **every scan**. When the rung is false, `MOVE` does nothing and `dest` keeps its last value.

## Example — Change a Timer Preset at Run Time [#example--change-a-timer-preset-at-run-time]

Set a timer's preset based on which mode the machine is in.

```ladder
XIC(ModeFast)MOVE(2000,CycleTimer.PRE);XIC(ModeSlow)MOVE(8000,CycleTimer.PRE)
```

While `ModeFast` is selected, `CycleTimer.PRE` is held at `2000`. While `ModeSlow` is selected, it is held at `8000`.

## Example — Copy a Reading [#example--copy-a-reading]

```ladder
XIC(SampleNow)MOVE(TempSensor,LastSample)
```

## Type Conversion [#type-conversion]

Studio has no separate `_TO_` conversion instructions (no `REAL_TO_DINT`, no `DINT_TO_REAL`). Conversion happens **automatically** when `MOVE`'s source and destination types differ.

> **INFO**
>
> **Modeled on Studio 5000 Logix Designer**
>
> Conversion behavior in [rungs.dev](https://studio.rungs.dev) follows the same conventions as Studio 5000 Logix Designer®.

### DINT → REAL (lossless for most values) [#dint--real-lossless-for-most-values]

A `DINT` value is copied into a `REAL` with a decimal point added. For everyday values this is exact:

| Source (`DINT`) | Destination (`REAL`) |
| --------------- | -------------------- |
| `7`             | `7.0`                |
| `-1000`         | `-1000.0`            |
| `16777216`      | `16777216.0`         |

A `REAL` can represent integers exactly up to about **16.7 million**. Above that, the conversion is rounded to the nearest representable value. For example, `16777217` becomes `16777216.0`. You'll only hit this with large counters or accumulators — for everyday tags it's not something to worry about.

### REAL → DINT (banker rounding) [#real--dint-banker-rounding]

The fractional part has to go somewhere, so Studio uses **banker rounding** — also called _round half to even_. Halves go to the nearest even integer; non-halves round normally.

| Source (`REAL`) | Destination (`DINT`) |
| --------------- | -------------------- |
| `0.5`           | `0`                  |
| `1.5`           | `2`                  |
| `2.5`           | `2`                  |
| `3.5`           | `4`                  |
| `-2.5`          | `-2`                 |
| `1.4`           | `1`                  |
| `1.6`           | `2`                  |

```
MOVE(2.5, DintTag)   // DintTag = 2
MOVE(3.5, DintTag)   // DintTag = 4
```

For more on why halves round to the nearest even number rather than always up, see the [Arithmetic and Comparison Operators](https://rungs.dev/docs/structured-text/arithmetic-and-comparison-operators) page.

### REAL → DINT overflow [#real--dint-overflow]

After rounding, a finite `REAL` that is outside the DINT range overflows into the stored 32-bit DINT bit pattern. For example, `2147483648.0` stores as `-2147483648`.

### REAL → DINT with non-finite values [#real--dint-with-non-finite-values]

If the source is `+Infinity`, `-Infinity`, or `NaN` (which can happen after a divide-by-zero), Studio **clamps** the value to the DINT range so an integer tag never holds a non-numeric value.

| Source (`REAL`) | Destination (`DINT`) |
| --------------- | -------------------- |
| `+Infinity`     | `2147483647` (MAX)   |
| `-Infinity`     | `-2147483648` (MIN)  |
| `NaN`           | `0`                  |

## Masked Move (MVM) [#masked-move-mvm]

`MOVE` overwrites the _whole_ destination. `MVM` is a **masked move**. Copies the Source bits that the Mask lets through into the destination, leaving the destination bits under a 0 mask bit unchanged. Where a mask bit is `1`, that bit of `dest` takes the Source value; where a mask bit is `0`, that bit of `dest` keeps what it had.

| Name     | Type                      |
| -------- | ------------------------- |
| `source` | `DINT` \| `INT` \| `SINT` |
| `mask`   | `DINT` \| `INT` \| `SINT` |
| `dest`   | `DINT` \| `INT` \| `SINT` |

```ladder
MVM(StatusWord,16#00FF,Result)
```

With mask `16#00FF`, only the low 8 bits of `StatusWord` are copied into `Result`; the top 24 bits of `Result` are left untouched. A mask of `16#FFFFFFFF` copies everything (the same as `MOVE`); a mask of `0` copies nothing. Write the mask in [hexadecimal or binary](https://rungs.dev/docs/structured-text/arithmetic-and-comparison-operators) so the passed-through bits are obvious.

Unlike `MOVE`, `MVM` works on bit patterns, so its operands are whole numbers — `DINT`, `INT` or `SINT`. There is no `REAL` masked move.

## Common Mistakes [#common-mistakes]

- Moving a `REAL` into a `DINT` destination without expecting **rounding** — the fractional part is gone, and halves snap to the nearest even integer (so `2.5 → 2`, not `3`).
- Treating `MOVE` as a free transfer between any two types — it works for numbers (`DINT` ↔ `REAL`), but not for structured types like `TIMER` or `COUNTER`.
- Expecting `MVM` to clear the bits the mask blocks — it doesn't. Bits under a `0` mask bit keep their current destination value; use `CLR` or a plain `MOVE` first for a clean slate.

## Related [#related]

- [Logical & bit instructions](https://rungs.dev/docs/ladder-logic/instructions/logical) — `AND` / `OR` / `XOR` / `NOT` combine words bit-by-bit, `CLR` clears one, and `BTD` moves a run of bits
- [Compare instructions](https://rungs.dev/docs/ladder-logic/instructions/compare) — inspect values rather than move them
- [Math instructions](https://rungs.dev/docs/ladder-logic/instructions/math) — compute values, then `MOVE` or assign directly
- [Arithmetic and Comparison Operators](https://rungs.dev/docs/structured-text/arithmetic-and-comparison-operators) — full division, rounding, and coercion rules