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



## JesperMP (6 März 2010)

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.


----------



## Larry Laffer (6 März 2010)

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


----------



## JesperMP (6 März 2010)

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.


----------



## vierlagig (6 März 2010)

wenn REAL NaN ist sind die statusbits A1, A0, OV, OS true


----------



## Larry Laffer (6 März 2010)

JesperMP schrieb:


> 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


----------



## Thomas_v2.1 (6 März 2010)

Probier mal das OK-Flag nach einer Division abzufragen, darauf kann man auch in SCL zugreifen. In der Hilfe steht zumindest dass man damit eine Division durch Null feststellen kann.


----------



## Larry Laffer (6 März 2010)

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 ...


----------



## JesperMP (6 März 2010)

vierlagig schrieb:


> 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 !!


----------



## Larry Laffer (6 März 2010)

... das mit den Statusbits weiß ich auch nicht - ich würde es aber sehr wahrscheinlich mit "IF ..." machen ...


----------



## JesperMP (6 März 2010)

Habe diese code in SCL ausprobiert:

```
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:

```
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.


----------

