Skip to main content

SA0054: Comparisons of REAL/LREAL for equality / inequality

Detects whether or not the comparison operators = (equality) and <> (inequality) compare the operands of type REAL or LREAL.

Justification: REAL/LREAL values are implemented as floating-point numbers according to the IEEE 754 standard. This standard implies that specific, apparently simple decimal numbers cannot be represented with precision. As a result, there may be different representations as LREAL for the same decimal number.

Consider the following lines of code:

lr11 := 1.1;
lr33 := 3.3;
lrVar1 := lr11 + lr11;
lrVar2 := lr33 - lr11;
botest := lrVar1 = lrVar2;

In this case, botest returns FALSE, even if the variables lrVar1 and lrVar2 both return the monitoring value of "2.2". This is not an error of the compiler, but a property of the floating point units of all conventional processors. You can avoid this by specifying a minimum value by which the values may differ:

botest := ABS(lrVar1 - lrVar2) < 0.1;

Exception: A comparison with 0.0 is not reported by this analysis. For the 0, there is an exact representation in the IEEE 754 standard, and therefore the comparison functions usually as expected. Therefore, for better performance, it makes sense to permit a direct comparison here.

Importance: High

PLCopen rule: CP54

Example 64. Example
PROGRAM PLC_PRG
VAR
    rTest1 : REAL;
    rTest2 : REAL;
    lrTest3 : LREAL;
    lrTest4 : LREAL;
    xResult : BOOL;
END_VAR
//the following lines each will cause an  SA0054:
xResult := rTest1 = rTest1;
xResult := rTest1 = rTest2;
xResult := rTest1 <> rTest2;
xResult := lrTest3 = lrTest3;
xResult := lrTest3 = lrTest4;
xResult := lrTest3 <> lrTest4;
//the following lines each will not cause an  SA0054:
xResult := rTest1 > rTest2;
xResult := lrTest3 < lrTest4;

Output in the Messages view:

  • sa_icon_message.png SA0054: Comparisons of REAL/LREAL for equality / inequality