SA0054 : Comparaisons REAL/LREAL pour l'égalité/l'inégalité
Détecte si les opérateurs de comparaison =
(égalité) et <>
(inégalité) comparer les opérandes de type REAL
ou LREAL
.
Justification : REAL
/LREAL
les valeurs sont implémentées sous forme de nombres à virgule flottante conformément à la norme IEEE 754. Cette norme implique que des nombres décimaux spécifiques, apparemment simples, ne peuvent pas être représentés avec précision. En conséquence, il peut y avoir différentes représentations selon LREAL
pour le même nombre décimal.
Considérez les lignes de code suivantes :
lr11 := 1.1; lr33 := 3.3; lrVar1 := lr11 + lr11; lrVar2 := lr33 - lr11; botest := lrVar1 = lrVar2;
Dans ce cas, botest
Retour FALSE
, même si les variables lrVar1
et lrVar2
les deux renvoient la valeur de surveillance de « 2,2 ». Ce n'est pas une erreur du compilateur, mais une propriété des unités à virgule flottante de tous les processeurs conventionnels. Vous pouvez éviter cela en spécifiant une valeur minimale par laquelle les valeurs peuvent différer :
botest := ABS(lrVar1 - lrVar2) < 0.1;
Exception : Une comparaison avec 0.0
n’est pas rapporté par cette analyse. Pour le 0, il existe une représentation exacte dans la norme IEEE 754, et donc la comparaison fonctionne généralement comme prévu. Par conséquent, pour de meilleures performances, il est logique d’autoriser ici une comparaison directe.
Importance : Élevée
Règle PLCopen : 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;
Sortie dans le messages voir:
SA0054 : Comparaisons de REAL/LREAL pour l'égalité/inégalité