VectorLibIndex:OptiVec HomeMatrixLib CMATH Download Bestellung / Registrierung Update Support |
VectorLib5. Fehlerbehandlung
5.1 AllgemeinesEs gibt grundsätzlich zwei Arten von Fehlerbehandlung: Durch die Hardware oder durch die Software. Um einen unkontrollierten Absturz zu vermeiden, ist es immer wünschenswert, drohende Fehler durch die Software abzufangen, bevor sie Unheil anrichten können. Alle Hochsprachen unterstützen diese Software-Fehlerbehandlung bis zu einem gewissen Grad an Perfektion. Innerhalb der sehr strikt definierten OptiVec-Funktionen läßt sich häufig eine noch effizientere Fehlerbehandlung durchführen als sie einem Compiler für "normalen" Programmcode möglich ist. Auch hier sind allerdings Grenzen gesetzt, insbesondere für den Überlauf-Schutz innerhalb der extended-, teilweise auch der double-Versionen von OptiVec-Funktionen. Der Programmierer sollte generell darauf achten, daß konstante Paramater bei der Übergabe an Funktionen sicherheitshalber nicht größer als 1.E32 für float / Single, 1.E150 für double und 1.E2000 für extended sind.In den "erweiterten" Versionen aller extended-genauen Funktionen (also denen mit den Präfixen VEx_ und VCEx_; z.B. VEx_exp) wird generell kein Überlauf-Schutz für die Berechnung des Zwischenergebnisses A*Xi+B gewährt, sondern nur für den Kern der Funktion selbst und für die abschließende Multiplikation mit dem Skalierungsfaktor C. Wie üblich, werden Fehler durch Ausgabe einer Meldung angezeigt. Eine Folge identischer Fehler innerhalb ein- und derselben OptiVec-Funktion führt dabei immer nur zu einer einzigen Meldung. Nachfolgende identische Meldungen werden unterdrückt. Zwischen Fließkomma- und Ganzzahlen besteht ein grundsätzlicher Unterschied bezüglich OVERFLOW- und DOMAIN- Fehlern: Für Fließkommazahlen sind dies ernst zu nehmende (OVERFLOW) bzw. meist zum Abbruch führende (DOMAIN) Fehler. Demgegenüber wird für Ganzzahlen eine implizite modulo-2n-Arithmetik verwendet, bei der diese "Fehler" gar nicht als solche betrachtet werden. Im Gegenteil: Häufig wird sogar der Überlauf als schnelles Mittel der modulo-Division ausgenutzt. In den folgenden beiden Abschnitten wird die Fehlerbehandlung von Fließkomma- und Ganzzahlen detailliert dargestellt. Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home 5.2 Ganzzahl-FehlerDie einzige Operation, die bei ganzen Zahlen immer ein Fehler ist, ist die Division durch 0, die zu einem ZERODIVIDE-Fehler führt. Überlauf- und Bereichs-Fehler, also INTEGER OVERFLOW und INTEGER DOMAIN (letztere entstehen z.B. beim Zuweisen einer negativen Zahl zu einem vorzeichenlosen Typ), werden schlicht ignoriert bzw. im Sinne der erwähnten impliziten modulo-2n-Arithmetik um-interpretiert. Für Fälle, in denen dies nicht erwünscht ist, bietet VectorLib neben der Normalversion aller Integer-Funktionen eine weitere Version mit der Möglichkeit, diese Fehler abzufangen und eine Fehlermeldung auszugeben, gegebenenfalls auch das Programm abzubrechen.Nur 32-bit-Versionen (also nicht für 64-bit):
Obwohl ein Aufruf von nur C/C++: Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home 5.3 Fließkomma-Fehler5.3.1 C/C++-spezifischDie Behandlung von Fließkomma-Fehlern lehnt sich eng an die Behandlung in den mathematischen Funktionen von C/C++ an. Insbesondere gilt auch für die Funktionen von OptiVec, daß _matherr (in Borland C vor der Version 4.0: matherr, ohne den Unterstrich) und _matherrl der Dreh- und Angelpunkt der Fehlerbehandlung sind und vom Benutzer auf die jeweiligen Bedürfnisse zugeschnitten werden können. Dabi wird _matherr von den VF_, VCF_, VD_ und VCD_-Funktionen verwendet und _matherrl von den VE_ und VCE_- Funktionen (letzteres nur Borland C++, da Visual C++ 80-bit-IEEE-Zahlen nicht unterstützt).Falls die Funktion, in der ein Fehler auftritt, ein reelles Argument enthält, wird nur der Parameter e->x definiert beim Aufruf von _matherr; e->y bleibt undefiniert. Nur falls zwei Argumente nötig sind (wie in VF_atan2 oder in VF_cotrpi), werden e->x und e->y zur Aufnahme dieser beiden Argumente benutzt. Bei komplexen Argumenten wird der Realteil (bzw. für Polarkoordinaten der Mag-Teil) in e->x übergeben und der Imaginärteil (bzw. der Zeigerwinkel) in e->y. Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home 5.3.2 Pascal/Delphi-spezifischDie in mathematischen Funktionen auftretenden Fehlerarten werden unten einzeln beschrieben. Wie OptiVec die einzelnen Fehlerarten behandelt, wird durch Aufruf von V_setFPErrorHandling vorgegeben. Die vorhandenen Optionen werden durch die vordefinierten Konstanten fperrXXX gesetzt, siehe V_setFPErrorHandling. Beim Aufruf von V_setFPErrorHandling sollten diese Konstanten mit dem OR-Operator verknüpft werden. Man beachte, daß dies nur die Behandlung von Fehlern beeinflußt, die innerhalb von OptiVec-Funktionen auftreten. Die zu Borland Pascal/Delphi gehörenden Standard-Funktionen bleiben hiervon unberührt.Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home 5.3.3 Fehlerarten (sowohl C/C++ als auch Pascal/Delphi)Für jede Funktion werden die möglichen Fehlerarten, die abgefangen und behandelt werden, in der Beschreibung der jeweiligen Funktion aufgeführt. Alle von mathematischen ANSI C- oder Pascal/Delphi-Funktionen abgeleiteten VectorLib-Funktionen (also diejenigen, deren Deklaration sich in <V?math.h> bzw. den Units V?math findet) führen eine vollständige Fehlerbehandlung für jedes Vektorelement durch. Über diese Fehlerbehandlung "pro Element" hinaus wird mit Hilfe des Rückgabewertes angegeben, ob insgesamt irgendein Fehler auftrat oder nicht. Ein Rückgabewert von FALSE (0) bedeutet Fehlerfreiheit; Rückgabewerte von TRUE (ungleich 0) zeigen aufgetretene (und behandelte) Fehler an.Bei der nun folgenden Beschreibung der einzelnen möglichen Fehler wird als "HUGE_VAL" der größte im jeweiligen Datentyp darstellbare Wert bezeichnet, also MAX_FLT, MAX_DBL oder MAX_LDBL, je nach Typ. Ähnlich wird mit "TINY_VAL" der kleinste eben noch darstellbare Wert ungleich 0 bezeichnet. Dies ist nicht dasselbe wie MIN_VAL, welches der kleinste mit voller Genauigkeit darstellbare Wert ist.
Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home 5.4 Die Behandlung nicht-normalisierter ZahlenNicht-normalisierte Zahlen (engl.: denormals) sind sehr kleine Zahlen zwischen 0 und der kleinsten in voller Genauigkeit darstellbaren Zahl des jeweiligen Datentyps. Man mag das ihnen zugrundeliegende Prinzip am folgenden vereinfachten Beispiel verstehen:1.175494E-38 ist die kleinste normalisierte float / Single, mit 7-stelliger Genauigkeit. Was geschieht, wenn diese Zahl durch, sagen wir, 1024 geteilt wird? Das Ergebnis kann nur als 0.001145E-38 dargestellt werden, das heißt, mit nur noch 4-stelliger Genauigkeit. Die ersten drei Stellen sind ja für führende Nullen verbraucht. Auf diese Weise "vermitteln" Denormals einen sanften Übergang zwischen sehr kleinen Zahlen und 0. Generell können sie als ganz gewöhnliche Zahlen behandelt werden. Bei der Bildung des Kehrwertes allerdings folgt ein Überlauf, und hier wird die etwas akademische Unterscheidung zwischen SING- und OVERFLOW-Fehlern fallengelassen und ein SING-Fehler angezeigt, als ob es sich um eine Division um exakt 0 handelte. Andererseits geben Denormals als Argumente von einigen Funktionen, beispielsweise log, völlig vernünftige Ergebnisse, während exakt 0 als Argument zu einem SING-Fehler führt. Leider behandeln die meisten Compiler auch für diese Funktionen Denormals als 0. Wir schließen uns dem nicht an und berechnen lieber das Ergebnis. Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home 5.5 Fortgeschrittene Fehlerbehandlung: Meldungen in eine Datei schreibenAllgemein bieten die mit Compilern mitgelieferten Bibliotheken dem Programmierer keine sehr gute Kontrolle über die Art, wie Fehlermeldungen ausgegeben werden. In den meisten Fällen ist dies akzeptabel. Gelegentlich möchte man aber vielleicht die Meldungen lieber in eine Datei schreiben, um nach Abarbeitung des Programms in Ruhe studieren zu können, was schiefgegangen ist. Unter Windows kommt noch hinzu, daß für jeden Fehler eine Meldungs-Box erzeugt wird, auf die der Anwender zu reagieren hat, bevor die Ausführung fortgesetzt werden kann.Man mag dies umgehen wollen. Eine einfache Lösung dieses Problems besteht in der Funktion V_setErrorEventFile. Diese Funktion benötigt als Argumente den Namen der gewünschten Ereignis-Datei ("Log-File") und einen Schalter, ScreenAndFile, der darüber entscheidet, ob Fehlermeldungen ausschließlich in die Datei (ScreenAndFile = FALSE (0)) oder außerdem noch auf dem Bildschirm (ScreenAndFile = TRUE (> 0)) auszugeben sind. Beispiel: Man beachte, daß die beschriebene Umleitung von Fehlermeldungen zunächst nur für Fehler gilt, die innerhalb von OptiVec-Funktionen auftreten. Es gibt aber in C/C++ die Möglichkeit, sie auch für alle anderen über _matherr und _matherrl behandelte Fehler auszunutzen. Hierzu muß die _matherr-Funktion so modifiziert werden, daß anstelle der Zeile
Eine Anwender-definierte Funktion _matherr (matherr – ohne Unterstich – für Borland C++ 3.0 und 3.1) könnte also etwa wie folgt aussehen:
Eine Möglichkeit, auch vom Auftreten der nicht zu einer Meldung führenden Fehler zu erfahren, wird durch die Rückgabewerte der mathematischen VectorLib-Funktionen geboten. Alle "stillen" TLOSS- ebenso wie die schwereren DOMAIN-, SING- und OVERFLOW-Fehler führen zu einem Rückgabewert von TRUE (ungleich 0). Man kann nach einer Reihe von Funktionsaufrufen testen, ob für alle Vektorelemente ein "sauberes" Resultat berechnet wurde, wie im folgenden C/C++-Beispiel:
Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home 5.6 OptiVec-FehlermeldungenWie in jedem in C/C++ oder Pascal/Delphi geschriebenen Programm führen Fehler in den mathematischen Funktionen zu entsprechenden Meldungen, siehe Absatz 5.3.3.Nicht nur in mathematischen Funktionen können freilich Fehler auftreten, sondern es gibt eine Reihe von Fehlern, die spezifisch für bestimmte Funktionen von OptiVec sind. Die durch sie erzeugten Meldungen werden in diesem Kapitel erläutert. Der in den Meldungen auftauchende Funktionsname ist nicht immer exakt derselbe, den Sie in Ihrem Programm geschrieben haben. So werden Sie anstelle des Präfixes VI_ entweder auf VSI_ oder VLI_ stoßen, je nach Speichermodell. Auch werden sich VFs_FFT oder VFl_FFT melden, wo Sie VF_FFT schrieben, wiederum abhängig vom Speichermodell. Der Grund für dieses Verhalten ist natürlich, daß viele Funktionen gemeinsamen Code benutzen und einige Namen als Synonyme für andere definiert sind.
Oder Sie haben versucht, OptiVec durch manuelles Entpacken der erhaltenen .ZIP-Dateien zu installieren, ohne INSTALL.EXE zu benutzen. Dies ist nicht möglich, da INSTALL.EXE die Uhr für die Testzeit startet. Unter Windows 2000 / XP müssen Sie statt des hier nicht lauffähigen INSTALL.EXE die Initialisierungs-Routine InitOVBC.EXE (Borland C++-Version) bzw. InitOVVC.EXE (MSVC-Version) ausführen.
Sie versuchen, Speicher zuzuweisen, aber es ist nicht mehr genügend vorhanden. Dieser Fehler kommt vor allem im Zusammenhand mit "vergessenen Vektoren" in Schleifen vor, die alloziert, aber niemals freigegeben werden. Man versuche die folgenden Lösungen: * Schnellstmögliche Freigabe aller nicht mehr gebrauchten Vektoren. Gehen Sie sicher, daß alle innerhalb eines Unterprogrammes erzeugten Vektoren wieder freigegeben werden, bevor das Unterprogramm verlassen wird. * Arbeiten Sie noch mit 16-bit-Modellen und müssen große Datenmengen verarbeiten? Steigen Sie auf das Speichermodell FLAT für Win32 und Windows95/98/NT um, wodurch der volle RAM-Speicher (und gegebenenfalls außerdem noch virtueller Speicher) verfügbar wird. * Lagern Sie Daten zwischendurch mittels VF_store auf Festplatte aus und lesen sie mit VF_recall wieder ein, wenn sie gebraucht werden. Diese Methode ist langsam und sollte nur im Notfall angewandt werden.
* Entweder versuchen Sie einen Vektor zu erzeugen, dessen Größe das Maximum von 4 GB (32-bit) bzw. 64 kB (16-bit-Speichermodelle außer HUGE) übersteigt. * Oder Sie benutzen das Speichermodell HUGE und rufen eine der wenigen Funktionen auf, bei denen bestimmte Vektoren auf 64 kB limitiert sind (wie z.B. die Tabellen in den Interpolations-Funktionen). Sie müssen auf 64-bit umsteigen, wenn sich Ihr Problem nicht in kleinere Portionen zerlegen läßt.
Bei einigen Funktionen, wo mehr als ein Eingangs-Vektor (bzw. -Matrix) verwandt wird, um mehr als einen Ergebnis-Vektor zu berechnen, muß darauf geachtet werden, welcher Ergebnis-Vektor welchen Eingangs-Vektor überschreiben darf oder eben nicht. Vergleiche die Beschreibung der jeweiligen Funktion.
Dieser Fehler taucht bei den Ausgabe-Funktionen (VF_print usw.) auf. Der Parameter nperline wurde zu groß für den jeweiligen Datentyp und die zur Verfügung stehende Zeilenlänge angegeben. Die Funktion wählt automatisch die maximal mögliche Zahl der Einträge pro Zeile und setzt hiermit die Ausführung des Programmes fort.
Die Interpolations-Routinen benötigen Tabellen, die gemäß ihren X-Werten geordnet sind. Jeder X-Wert darf nur einmal vorkommen, da unmöglich zu ein- und demselben X-Wert verschiedene Y-Werte gehören können.
Einige Funktionen verlangen das Vorhandensein einer minimalen Anzahl von n Vektor-Elementen.
Einige Funktionen begrenzen die Verarbeitung auf eine bestimmte Anzahl von n Vektor-Elementen (z.B. VF_polyinterpol, wo bis zu 10 Tabellen-Elemente für die Interpolation herangezogen werden können).
Für alle Funktionen, die – explizit oder implizit – Fast-Fourier-Transform-Methoden anwenden, muß die Vektorgröße eine ganzzahlige Potenz von 2 sein. Man vergrößere oder verkleinere den/die Vektoren, um diese Bedingung zu erfüllen.
In einigen Funktionen ist der zulässige Bereich eines oder mehrerer Eingabe-Parameter beschränkt. In anderen wiederum sind bestimmte Kombinationen von Eingabe-Parametern nicht erlaubt. So können Sie beispielsweise keine 9-Punkt-Interpolation mit nur 5 Datenpunkten durchführen.
Die in den Plot-Funktionen von VectorLib verwendeten Symbole können nicht um mehr als einen Faktor 50 vergrößert werden (was allerdings bereits bedeutet, den ganzen Bildschirm mit einem einzigen Symbol zu füllen). Die Ausführung des Programmes wird nach dieser Meldung mit dem – immer noch ziemlich unsinnigen – Wert von 30 fortgesetzt.
Die Linienstärke in den Plot-Funktionen von VectorLib kann nicht diecker als 500 Pixels sein (was ohnehin ein ziemlich unsinniger Wert ist). Die Ausführung des Programmes wird nach dieser Meldung mit dem Wert von 500 fortgesetzt.
Sie haben V_free oder V_nfree für einen Vektor aufgerufen, dem gar kein Speicher zugeordnet ist. Die Ausführung des Programmes wird nach dieser Meldung fortgesetzt, ohne daß irgendetwas freigegeben wird.
Auf die eine oder andere Weise erfüllen die Dimensionen von Ein- und Ausgabematrizen nicht die in der jeweiligen Funktionsbeschreibung genannten Bedingungen.
In einer Funktion, die reguläre Eingabematrizen verlangt, wurde eine singuläre Matrix angetroffen. Sie sollten eine alternative Funktion verwenden, die für die Behandlung auch (nahezu) singulärer Matrizen ausgelegt ist.
Einige iterative Matrix-Methoden können in sehr seltenen Fällen scheitern, indem auch nach zahlreichen Iterations-Durchläufen keine Konvergenz erreicht wurde.
Dieser Fehler taucht bei den Matrix-Ausgabefunktionen (MF_print usw.) auf, wenn die Zahl der Spalten größer ist als auf den Bildschirm paßt. Die Funktion wählt automatisch die maximal mögliche Spaltenzahl und schneidet die Zeilen am Bildschirmrand ab. Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home 6. Wenn etwas schiefgehtWenn Sie Probleme mit OptiVec haben, sollten Sie zuerst prüfen, ob die Installation korrekt durchgeführt wurde (s. Kap. 1.4). Weiterhin sollte man sehr genau darauf achten, die folgenden Bedingungen einzuhalten, deren Nichtbeachtung unweigerlich Schwierigkeiten nach sich zieht.
Obwohl OptiVec gründlich getestet worden ist, besteht natürlich immer die Möglichkeit, daß ein Problem unserer Aufmerksamkeit entgangen ist. Sollten Sie das Gefühl haben, auf ein solches Problem zu stoßen, so versuchen Sie doch bitte, die zu seinem Auftauchen führenden Bedingungen so genau wie möglich zu spezifizieren, und lassen Sie es uns unter support@optivec.de wissen! Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home 7. Die Include-Dateien und Units von OptiVecAlle C/C++-Include-Dateien von OptiVec haben dieselben Namen wie die entsprechenden Pascal/Delphi-Units. Natürlich ist die Namenserweiterung unterschiedlich: ".H" für die C/C++-Include-Dateien, ".DCU" für Delphi-Units und ".TPU" oder "TPP" für Pascal-Units. Unten werden nur die Namen ohne Erweiterung aufgeführt.Nur C/C++: Man deklariere den Gebrauch von OptiVec-Funktionen mit #include-Anweisungen. Falls Sie MFC (Microsoft Foundation Classes) oder Borlands OWL (ObjectWindows Library) verwenden, müssen die MFC- oder OWL-Include-Dateien vor(!) denen von OptiVec eingeschlossen werden. Nur Pascal/Delphi: Man deklariere den Gebrauch von OptiVec-Funktionen mit der uses-Anweisung.
Zurück zum VectorLib-Inhaltsverzeichnis OptiVec Home Copyright © 1996-2020 OptiCode – Dr. Martin Sander Software Development |