IsFinite

IsFinite 1:

Die Funktion IsFinite() liefert TRUE zurück, wenn deren Argument einen endlichen Wert besitzt (INF < x < +INF). D.h. die Funktion liefert FALSE zurück, wenn der Argument unendlich oder NaN ist (NaN  = Not a number). IsFinite() überprüft, ob die Formatierung einer LREAL oder REAL-Variablen der IEEE entspricht. 

 

INF-Zahlen können auf einem Laufzeitsystem dann vorkommen, wenn das Ergebnis einer mathematischen Operation den darstellbaren Bereich überschreitet oder unterschreitet. Z.B.:

PROGRAM MAIN
VAR
    fSingle : REAL := 12.34;
END_VAR
(*Cyclic called program code*)
fSingle := fSingle*2;

 

NaN-Zahlen können im Laufzeitsystem dann vorkommen, wenn deren eigentliche Formatierung (Speicherinhalte) durch unerlaubten Zugriff ( z.B. durch Benutzung der MEMCPY, MEMSET Funktionen ) überschrieben wurden. Z.B.:

PROGRAM MAIN
VAR
    fSingle : REAL := 12.34;
END_VAR
(*Cyclic called program code*)
MEMSET( ADR( fSingle ), 16#FF, SIZEOF( fSingle ) ); (* Invalid initialization of REAL variable *)

 

Beim Aufruf einer Konvertierungsfunktion mit einer NaN oder INF-Zahl als Parameter wird auf einem PC-System (i368) eine FPU-Exception ausgelöst. Diese Exception führt anschließend zum Stopp der SPS. Mit der Funktion IsFinite() kann der Wert der Variablen überprüft, die FPU-Exception vermieden und die Programmausführung fortgesetzt werden.

 

FUNCTION IsFinite : BOOL

VAR_INPUT
    x :T_Arg;
END_VAR

x: Eine Hilfsstruktur mit Informationen zu der zu überprüfenden REAL oder LREAL-Variablen. Die Strukturparameter müssen beim Aufruf von IsFinite() mit Hilfsfunktionen F_REAL oder F_LREAL erzeugt und als Parameter übergeben werden.

 

Beispiel für einen Aufruf in ST:

Im folgenden Beispiel wird die Formatierung einer REAL- und einer LREAL-Variablen überprüft und eine FPU-Exception vermieden.

PROGRAM MAIN
VAR
    fSingle         : REAL := 12.34;
    fDouble         : LREAL := 56.78;
    singleAsString  : STRING;
    doubleAsString  : STRING;
END_VAR
fSingle := fSingle*2;
IF IsFinite( F_REAL( fSingle ) ) THEN
    singleAsString := REAL_TO_STRING( fSingle );
ELSE
  (* report error !*)
 fSingle := 12.34;
END_IF

fDouble := fDouble*2;
IF IsFinite( F_LREAL( fDouble ) ) THEN
    doubleAsString := LREAL_TO_STRING( fDouble );
ELSE
  (* report error !*)
 fDouble := 56.78;
END_IF

Im folgenden Fall kann eine FPU-Exception durch Überprüfung mit IsFinite() nicht vermieden werden:

PROGRAM MAIN
VAR
    bigFloat  : LREAL := 3.0E100;
    smallDigit: INT;
END_VAR
IF IsFinite( F_LREAL( bigFloat ) ) THEN
    smallDigit := LREAL_TO_INT( bigFloat );
END_IF

Die bigFloat-Variable besitzt zwar richtige Formatierung, der Variablenwert ist aber zu groß um diesen in einen INT-Typ konvertieren zu können. Auf einem PC-System (i368) wird eine Exception ausgelöst und das Laufzeitsystem gestoppt.

 

Voraussetzungen

Entwicklungsumgebung

Zielplattform

Einzubindende SPS-Bibliotheken

TwinCAT v2.8.0 Build > 747
TwinCAT v2.9.0 Build > 947

PC or CX (x86)

TcUtilities.Lib

TwinCAT v2.10.0 Build >= 1301

CX (ARM)