SA0054: Vergleich von REAL / LREAL auf Gleichheit/Ungleichheit
Ermittelt, ob die Vergleichsoperatoren =
(Gleichheit) und <>
(Ungleichheit) Operanden vom Typ REAL
oder LREAL
vergleichen.
Begründung: REAL
/ LREAL
- Werte werden als Gleitpunktzahlen 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 Sie 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 Gleitpunkteinheiten 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 üblicherweise wie erwartet. Für eine bessere Performance ist es daher sinnvoll, hier einen direkten Vergleich zuzulassen.
Wichtigkeit: Hoch
PLCopen-Regel: CP54
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;
Ausgabe unter Ansicht Meldungen:
SA0054: Vergleich von REAL / LREAL auf Gleichheit/Ungleichheit