Ermittelt, ob die Vergleichsoperatoren =
(Gleichheit) und <>
(Ungleichheit) Operanden vom Typ REAL
oder LREAL
vergleichen.
Begründung: REAL
/ LREAL
- Werte werden als Gleitzahlen nach dem Standard IEEE 754 implementiert. Dieser Standard
bringt es mit sich, dass bestimmte, scheinbar einfache Dezimalzahlen nicht exakt dargestellt
werden können. Das hat zur Folge dass es für dieselbe Dezimalzahl unterschiedliche
Repräsentationen als LREAL
geben kann.
Betrachten wir folgende Codezeilen:
lr11 := 1.1; lr33 := 3.3; lrVar1 := lr11 + lr11; lrVar2 := lr33 - lr11; botest := lrVar1 = lrVar2;
botest
wird in diesem Fall FALSE
liefern, auch wenn die Variablen lrVar1
und lrVar2
beide den Monitoring-Wert "2.2" liefern. Das ist kein Fehler des Compilers, sondern
eine Eigenschaft der Gleitkomma-Einheiten aller üblichen Prozessoren.
Vermeiden können Sie das, indem Sie einen Mindestwert angeben, um den sich die Werte
unterscheiden dürfen: botest := ABS(lrVar1 - lrVar2) < 0.1;
Ausnahme: Ein Vergleich mit 0.0
wird nicht von dieser Analyse gemeldet. Für die 0 gibt es im Standard IEEE 754 eine
exakte Darstellung und daher funktioniert der Vergleich normlerweise wie erwartet.
Für eine bessere Performance ist es daher sinnvoll, hier einen direkten Vergleich
zuzulassen.
Wichtigkeit: Hoch
PLCopen-Regel: CP54
Beispiel
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: Vergleich von REAL / LREAL auf Gleichheit/Ungleichheit