Skip to main content

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

Beispiel 64. 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;

Ausgabe unter Ansicht Meldungen:

  • sa_icon_message.png SA0054: Vergleich von REAL / LREAL auf Gleichheit/Ungleichheit