Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Datentyp für Messdaten (Chemie, Physik) (https://www.delphipraxis.net/145247-datentyp-fuer-messdaten-chemie-physik.html)

EConvertError 27. Dez 2009 18:24


Datentyp für Messdaten (Chemie, Physik)
 
Hallo!

Ich will Messdaten aus der Chemie/Physik verarbeiten - die Frage ist jetzt: Welcher Datentyp ist zur Speichrung der Messwerte am besten geeignet?

Die Programmersprache ist ausnahmsweise C++, bin aber als langjähriger Delphi-Programmierer in der Lage auch aus Antworten für Delphi meine Schlüsse zu ziehen.

Anforderungen: Es handelt sich ganz allgemein um Messdaten (für versch. Anwendungen), sodass die Anzahl der Kommastellen unbekannt ist. Grob gesagt: Von 2-3 bis ca. 10 Kommastellen kann es sich bewegen...

Kann ich hierbei einfach den größten Fließkomma-Datentyp, long double, verwenden, oder muss darüber hinaus etwas Spezielles bedacht werden? Ungenauigkeit durch Rundungsfehler, etc? Wie ihr euch vorstellen könnt, lege ich auf größte Genauigkeit wert, da unter Umständen unterhalb des mg/L-Bereichs analysiert wird...

Darüber hinaus ist die Effizienz ein besonderes Thema: Natürlich liegt die Hauptarbeit in den Algorithmen, aber ist es ansonsten sinnvoll, Algorithmen für mehrere Datentypen, z.B. float, double, long double zu implementieren, um die Auswahl der gewünschten Genauigkeit dem Anwender der Bibliothek zu überlassen?

Vielen Dank,
Andreas

markus5766h 27. Dez 2009 18:54

Re: Datentyp für Messdaten (Chemie, Physik)
 
Hallo,

Datentypen C++:

bit min.Wert max.Wert Genauigkeit
double 64 ca.±1.7E-308 ±1.7E308 >= 10 Stellen
long double 80 ca.±1.2E-4932 ±1.2E4932 >= double
float 32 ca.±3.4E-38 ±3.4E38 >= 6 Stellen

soll noch genauer als long double gearbeitet werden, musst Du Dir
wohl eine Funktion "basteln" - kann mich dunkel erinnern, dass es
hier mal einen entsprechenden Thread gab ... :?:

wenn's reicht, würde ich nur ein Datentyp (long double) verwenden -
geht zwar etwas auf Kosten der Effizienz, aber wenn Geschwindigkeit
nur eine untergeordnete Rolle spielt, ist's wohl am einfachsten (bequem).

Uwe Raabe 27. Dez 2009 19:04

Re: Datentyp für Messdaten (Chemie, Physik)
 
Die Genauigkeit von Float-Typen wird in signifikanten Stellen angegeben und spielt sich ausschließlich in der Mantisse ab. Der Exponent ist lediglich für den Wertebereich zuständig. Wenn z.B. ein Double 15 signifikanten Stellen angegeben wird, so ist eine Zahl in wissenschaftlicher Schreibweise (oder auch E-Notation) mit dieser Anzahl Stellen in hinreichender Genauigkeit speicherbar.

Problematisch wird es allerdings, wenn mit diesen Zahlen Berechnungen durchgeführt werden, durch die Rundungsfehler entstehen. Ein Beispiel:

Delphi-Quellcode:
var
  A: Double;
  B: Double;
  C: Double;
  F: Double;
begin
  A := Pi;         //  3.14159265358979E+0000
  F := 100*A;      //  3.14159265358979E+0002
  B := A + F;      //  3.17300858012569E+0002
  C := B - F;      //  3.14159265358978E+0000 
  Writeln(C - A);  // -1.06581410364015E-0014
end;
Obwohl mathematisch A = C sein sollte, wird die errechnete Differenz ungleich 0 sein. F hat zwar die gleiche Anzahl signifikanter Stellen wie A, ist jedoch um einen Faktor 100 größer. Für die Addition A + F müssen A und F angeglichem werden, was zu einem Verlust von signifikanten Stellen bei A führt. B ist also schon nicht mehr ganz so genau. Die nachfolgende Subtraktion macht das Problem dann deutlich.

Dein Problem ist also nicht die Auswahl des geeigneten Datentyps, sondern die bedachte Auswahl der Rechenreihenfolgen.

alzaimar 27. Dez 2009 19:27

Re: Datentyp für Messdaten (Chemie, Physik)
 
Messdaten haben normalerweise eine Genauigkeit von 0.1-1 Promille, also max 5-6 Stellen. Eine höhere Genauigkeit ist natürlich je nach Messgerät möglich, aber nur selten sinnvoll. Meist sind die Messfehler durch Umwelteinflüsse eh höher.

Nehmen wir also eine sinnvolle Genauigkeit von 6 Stellen an. Dann reicht zum Speichern die einfache Genauigkeit aus. Zum Rechnen (wenn es nicht endlose Iterationen sind), sollte der Double-Datentyp ausreichend sein, sicherheitshalber und auch weil die CPU mittlerweile problemlos damit klar kommen, kann man auch die doppelte Genauigkeit verwenden.

Wichtig ist, das man die Ergebnisse richtig und sinnvoll interpretiert. Ich beömmel mich immer wieder, wenn Umfrageergebnisse von 14,7102% veröffentlicht werden, aber nur 990 Leute befragt wurden. Hier sollte ich nur maximal 3 Stellen angeben, denn mehr (=eine höhere Genauigkeit) hat nämlich die Messung (=die Umfrage) nicht hergegeben.

schöni 27. Dez 2009 21:14

Re: Datentyp für Messdaten (Chemie, Physik)
 
Hallo,

so wie ich die Fragestellung verstanden habe:

Delphi-Quellcode:
type
  TMessdaten = record
    value: Double;
    dims: Double;       //Multiplikator mV->0.001, V -> 1, KV -> 1000, ...
    dimension: String;  //Maßeinheit mV, V, KV, MV
  end;
dimension ist für die Messwertausgabe gedacht. dims ist ein Umrechnungsfaktor je nach eingestelltem Messbereich.

Es sei denn, es gibt einen standardisierten Datentyp für die Industrie.

EConvertError 27. Dez 2009 22:42

Re: Datentyp für Messdaten (Chemie, Physik)
 
Vielen Dank für die zahlreichen Antworten!

Es handelt sich hauptsächlich um spektroskopische/chromatographische/massenspektroskopische Daten. Die Genauigkeit schwankt daher teilweise enorm (Massenspektroskopie ist z.B. irrsinnig genau, während andere Daten viel mehr schwanken). In der Tat werde normalerweise 5-6 Kommastellen ausreichen, jedoch möchte ich die Algorithmen nicht neu schreiben, sollten es einmal 10 Kommastellen sein - daher meine Nachfrage bezüglich Genauigkeit. Selbstverständlich weiß ich aus eigener Erfahrung im Labor, dass manchmal die Anzahl der signifikanten Stellen Geräte/Messtechnisch WEIT darunter liegt...

Aber von der Chemie zurück zur Programmierung:

Daher habt ihr völlig richtig erraten, dass ich nicht 37 Kommastellen korrekt berechnen muss. Dennoch will ich nicht relativ genaue Methoden mit schlechten Datentypen / miesen Algorithmen vermiesen, oder ohnehin schon ungenaue Methoden noch verschlimmern...

Daher wird es wohl nicht notwendig sein, einen eigenen Datentyp zu basteln, sollte es aber grundlegende Tipps geben, Stichwort hierbei hat Uwe Raabe vorgegeben: bedachte Auswahl der Rechenreihenfolgen

Gibt es da aufgrund der Informatik gewisse Regeln zu beachten, oder komme ich mit denen als Chemiestudent gelernten Regeln aus:
Addition/Substraktion: Die geringste Anzahl der signifikanten Stellen der einzelnen Zahlen bestimmt die Anzahl der signifikanten Stellen im Ergebnis. Analog bei den anderen Rechenoperationen...

Gibt es weitere allgemeine Tipps?

Vielen Dank,
Andreas

Reinhard Kern 28. Dez 2009 05:27

Re: Datentyp für Messdaten (Chemie, Physik)
 
Hallo,

das ist alles theoretisch schön und gut, aber die Messwerte existieren ja so überhaupt nicht: im Computer verrechnet und gespeichert werden kann nur, was ein Messgerät gemessen hat, nicht der wahre Wert. Und das ist z.B. bei einem 16bit-ADC eben nur ein 16 bit integer, je nach ADC signed oder unsigned. Ich speichere daher seit vielen Jahren die originalen Daten aus der Datenerfassung als Binärdaten - es gibt einfach nichts besseres zu speichern, jede Weiterverarbeitung kann eine Verfälschung bedeuten, und ich lege Wert darauf, dass die Messdaten auch nach Jahren noch neu verarbeitet werden können. Das ist vergleichbar der Tatsache, bei Digitalfotos Raw zu verwenden.

Bisher war die Speicherung mit 32 bit ausreichend, weil es kaum Messverfahren gibt, die eine bessere Genauigkeit als 32 bit liefern, man kann aber sicherheitshalber auch 64 bit verwenden. Dass Messgeräte i.A. Fixkomma liefern, ändert ja nichts. In den letzten Jahren bin ich jedoch im Interesse der Langzeit-Kompatibilität dazu übergegangen, die Originalmesswerte als ASCII-Text zu speichern, also z.B. 231.459 V für Netzspannung, und das genauso wie das Messgerät den Wert liefert. Das sollte auch in mehr als tausend Jahren noch ausgewertet werden können.

Delphi-spezifische Formate, womöglich Objekte, sind für Archivierung sowieso tabu, da kann man die Daten gleich löschen. Es ist sowieso klar, dass meine Meinung hier gleich niedergemacht wird, nach den bisherigen Beiträgen, trotzdem erlaube ich mir den Luxus eine zu haben.

Gruss Reinhard

EConvertError 28. Dez 2009 14:59

Re: Datentyp für Messdaten (Chemie, Physik)
 
Wie schon geschrieben, werde ich hier nicht die Genauigkeit meiner Methoden diskutieren. Warum? Dieses Programm soll mir das Leben in so manchen Labors vereinfachten und ich werde es nicht jedes Mal neu schreiben, wenn eine Kommastelle dazukommt oder wegfällt.

Daher: Größtmögliche SINNVOLLE Genauigkeit. Dass Rohdaten - sofern möglich - abgespeichert werden, ist völlig klar. Bringt mir halt nix, wenn dann nach der Fourier-Transformation nix mehr überbleibt, weil ich bei der Berechnung zu ungenau bin.

Um diese Diskussion zu einem konstruktiven Ende zu bringen, meine Zusammenfassung/meine abschließenden Fragen:
1) Es reicht also völlig aus, mit (long) double zu rechnen, weil das für praktische Zwecke völlig ausreichend ist?
2) Gibt es eine Möglichkeit, die von Uwe Raabe, beschriebene Problematik elegant (mit vertretbarem Aufwand) zu umgehen, oder ist das eine "generelle Unzulänglichkeit" der Computer? Ein von mir verwendetes Statistikprogramm (nicht von mir geschrieben) macht den gleichen Fehler, mein Taschenrechner ist wohl zu ungenau und rundet, sodass der Fehler gar nicht erst auftaucht...

