TIA SCL Code Problem

lsr

Level-2
Beiträge
109
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, Ich bin SCL Anfänger und habe folgendes Problem:

Bei diesem Code möchte ich jedes Mal wenn der Wert #Verbrauch_L2 ungleich #ZW_EnergieL2 ist(1 Zyklus lang)
den Wert #Verbrauch_Gesamt_L2_HT um 0.01 erhöhen.
Es funktioniert eigentlich auch, doch ich bekomme mehr Kommastellen als eigentlich sein dürfenden, siehe Bild vom DB.
Was mache ich da falsch?


Code:

IF #Verbrauch_L2 <> #ZW_EnergieL2 THEN

IF #HT_NT=True THEN
#Verbrauch_Gesamt_L2_HT := #Verbrauch_Gesamt_L2_HT + 0.01;
#ZW_Tagesverbrauch_L2_HT := #ZW_Tagesverbrauch_L2_HT + 0.01;
ELSE
#Verbrauch_Gesamt_L2_NT := #Verbrauch_Gesamt_L2_NT + 0.01;
#ZW_Tagesverbrauch_L2_NT := #ZW_Tagesverbrauch_L2_NT + 0.01;
END_IF;

END_IF;
 

Anhänge

  • db.jpg
    db.jpg
    10,1 KB · Aufrufe: 47
Mit dem Code oder mit SCL ist da nichts falsch.
Das Problem liegt in der Genauigkeit der Darstellung durch das Zahlenformat Real nach IEEE754.
HIER hatte ich das mal schön erklärt.

Wen du dir dort anschaust wie z.B. 0.1 in Wirklichkeit dargestellt wird,
dann kannst du dir auch sicher vorstellen was passiert, wenn du ständig Werte wie 0.001 aufaddierst.
Irgendwann kommt dann die Ungenauigkeit zu tragen.
Das Problem ist zusätzlich dass du sämtliche summierte Ungenauigkeiten immer mit dem Real mitschleppst.
Dann hast du plötzlich irgendwas .9999999

Lösung: Den Zähler mit +1 als DINT ausfühen und zur Anzeige 1x am Schluss in nen Real wandeln und mit 0.01 multiplizieren.

Auch wenn REAL ein universell einfach zu verwendender Datentyp ist, hat er durchaus seine Tücken! :ROFLMAO:

[EDIT]
Achja! Und schreib doch bitte ein [CODE] am Beginn und ein [/CODE] am Ende deines Code-Schnipsels hin.
Dann kann man das deutlich besser lesen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Ronin

Vielen Dank für Deine Ausführung.
Jetzt ist es mir klar, warum ich solche Werte bekomme.
Ich suchte den halben Nachmittag nach dem Fehler.

Ich werde den Code umschreiben.

Gruss Cornel
 
Kein Problem ;)
Wie ich im anderem Beitrag schon geschrieben hab, bin ich selber auch das erste mal darauf aufmerksam geworden als ich genau das selbe versucht habe wie du.
 
Aus Erfahrung, für einen Laufmeterzähler wurde bei uns eine Realzahl immer um 0.2 erhöht. Bei 200.000 war der Fehler schon in einstelligen Prozentbereich.
Bei einem Unterschied der 2er Potenzen von 15 sollte der Fehler kleiner als 0.1% aufweisen. Oder gemäss Siemens 6 Nachkommastellen.
Falls du auf solche hohen Summen kommen würdest, kann ich dir aus OSCAT die Funktionen zu Realzahlen mit doppelter Genauigkeit empfehlen. Da liegt die Genauigkeit bei ca 15. Stellen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zähler realisiert man in Ganzzahlen, da gibt es keine versteckten Probleme, und die kann man notfalls ganz einfach auf eine beliebige Anzahl Stellen kaskadieren. Wie old-School-Rechnen mit Übertrag.

Harald
 
Aus Erfahrung, für einen Laufmeterzähler wurde bei uns eine Realzahl immer um 0.2 erhöht. Bei 200.000 war der Fehler schon in einstelligen Prozentbereich.
Bei einem Unterschied der 2er Potenzen von 15 sollte der Fehler kleiner als 0.1% aufweisen. Oder gemäss Siemens 6 Nachkommastellen.
Bei mir haben Zähler im Real-Format einen variablen Überlauf anhand der Nachkommastellen des Summanden, dann bleibt man auch in den Toleranzen. Wenn du auf 200.000 noch 0,2 aufaddierst geht das eben in der Genauigkeit unter, weil diese Zahlen zu weit auseinanderliegen.

Hier mal ein Diagramm wie groß die Ungenauigkeit bei einer fortlaufenden Addition von 0,1 auf eine 32-Bit Gleitkommazahl wird. Auf der X-Achse ist die Anzahl der Additionen in logarithmischer Skala aufgetragen, auf der Y-Achse die Abweichung in Prozent.
ungenauigkeit-gleitkommaadditionen.jpg
Der Bereich bis 150.000 vergrößert:
ungenauigkeit-gleitkommaadditionen-bis-150000.jpg

Bei dir waren es 200.000 / 0.2 = 1.000.000 Additionen, passt also ungefähr mit der Abweichung bei 0,1er Schrittweite überein.
 
Vielleicht noch zur Vervollständigung.

Es kann sogar dazu kommen dass so ein Zähler mit nem REAL dann überhaupt stehen bleibt.
Versucht man zum Beispiel auf den Real-Wert 32768.0 noch 0.001 auf zu addieren, stellt man fest dass der Wert bei 32768 bleibt.

Code:
      L     MD   150
      L     0.000000e+000
      ==R   
      SPBN  Md01

      L     3.276800e+004
      T     MD   150

Md01: L     MD   150
      L     1.000000e-003
      +R    
      T     MD   150             //Bleibt immer 3.276800e+004
32768.001 kann nämlich in IEE754 nicht dargestellt werden, der nächste Wert wäre 32768.004.
Es ist auch klar das +R das "korrektere" Ergebnis mit 32768.000 liefert, das Problem ist halt dass es dann nicht mehr weitergeht... :rolleyes:

Zähler realisiert man in Ganzzahlen
*ACK*
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi all

http://de.wikipedia.org/wiki/IEEE_754 beschreibt, dass eine 32 Bit Gleitkommazahl 23 Bit Mantisse hat. D.h. ein Zähler mit REAL (32 Bit) wird bei der 2**23 - 1 = 8388607 ten Addition scheitern. Dabei ist es total egal, ob nun jedes mal 0.125 oder 1024 drauf addiert wird. Wird was anderes als eine Zweier-Potenz addiert, dann scheitert man früher, weil ja jedes mal mehr als ein Bit addiert wird. Zahlen die mit Zehnerpotenzen zu tun haben (10, 100, 0.1, 0.01) sind da besonders schlecht, weil 10 recht weit weg ist von 8 und 16. 11 und 12 und 13 sind noch schlimmer. Aber wer verwendet schon ein 11er oder 13er System ;-) Uhren haben ein 12er :cool:

Reelle Zahlen sind einfach nix für Computer.

'n schön' Tach auch
HB

PS: Oder gilt das nur für die Leute die glauben ein Computer macht immer alles richtig?
 
Zurück
Oben