SCL / ST : Wie NaN (Not a Number) testen ?

Beiträge
8.300
Reaktionspunkte
1.888
Zuviel Werbung?
-> Hier kostenlos registrieren
Problem ist das es kann passieren das das Inhalt von ein Variabel nicht korrekt als ein Fliesskommazahl interpretiert werden kann. Z.B nach division durch Null, oder durch falschen Zugang zu den Variabelinhalt anderswo von.

Wenn diese Falsche Fliesskommazahl später in SCL / ST verwendet wird, erzeugt es gravierende fehler.
Ich weiss das man bestens programmieren soll so das z.B. division durch null nicht passieren kann. Aber garantieren kann man nicht.

Also, gibt es irgendwie ein Verfahren womit man Variabelinhalte von NaN testen kann ? Ich will das den normale Rechen-Program abgebrocken wird, und ein Fehlermeldung ("Fliesskomma Fehler") in mein HMI ausgelöst wird.
 
Hallo Jesper,
ein derartiges Verfahren ist mir so nicht bekannt.
Ich bediene mich bei so etwas üblicherweise der Überprüfung bei der Eingabe - ich vermute jetzt mal, dass deine unbrauchbaren Werte aus einer Eingabe kommen.
Falls ich da jetzt falsch liegen sollte, dann schreib doch noch etwas mehr ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Larry.

Wie funktioniert es mit den "der Überprüfung bei der Eingabe".
Das Einhalt von ein Parameter wird wohl übertragen beim aufruf von den FB/FC, egal ob das Einhalt korrekt ist oder nicht. Oder ist das falsch ?

Dazu ist den Variabel nicht ein FC/FB Eingabe, sondern wird explicit von ein DB addressiert in den SCL code. Aber ich sehe nicht wie es ein unterschied macht.
Aber ich bin offen für andere methoden.

Am Ende von eine lange Rechensequenz, die durch viele Schritte läuft, will Ich wenn möglich ein Art Müllfilter haben. Dies als eine zusätzliche Sicherheit, das keine "unmögliche" Werte berechnet wird.

Jetz programmiere ich eine Reihe von Vergleichern, z.B:
IF (("LogData".Set1.Val1 < 50.0) AND ("LogData".Set1.Val1 > -20.0)) THEN ....
Es ist aber umständlich, und Ich habe den Gefühl es muss ein Clevere Weg sein.
 
Jetz programmiere ich eine Reihe von Vergleichern, z.B:
IF (("LogData".Set1.Val1 < 50.0) AND ("LogData".Set1.Val1 > -20.0)) THEN ....
Es ist aber umständlich, und Ich habe den Gefühl es muss ein Clevere Weg sein.

nicht meines Wissens.
Die wichtigste Grundbedingung einer Berechnung ist doch, dass sich die Werte in dem erwarteten Bereich bewegen. Das kannst du m.E. nur auf diese Weise sicherstellen. Übergibst du einen falschen Wert, so könntest du z.B. einen Fehlercode ausgeben, der sagt "Parameter-Fehler" (oder ähnlich).

Gruß
LL
 
Ach ja - Nachsatz:
was ich auch schon mal mache ist, dass ich erst bei einem Zwischenwert (Zwischenergebnis) kontrolliere, ob ich noch im legalen Bereich bin ...
 
wenn REAL NaN ist sind die statusbits A1, A0, OV, OS true
Daran habe Ich auch gedact. Aber die status bits werden wohl beim berechnen gesetst ?
Hmmm..... Vielleicht konnte Ich die Daten beim Ende von den Rechensequenz in ein Zwisschenspeicher plazieren, und dann mit auswerten von die Statusbits entscheiden ob die Daten in den richtige Speicher kopiert werden soll.
Hmmm..... (bin am Online Hilfe lesen) es gibt ein "OK" Flag in SCL. Aber kein A1, A0, OV, OS (am mindestens kann Ich sie nicht finden). Ich glaube es wäre ein Möglicheit. Das werden Ich testen.

Danke !

edit: Thomas und Larry, Danke, das wäre genau was Ich jetzt testen will. Es scheint den "Clevere Weg" zu sein. Danke !!
 
Habe diese code in SCL ausprobiert:
Code:
FUNCTION FC19 : VOID

VAR_INPUT
    r1 : REAL ;
    r2 : REAL ;
END_VAR
VAR_OUTPUT
    r3 : REAL ;
    biOK : BOOL ;
END_VAR
VAR_TEMP
    rTemp : REAL ;
END_VAR

OK := TRUE ;

rTemp := r1 / r2 ;

IF OK THEN 
    r3 := rTemp ;
    biOK := TRUE ;
ELSE
    r3 := 0.0 ;
    biOK := FALSE ;
END_IF ;

END_FUNCTION

Wird zu diesen STL code:
Code:
      SET   
      SAVE  
      =     L      4.1
      =     L      4.1
      L     #r1
      L     #r2
      /R    
      [COLOR="Blue"][B]JO    I007[/B][/COLOR]
      JU    I008
I007: CLR   
      =     L      4.1
I008: T     #rTemp
      CLR   
      A     L      4.1
      JCN   A7d0
      T     #r3
      SET   
      =     #biOK
      JU    A7d1
A7d0: L     0.000000e+000
      T     #r3
      CLR   
      =     #biOK
A7d1: CLR   
      A     L      4.1
      SAVE  
      BE

Den OK Flag wird in ein JO Sprungbefehl gewandelt.

Es scheint zu funktionieren.
 
Zurück
Oben