SA0054: Comparisons of REAL/LREAL for equality / inequalityPermalink

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