Mastering Real Number Operations in TwinCAT PLC: Pitfalls, Best Practices, and Optimization Techniques

 Have you ever wondered if what you think about real numbers is truly what you think? It turns out, not quite. Before stepping into the pitfalls, everyone is confident. This article outlines the pitfalls encountered over the years regarding real numbers, which might be helpful for you.

If you've encountered other issues related to real numbers, feel free to leave a comment!

Range and Precision of Real Numbers:

In TwinCAT PLC, there are two types of real numbers: 'real' and 'lreal,' where the former occupies 4 bytes and the latter 8 bytes. A 4-byte integer can express any integer within the range of +-2e31, i.e., -21474836482 to 2147483647, or 4.210e10. The theoretical range of real numbers is much larger than integers and can be precise to several decimal places. For instance, the maximum value of a 4-byte Real can be 3.410e38, but considering precision, the practical range is significantly reduced—only capable of expressing 7 significant digits.

What does 7 significant digits mean? It implies that the total number of integer and decimal digits does not exceed 8, and the last digit is rounded. If precision is to three decimal places, it can only express up to 10e4. An 8-byte lreal can express 16 significant digits, allowing precision up to 10e13 when accurate to three decimal places. Due to this characteristic of real numbers, the more significant digits in the integer part, the lower the precision.

If a Real value exceeds 10e8, the units digit becomes indistinguishable, limiting its accuracy to the tens place.

Transmission of Real Numbers in TwinCAT with Different Systems:

  • Exchange of Real Numbers with PC via ADS: When transferring real numbers between TwinCAT and PC using ADS, the data format typically aligns without the need for conversion.

  • Exchange of Real Numbers with Traditional PLC via Fieldbus: When transferring real numbers between TwinCAT and traditional PLCs using fieldbus communication, there may be a need to swap high and low bytes. An unusually large received real number might indicate this issue.

  • Exchange of Real Numbers with Touchscreens or Instruments via MODBUS: There are two approaches: converting to an integer by keeping a certain number of decimal places or directly transmitting as WORDs. The receiver must assemble these WORDs into real numbers, considering whether byte swapping is necessary.

  • Writing Real Numbers from TwinCAT to a Database: Writing data to a database in TwinCAT is done through SQL statements, which are inherently string types. Therefore, all data needs to be converted to characters before transmission. Avoid using functions like LREAL_TO_STRING, as certain real number values may generate characters not accepted by the corresponding database field.

For writing real numbers to a database, the FB_FormatString2 function in Tc2_Utilities can be utilized for merging up to 10 variables:

for example:


Considerations when using Real Numbers:

Avoiding Equality Checks with Real Numbers: When performing integer-related operations with real numbers, avoid using equality checks between two real numbers or between a real number and an integer as a condition. Solution: Use the absolute difference between the two values within a certain range as a condition, for example: ABS(X-Y)<0.001.

Implicit Rules in PLC Regarding Real Number Operations:

  • Any constant with a decimal point, when operated with a 'real,' results in a 'real'; when operated with an 'lreal,' the result is an 'lreal.'
  • If both operands are constants, the result is an 'lreal.'
  • If both operands are variables, the result is an 'lreal.'

Choosing 'lreal' for Numbers Exceeding 10,000: For 'real' types, the precision of numbers in the tens of thousands is limited to three decimal places, and in the hundreds of thousands, it's limited to two decimal places. Considering TwinCAT utilizes PC control with ample CPU and memory resources, it is advisable to default to using 'lreal.'

Integer Division and Remainder:

  • Result of integer division is rounded down using the IEC operator DIV. Example: For INT variables X and Y, in ST language: X / Y is equivalent to (X - (X MOD Y)) / Y.

  • Remainder of integer division. Example: For INT variables X and Y, in ST language: X MOD Y.

  • Rounding to the nearest integer for the result of integer division. No direct operator; use: LREAL_TO_INT(X*1.0/Y).

  • Rounding up for the result of integer division. No direct operator; use: X/Y+SEL(( (X MOD Y)>0),1,0).

Real Number Division:


  • Rounding down for the result of real number division. In seemingly divisible cases, the calculated integer result from real number division may have uncertainty. Solution: Multiply both divisor and dividend by 10^n, round to the nearest integer, and then use integer division methods for the precise integer part (without rounding). Example: TRUNC_INT(2.4/0.8) results in 2, not 3.

  • Remainder of real number division. Example: For REAL variables X and Y, in ST language: LMOD(X, Y). Note: When the remainder is close to zero, the result may approximate the value of Y.

  • Rounding to the nearest integer for the result of real number division. Since real number to integer conversion defaults to rounding, the result of real number division can be written as: LREAL_TO_INT(X*1.0/Y).

  • Rounding up for the result of real number division. Due to the uncertainty in real number division, the same method of multiplying both divisor and dividend by 10^n and converting to integers is applicable. Example: For REAL variables X and Y,


  • X1:= LREAL_TO_INT(X*10)

    Y1:= LREAL_TO_INT(Y*10)

    Result of rounding up:

    X1/Y1+SEL(( (X1 MOD Y1)>0),1,0)