Vielen Dank,
Andreas

arbu man 28. Dez 2009 16:45

Re: Datentyp für Messdaten (Chemie, Physik)
 
zu 1) http://de.wikipedia.org/wiki/GNU_Mul...hmetic_Library

Du wirst nur immer das Problem haben Genauigkeit gegen Rechenzeit abwiegen zu müssen. Diese Abschätzung für alle Zeiten richtig zu machen ist imho nicht möglich.
Sonst gibt es noch die Möglichkeit, die Rechnenoperationen austauschbar zu implementieren, dann muss man wenn es genau haben will nur eine Einstellung ändern, und das Programm rechnet genau mit beispielsweise GMP, oder sonst schnell mit double.

lg Björn

EConvertError 3. Jan 2010 14:23

Re: Datentyp für Messdaten (Chemie, Physik)
 
Ich denke, dass ich ohne dieser GNU_Multiple_Precision_Arithmetic_Library oder BCD-Arithmetik auskommmen werde.

Trozdem habe ich mich noch ein wenig in dieses interessante Thema eingelesen:

Zitat:

Der Typ float (6-stelliger Genauigkeit) ist also ungeeignet für kaufmännische und genaue wissenschaftliche Berechnungen.
Soweit, so gut. Daher verwende ich (long?) double:
Zitat:

Man braucht wirklich nie eine solche Genauigkeit wie mit long double, es reicht double aus. Außerdem entspricht long double nicht dem C89-Standard.
Ist diese C89-Standard-Geschichte ein Problem?

Zitat:

Sollten Sie jetzt denken, mit long double erhielten Sie eine größere Genauigkeit, kann der Schein trügen. Intern (in der FPU) werden sowieso alle Werte, ob float oder double, erst nach long double konvertiert, und dann entsprechend zurück.
Habe ich jetzt mit double 15 signifikante Stellen und mit long double 19 Stellen, oder nicht? Von Interesse sind hierbei lediglich "die normalen Architekturen", das Programm (C++ mit Qt) soll auf Windows XP (oder höher), Linux (mit normaler Intel/AMD Architektur), sowie Intel-Macs laufen.

19 bzw. 15 signifikante Stellen scheinen mir mehr als genug zu sein, jedoch will ich wissen, wie mein Programm arbeitet... ;)

lg,
Andreas


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz