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 normally as expected.
Therefore, for better performance, it makes sense to permit a direct comparison here.
Importance: High
PLCopen rule: CP54
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; --> SA0054: Comparisons of REAL/LREAL for equality / inequality