Step 7 REAL Zahlen addieren

Ninja2602

Level-1
Beiträge
271
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin,

hoffe ich poste jetzt nich zweimal, den Eintrag von heute morgen finde ich nicht (scheint nicht gepostet worden zu sein).

Ich habe eine Pumpe bei der ich mittels IDM das gepumpte Volumen berechnen möchte.
Wenn die Pumpe an ist, wird ein Impulssignal an die SPS gesendet.
Anhang anzeigen FB60.pdfAnhang anzeigen FB200.pdf

Wenn in der Multiinstanz (FB200) die Addition EN ist, soll jedesmal ein Volumen von 0,025m^3 zum Gesamtvolumen addiert werden (die 0,025m^3 kommen vom IDM Hersteller in Zusammenhang mit unserem Rohrdurchmesser).
Letzte Woche war der IDM kurz ohne Spannung, es scheint das seit diesem Zeitpunkt die Addition nicht mehr funktioniet.
Wenn ich den zu addieren Wert von 0,025 (REAL) auf 0,035 ändere wird das Gesamtvolumen (REAL) korrekt berechnet.
Warum funktioniet das aber nicht mehr mit 0,025?
Der IDM ist in Ordnung!

Hatte jemand schon einmal ein ähnliches Problem?
 
Ich habe das ganze gerade simuliert und dabei festgestellt das mein Gesamtvolumen sich bei z.B. 5.255555+e003 addiert.
Mein wirklicher Wert liegt aber bei 5.255555+e005 und hier wird sichtbar nichts addiert.
Kann ich bei REAL Zahlen nur bis zu einem bestimmten Wert addieren???
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Auf welchem Wert steht denn das Gesamtvolumen?
Denn bei einer Gleitkommazahl hast du nur eine eingeschränkte Genauigkeit. D.h. wenn man zu einer sehr großen Zahl eine kleine addieren will, geht das in der Genauigkeit der Darstellungsart unter.
Bei 32-Bit Gleitkomma hat man ca. 7 Stellen Genauigkeit:
2,5e-2 * 1,0e7 = 2,5e5
D.h. wenn dein Gesamtvolumen bei ca. 250.000 m³ steht, wird nicht mehr korrekt addiert.
 
Mein Gesamtvolumen liegt bei ca.525518,7m^3.
An die Genauigkeit habe ich auch schon gedacht, aber müsste das dann nicht auch zutrefen sprich nicht mehr korekt addieren bei dem Wert 0,035?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe jetzt gerade nochmal nachgeforscht wie man den Wert berechnen kann ab dem die Addition nicht mehr funktioniert.

Das müsste ja dann sein, wenn das niederwertigste Bit in der Mantisse eine kleinere Wertigkeit hat als der Wert der addiert werden soll.
Die Wertigkeit der Mantissenbits hängt vom Exponenten ab. Bei 32-Bit Gleitkomma sind es 23 Bit in der Mantisse.
Das niederwertigste Bit in der Mantisse hat dann die Wertigkeit 1/2^-(m+1) = 1/2^24

Der kleinste Wert (Abstand) sei wie hier im Beispiel e=0,025
Gesucht ist dann der Exponent x

2^x * 2^-(m+1) = e
x = lb (e / 2^-(m+1))
eingesetzt:
x = lb (0,025 / 2^-24)

für den Taschenrechner ohne Zweierlogarithmus:
x = log (0,025 / 2^-24) / log (2)
x = 18,67

Ist der Exponent 19 dann ist die Wertigkeit größer als 0,025
D.h. die Addition wird nur funktionieren bis 2^18 * 2,0 = 524288.0


Wird hingegen 0,035 addiert ergibt sich:

x = lb (0,035 / 2^-24)
x = 19,16

Ist der Exponent 20 dann ist die Wertigkeit größer als 0,035
D.h. die Addition wird nur funktionieren bis 2^19 * 2,0 = 1048576.0


Daher zählt dein Zähler bei 0,035 um das Doppelte weiter als mit 0,025. Ungenau wird es aber vorher schon.
 
Ist es nicht moglich mit liters zu rechnen in platz von mit M3 Mit liter kan mann ein DINT brauchen und dass Max ist 2^31 , Sie must 25 liter pro puls addieren , Aber in ihre FB ist Dass volume wie IO declariert und wenn sie est ausser die FB wie Real bearbeitte geht dass nich aber fur ein Visie kan man dass scale nach M3 .

Joop
 
Danke für die Rechnung.
Werde das Gesamtvolumen mal auf Null setzten, dann sollte es ja wieder funktionieren und auch genau rechnen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe jetzt gerade nochmal nachgeforscht wie man den Wert berechnen kann ab dem die Addition nicht mehr funktioniert.
Magst Du verraten wo Du das gefunden hast? Habe auch geforscht und komme auch zu Erklärungen, aber von keiner kann ich eine Rechnung wie bei Dir ableiten!

