DINT_TO_REAL converts a 32-bit signed integer (DINT) into a 32-bit floating-point value (REAL), so integer counts — encoder pulses, raw analog values, totals — can enter fractional math like scaling, averaging and flow calculations.
Join 1900+ learners practicing PLC programming
How it works
The two data types split the world between them. A DINT is a 32-bit signed integer: exact, fast, the natural type for counts — encoder pulses, raw ADC values, part totals — covering −2,147,483,648 to 2,147,483,647 with no fractions. A REAL is a 32-bit IEEE-754 float: it holds fractions and huge ranges, but stores only about 7 significant digits. Real programs constantly cross the boundary — a flow total in pulses needs dividing by pulses-per-litre, a raw analog count needs scaling to engineering units — and DINT_TO_REAL is that crossing, in the integer-to-float direction.
In Studio 5000 the conversion happens two ways. Implicitly: ladder instructions convert between numeric types whenever operands differ, so MOV Encoder_Counts Flow_REAL, or a DIV with a DINT input and a REAL destination, quietly performs the conversion — most AB programs never write the conversion explicitly at all. Explicitly: in Structured Text, DINT_TO_REAL(Encoder_Counts) makes the conversion visible, which is the style IEC 61131-3 platforms enforce — CODESYS and TIA Portal are strictly typed, and DINT_TO_REAL (TIA: DINT_TO_REAL conversion box, or CONVERT in LAD) is a standard-defined function, one member of the big TYPE_TO_TYPE conversion family.
The precision trap is the part worth reading twice. A REAL’s mantissa holds 24 bits, so every integer up to 16,777,216 (2²⁴) converts exactly — and beyond that, a REAL cannot represent every integer. Convert a DINT of 16,777,217 and you get 16,777,216.0; at a billion, the gaps between representable floats are 64 wide. A totalizer that accumulates in REAL (or converts a large DINT total for display) stops counting individual events long before the DINT itself would overflow. The professional pattern: accumulate in DINT (or LINT), convert late, and if a running total must be fractional, use scaled-integer techniques or 64-bit floats where the platform offers them (LREAL).
The reverse direction — REAL_TO_DINT — has its own rule: rounding. Logix rounds to nearest with ties going to the even number (2.5 → 2, 3.5 → 4), IEC REAL_TO_DINT rounds to nearest, and truncation requires asking for it (TRUNC / TRN). Any conversion pair in a loop (DINT → REAL → math → DINT) should be audited for where the rounding happens — once per scan of accumulated rounding error is a genuine drift bug.
Across vendors
| Platform | Name / syntax | Notes |
|---|---|---|
| Allen-Bradley (Studio 5000) | Implicit / DINT_TO_REAL (ST) | Ladder converts implicitly whenever operand types differ (MOV DINT→REAL just works). Structured Text offers explicit DINT_TO_REAL(). No dedicated ladder conversion instruction needed. |
| IEC 61131-3 (CODESYS, OpenPLC) | DINT_TO_REAL | Standard conversion function; strict typing makes it mandatory — Flow := DINT_TO_REAL(Counts) / PulsesPerLitre. Full TYPE_TO_TYPE family available. |
| Siemens (TIA Portal) | CONVERT / DINT_TO_REAL | The CONV box in LAD/FBD (choose DInt to Real), DINT_TO_REAL in SCL. S7-1500 also offers LREAL (64-bit) when 7 digits are not enough. |
| Mitsubishi (GX Works) | FLT / DFLT / INT2FLT | FLT converts 16-bit, DFLT 32-bit binary to float on FX/Q series; GX Works3 structured projects use the IEC-style conversion functions. |
The search phrase is "dint_to_real studio 5000", but in Studio 5000 ladder the honest answer is usually "you do not need an instruction — MOV or the math instruction converts implicitly". The explicit function belongs to Structured Text and the IEC platforms.
In practice
| Always_On MOV Raw_Counts Counts_REAL | |----] [--------------------[MOV]-------------------------| | CPT Level_Pct = (Counts_REAL - 6242.0) | | * 100.0 / (31208.0 - 6242.0) | |----------------------------[CPT]------------------------|
A 4–20 mA level transmitter arrives as integer counts (6242–31208 on this card). The MOV into a REAL tag is the implicit DINT_TO_REAL; the CPT then computes a percentage with fractional precision. Done in pure integer math, the same formula would truncate at every division — the level would move in visible steps and any deadband logic downstream would chatter on the stairs.
| Flow_Pulse ONS_P ADD Total_Pulses + 1 | |----] [----------[ONS]---------------------[ADD]---------| | Display_Update.DN CPT Total_Litres = | |----] [---------------[ DINT_TO_REAL(Total_Pulses) | | / 450.0 ]---------|
The accumulation happens in a DINT — exact, one count per pulse, good to 2.1 billion. Only at display time is the total converted to REAL and divided by the meter’s 450 pulses per litre. The tempting shortcut — adding 1.0/450.0 litres to a REAL total on every pulse — fails in two ways: 0.00222 has no exact float representation, so error compounds; and once the total passes ~16.7 million litres the additions start disappearing entirely (adding a small float to a large one below its resolution changes nothing).
Convert late, accumulate exact: it is the single most transferable rule in PLC numeric design.
Gotchas
Totalizing in REAL instead of DINT
Floats absorb small additions into rounding error once the total grows large — beyond 2²⁴ the gaps between representable values exceed 1, and your totalizer silently plateaus. Accumulate in DINT/LINT; convert at the edges (display, ratio math).
Assuming every DINT converts exactly
Only integers up to 16,777,216 are exactly representable in a 32-bit REAL. Above that, DINT_TO_REAL snaps to the nearest float — comparisons like EQU after a round trip fail mysteriously. If a converted value feeds an equality test, rethink the test.
Forgetting the rounding rule on the way back
REAL_TO_DINT rounds to nearest (Logix: ties to even — 2.5 → 2, 3.5 → 4). Code that assumed truncation is off by one, half the time. Use TRUNC when truncation is the intent, and say so in a comment.
Doing the whole calculation in integers "for speed"
Integer division discards remainders at every step, and rearranging the formula to divide last overflows the intermediate DINT instead. Modern controllers do float math fast — convert once at the start of the calculation, compute in REAL, convert once at the end if needed.
COP-ing a DINT into a REAL to "convert" it
COP copies raw bits, not values — the DINT bit pattern reinterpreted as IEEE-754 is nonsense that occasionally looks plausible. Conversion is MOV / DINT_TO_REAL; COP is for structures of identical layout.
Drop the instruction on a rung in the browser simulator, toggle the inputs, and watch the rung state, accumulator values and outputs update scan by scan.
Questions
In ladder, just use the value where a REAL is expected — MOV My_DINT My_REAL, or a CPT/DIV with a REAL destination — because Logix converts between numeric types implicitly. In Structured Text, the explicit function DINT_TO_REAL(My_DINT) does the same conversion visibly. There is no dedicated ladder conversion instruction because none is needed.
Not for values up to 16,777,216 (2²⁴) — every integer in that range converts exactly, because a 32-bit REAL has a 24-bit mantissa. Beyond it, a REAL cannot represent every integer: the converted value snaps to the nearest representable float, with gaps that grow as the number gets larger. Large counters and totalizers should stay in DINT and convert only for display or ratio math.
A DINT is a 32-bit signed integer: exact whole numbers from −2,147,483,648 to 2,147,483,647, ideal for counts and totals. A REAL is a 32-bit IEEE-754 floating-point number: it holds fractions and very large or small magnitudes, but only about 7 significant digits of precision. Counts and comparisons favour DINT; scaling, ratios and engineering units need REAL.
Going float-to-integer, the value is rounded to the nearest whole number — and in Logix, exact halves round to the even neighbour (2.5 → 2, 3.5 → 4), which keeps long-run totals unbiased. If you want the fraction simply cut off, use TRUNC (TRN) instead. IEC 61131-3 defines REAL_TO_DINT as round-to-nearest and provides TRUNC separately as well.