# String Conversion — DTOS, STOD, RTOS, STOR, UPPER, LOWER

Source: https://rungs.dev/docs/structured-text/instructions/string-conversion

> The Structured Text conversion instructions in rungs.dev turn numbers into text and text into numbers, and change the case of letters, each as a statement of its own.

A display shows text, and a barcode reader or a serial device sends text. Your logic works with
numbers. These instructions cross between the two, and change the case of letters so two pieces
of text can be compared whatever case they were typed in.

Each one is a **statement of its own** that writes its result into its last operand. None of
them gives back a value, so `Speed := STOD(Reply);` is refused: write `STOD(Reply, Speed);`.

```iecst
DTOS(PartCount, CountText);    (* -42 gives '-42' *)
STOD(Reply, Speed);            (* '1500 rpm' gives 1500 *)
RTOS(Temperature, TempText);   (* 21.5 gives '21.5000000' *)
STOR(Reply, Pressure);         (* 'P=2.75bar' gives 2.75 *)
UPPER(Typed, Code);            (* 'ab-12x' gives 'AB-12X' *)
LOWER(Typed, Code);            (* 'AB-12X' gives 'ab-12x' *)
```

## Operands [#operands]

| Instruction | Source                            | Destination               |
| ----------- | --------------------------------- | ------------------------- |
| `DTOS`      | a `DINT`, `INT`, `SINT` or `REAL` | a `STRING`                |
| `STOD`      | a `STRING`                        | a `DINT`, `INT` or `SINT` |
| `RTOS`      | a `REAL`                          | a `STRING`                |
| `STOR`      | a `STRING`                        | a `REAL`                  |
| `UPPER`     | a `STRING`                        | a `STRING`                |
| `LOWER`     | a `STRING`                        | a `STRING`                |

A source is a tag, or for `DTOS` and `RTOS` a number typed in, never an expression:
`DTOS(Count + 1, CountText);` is refused, so work `Count + 1` out into a tag first. Text in
quotes goes only in `:=` and in a comparison, never into these.

## What each one writes [#what-each-one-writes]

- **`DTOS`** makes a `REAL` a whole number first, the way `:=` stores a `REAL` into a `DINT`: a
  half goes to the even neighbour, so `2.5` gives `'2'` and `3.5` gives `'4'`. It clears the
  whole destination before it writes.
- **`STOD`** skips everything up to the first digit, then reads digits until something that is
  not one. A `-` counts only directly before the first digit, so `'SPD=-20'` gives `-20` and
  `'12.7'` gives `12`. No digit at all gives `0`. A number too large for a `DINT` is held to the
  `DINT` limit, with a warning; into an `INT` or a `SINT` it then wraps as any store does.
- **`RTOS`** always writes nine digits: eight decimals from `0.0001` up to `1`, nine digits in
  all from `1` up to `10000000`, and nine digits with an exponent otherwise, as in
  `'1.23456780e+07'`. Zero gives `'0.0'`. The digits are the `REAL`'s own, so `123.456` gives
  `'123.456001'`.
- **`STOR`** reads like `STOD`, then a decimal point and more digits, and an exponent such as
  `e3`. Text starting `0x` reads as hexadecimal: `'0x1F'` gives `31.0`. A number a `REAL` cannot hold gives `Infinity`, with a warning.
- **`UPPER`** and **`LOWER`** change only the letters `a` to `z` and `A` to `Z`.

When the source's `LEN` is outside `0` to `82`, none of them reads it: `UPPER` and `LOWER` leave
the destination as it was, `STOD` and `STOR` store `0`, and Studio shows a warning.

## Common Mistakes [#common-mistakes]

- Expecting `STOR` to read `'.5'` as `0.5`. It starts at the first digit, so it reads `5`.
- Expecting `STOD` to round. `'12.7'` gives `12`. Use `STOR` and then `:=` into a `DINT`.

## Related [#related]

- [String instructions](https://rungs.dev/docs/structured-text/instructions/string) — join, find and cut text
- [String conversion in Ladder](https://rungs.dev/docs/ladder-logic/instructions/string-conversion)