Danke!
 
Magst Du verraten wo Du das gefunden hast? Habe auch geforscht und komme auch zu Erklärungen, aber von keiner kann ich eine Rechnung wie bei Dir ableiten!

Hi,
direkt habe ich die Berechnung so nirgends gefunden.
Ich habe mir diese aus der Beschreibung des IEE 754 Formates abgeleitet, ich hoffe mal da hat sich kein Fehler eingeschlichen ;-)
Ich habe es aber zumindest gerade mit Plcsim getestet, demnach wird genau ab meinen berechneten Werten nicht mehr addiert.

In dem Wikipedia Artikel ist unten ein Link zu einem Java-Applet in dem man an den Bits rumspielen kann, bzw. sehen
kann was sich für ein Bitmuster bei bestimmten Zahlen ergibt.

Eine Gleitkommazahl setzt sich aus 1 Bit Vorzeichen, 8 Bit Exponent und 23 Bit Mantisse (m) zusammen.
Sind in der Mantisse alle Bits gesetzt, so berechnet sich der Wert mit:
1 + 1/2 + 1/4 + 1/8 + 1/16 + ...
Der Gesamtwert ist dann der Wert der Mantisse mal 2 hoch den Exponent

Die erste "1" ist implizit immer vorhanden, darum habe ich in meiner Berechnung für die Bitanzahl der Mantisse nicht 23 sondern 24 eingesetzt.

Was ist dir denn unklar, dann kann ich versuchen zu erklären warum ich das so gerechnet habe.
 
Ich kann aus Deiner Erklärung die Formel
2^x * 2^-(m+1)=e
nicht herleiten.
Und ich kann die Erklärung "Das niederwertigste Bit in der Mantisse hat dann die Wertigkeit 1/2^-(m+1)=1/2^24" nicht nachvollziehen. Warum muss ich hier 1/... rechnen?
Warum m+1 ist habe ich verstanden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Stimmt, da habe ich ein paar Zwischenschritte weggelassen.


Die Formel wie sich eine Gleitkommazahl aus Exponent und Mantisse zusammensetzt, wenn in der Mantisse nur ein Bit m gesetzt ist lautet:

2^x * (1 + 2^-(m+1)) = e

mit:
x = Exponent (ohne Bias)
m = Bitposition in der Mantisse
e = Gleitkommawert


Jetzt suche ich die Differenz zwischen zwei Gleitkommazahlen bei denen einmal
in der Mantisse nur das letzte Bit gesetzt, und einmal gar kein Bit gesetzt ist. Das ist der kleinstmögliche Unterschied (d) zwischen zwei Gleitkommazahlen bei gleichem Exponenten.

Als Formel aufgestellt:
2^x * (1 + 2^-(23+1)) - 2^x * (1 + 0) = d

Vereinfachen und umstellen:
2^x * (1 + 2^-(23+1)) - 2^x = d

(1 + 2^-(23+1)) ersetze ich der Einfachheit halber durch K:

2^x * K - 2^x = d

Ausklammern von 2^x:
2^x * (K - 1) = d

Umstellen nach x:
x = lb (d / (K - 1))

Jetzt für K wieder (1 + 2^-(23+1)) einsetzen:
x = lb (d / (1 + 2^-(23+1)) - 1))

Die 1 fällt weg, 23+1 ausrechnen:
x = lb (d / 2^-24)


Die Differenz soll min. 0,025 sein:

x = lb (0,025 / 2^-24)
x = 18,67
 
Hallo Ninja,

bilde doch einfach mit deinen Realwerten eine Summe. Wenn diese Summe den Wert 1.0 übersteigt, zählst du ein DINT hoch und subtrahierst von der Realsumme den Wert 1.0. Damit kommst du ein ganzes Stück weiter, ohne Verlust an Genauigkeit. Jopp meinte es im Beitrag 7 vermutlich ähnlich.


Gruß, Onkel
 
@ Thomas_V2.1: Danke für die Erklärung.

@ Onkel Dagobert: Das Gesamtvolumen wird an mehreren Stellen verwendet, die Gefahr das ich eine vergesse und dann eine Stelle was falsches anzeigt oder rechnet ist hoch. Habe das Gesamtvolumen wieder auf Null gesetzt, jetzt dauert es wieder ein zwei Jahre bis das Gesamtvolumen so hoch ist das das ungenau wird oder gar nicht mehr mit 0,025 rechnet.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde eventuell in einem DINT die Impulse oder Ereignisse zählen (d.h. immer 1 dazuzählen, wenn du das Volumen zum Real addieren würdest). Danach dieses DINT mit dem Volumen multiplizieren, ergibt Gesamtvolumen zur Verwendung an mehreren weiteren Stellen.
 
Zurück
Oben