| CMATH Version 8
für C/C++ und für Pascal (Delphi und Lazarus)
|
OptiCode
Dr. Martin Sander Software-Entwicklung
Brahmsstr. 6
D-32756 Detmold
http://www.optivec.com
e-mail: optivec@gmx.de
|
|
CMATH ist sowohl separat erhältlich als auch als Teil von OptiVec. Falls Sie CMATH allein gekauft oder aus dem Internet heruntergeladen haben, ignorieren Sie bitte alle Verweise nach OptiVec in dieser Dokumentation.
Falls Sie andererseits CMATH zusammen mit OptiVec bekommen haben, sollten Sie zuerst HANDBUCH.HTM lesen. Dort sind die Grundsätze der OptiVec-Bibliotheken beschrieben. Außerdem enthält diese Datei einen Überblick über VectorLib, den ersten Teil von OptiVec. Der zweite Teil, MatrixLib, wird in MATRIXD.HTM dokumentiert.
Kap. 1.2 der vorliegenden Datei enthält die Lizenz-Bedingungen der Shareware-Version, Kap. 1.3 diejenigen der registrierten Vollversion.
OptiCode™ und OptiVec™ sind Warenzeichen von Dr. Martin Sander Software-Entwicklung. Andere zum Zwecke der Identifikation hier erwähnte Warenzeichen sind Eigentum der jeweiligen Hersteller.
Inhaltsverzeichnis
1. Einführung
1.1 Was ist CMATH ?
1.1.1 Besonderheiten für C/C++
1.1.2 Besonderheiten der Pascal/Delphi-Version
1.2 Lizenzbedingungen der Shareware-Version
1.3 Registrierte Vollversion
1.3.1 Preise und Bestellmöglichkeiten
1.3.2 Lizenzbedingungen
1.4 Installation und Start
2. Übersicht über die CMATH-Funktionen
2.1 Initialisierung komplexer Zahlen
2.2 Datentyp-Umwandlung
2.3 Komplexe Grundfunktionen
2.4 Arithmetische Operationen
2.5 Mathematische Funktionen
3. Fehlerbehandlung
3.1 Fehlerbehandlung komplexer Funktionen
3.2 Fortgeschrittene Fehlerbehandlung: Meldungen in eine Datei schreiben
4. Syntax-Referenz
4.1 Funktionsdeklarationen für C und Pascal/Delphi
4.2 Überladene C++/Delphi-Funktionen
1. Einführung
1.1 Was ist CMATH ?
CMATH ist eine umfassende Bibliothek komplexer Operationen und Funktionen, sowohl in cartesischen als auch in Polar-Koordinaten. Alle Funktionen können mit typenspezifischen Funktionsnamen von den Sprachen C und Pascal/Delphi aus aufgerufen werden (wie z.B. cf_sin, cd_exp, pe_sqrt). Für C++ existieren darüberhinaus überladene Funktionsnamen und Operatoren (wie z.B. sin, exp, sqrt, operator +). So weit möglich, haben alle Funktionen dieselben Namen in Pascal/Delphi wie in C.
Durch die Implementierung in Assembler bietet CMATH höchste Geschwindigkeit, Genauigkeit und Sicherheit (im Gegensatz zu dem compilierten oder Inline-C++-Code der erhältlichen komplexen Klassenbibliotheken). Nur für die aller-einfachsten Operationen sind alternative C++-Inline-Funktionen definiert.
Die Implementierung von CMATH richtete sich strikt nach den folgenden Regeln:
- An oberster Stelle steht ohne jeden Kompromiß das "richtige" Ergebnis, also das mathematisch korrekte Resultat, mit der für den jeweiligen Datentyp verlangten Genauigkeit. Hierzu müssen gerade bei komplexen Funktionen viele verschiedene Situationen voneinander getrennt behandelt werden, was eine pedantisch genaue Fall-Unterscheidung nötig macht.
- Mathematische Funktionen haben unter allen Umständen sicher zu sein. Sie dürfen also niemals einfach abstürzen, sondern müssen eine saubere Fehlerbehandlung durchführen. Dies gilt auch und gerade für mathematisch "unsinnige" Argumente (allerdings nicht für die Nicht-Zahlen INF und NAN, die nur aus unbehandelten Fehlern anderer Funktionen resultieren können).
- Die nicht als "mathematisch" behandelten Funktionen (also z.B. die Operatoren + - * / ) führen zwar keine Fehlerbehandlung durch, können also durchaus zum Programm-Abbruch durch Überlauf etc. führen; in jedem Fall gilt aber, daß nur ein nicht-darstellbares End-Ergebnis zum Fehler führen darf. Algorithmen, die mit potentiell überlaufenden Zwischen-Ergebnissen arbeiten, sind unbrauchbar.
- Durch alle nur möglichen Maßnahmen muß die maximale Ausführungsgeschwindigkeit erzielt werden. Sie als Anwender haben schließlich keine Zeit zu verschenken und sich nicht umsonst einen schnellen Rechner gekauft!
- Der Programm-Code soll so kompakt wie möglich sein. Im Falle von Zielkonflikten wird aber der Ausführungsgeschwindigkeit eindeutige Priorität eingeräumt.
Wer die komplexen Klassenbibliotheken gängiger Compiler anschaut, dem wird der Unterschied zwischen deren und unserem Ansatz schnell klar. Bei den mathematischen Funktionen sind häufig einfach die Formeln aus dem Lehrbuch
aufgeschrieben. Das liefert zwar relativ kompakten Source-Code, führt aber durch Rundungsfehler in Zwischenergebnissen zu mitunter drastisch ungenauen bis hin zu vollkommen falschen Ergebnissen oder gar zu nicht-abgefangenen
Fließkomma-Fehlern (das heißt: Absturz!). Außerdem ist der erzeugte Code langsam.
Die vorliegende Dokumentation beschreibt die Implementierungen von CMATH für
- Embarcadero / Borland / CodeGear C++ (alle Versionen von RAD Studio und C++ Builder; sogar Borland C++ Version 5.0 funktioniert noch immer) unter 64-bit oder 32-bit Windows.
- Microsoft Visual C++ (alle Versionen von Visual Studio und MSVC bis hinab zu VS 2005) für 32-bit und für 64-bit Windows auf PC-Plattformen
- GCC (jeweils aktuelle Version) sowohl für 32-bit als auch für 64-bit-Windows auf PC-Plattformen
- LLVM CLang (jeweils aktuelle Version) sowohl für 32-bit als auch für 64-bit-Windows auf PC-Plattformen
- Embarcadero / Borland Delphi Version 12, 11.x, 10.x, XE-Serie, 2010, 2009 (RAD Studio, Borland Development Studio), für 32-bit oder 64-bit Windows
- Lazarus / FreePascal, ausschließlich 64-bit-Windows-Plattform.
Man beachte, daß nur die Dokumentation für diese verschiedenen Compiler gemeinsam gültig ist. Die Bibliotheken selbst sind Compiler-spezifisch; jede von ihnen kann nur mit einem dieser Compiler und – im Falle von C/C++ – mit jeweils einem Speichermodell oder einem Target verwendet werden.
- Embarcadero / Borland / CodeGear C++:
Sie müssen zwei Bibliotheken einbinden: eine Basis-Bibliothek, die für die jeweilige Compiler-Version und -Konfiguration spezifisch ist, sowie eine Prozessor-spezifische zweite Bibliothek. Beispielsweise würden Sie für den klassischen bcc32-Compiler mit statischer BC-Laufzeitbibliothek und mit breitestmöglicher Prozessor-Unterstützung CMATHFS.LIB + CMATHF4W.LIB einbinden. Details zur Bibliotheks-Auswahl finden Sie in Kap. 1.4
- Microsoft Visual C++:
Die Shareware-Version ist für "multi-thread Debug" und "multi-thread DLL Debug", sowohl für 32-bit als auch für 64-bit. Die Vollversion enthält zusätzlich die zugehörigen Release-Bibliotheken. Es ist zwar keine Debug-Information in den OptiVec "Debug"-Bibliotheken enthalten; sie müssen aber mit den Debug-Bibliotheken von Visual C++ verwendet werden.
- GCC und LLVM CLang:
Abweichend von den Bedingungen für die kommerziellen Compiler stellen wir für die freien Compiler die 32-bit P4- und die 64-bit P8-Bibliothek als Freeware zur Verfügung.
nur GCC: Sowohl für 32-bit als auch für 64-bit werden die gängigen Konfigurationen von GCC mit jeweils einer eigenen Basis-Bibliothek abgedeckt, also Windows- bzw. Posix-Threads und hierfür jeweils die Auswahl zwischen SEH-, Dwarf- oder Setjmp-Longjmp-Exceptions.
- Delphi:
Jede Delphi-Version erfordert ihre eigene zugehörige CMATH-Version.
- Lazarus / FreePascal:
Alle CMATH-Routinen sind als cdecl deklariert und müssen in korrekter Groß- und Kleinschreibung angegeben werden. Technischer Grund hierfür ist, dass Lazarus bei den übrigen Aufruf-Modellen die Namen mit Datentyp-Informationen "dekoriert" und daher die in Assembler geschriebenen und als Object-Dateien gelieferten Routinen nicht finden würde.
Zurück zum Inhaltsverzeichnis
1.1.1 Besonderheiten für C/C++
Die in CMATH definierten C++-Klassen und C-structs sind miteinander vollständig binär kompatibel. Dies kann wichtig werden, wenn in großen Projekten C- und C++-Module gemischt werden.
Bereits existierender C++-Code, der die in <complex.h> enthaltene komplexe Klassenbibliothek von Borland C++
verwendet, kann praktisch unverändert bleiben, da CMATH funktional und binär vollständig kompatibel mit <complex.h> ist. Die einzige Ausnahme stellt die Member-Funktion polar dar, die durch magargtoc ersetzt werden mußte, da der Begriff "polar" nun die komplexen Klassen in Polarkoordinaten bezeichnent.
Der Wechsel von der mit Borland C++ ausgelieferten komplexen Klassenbibliothek zu CMATH wird im folgenden ausführlich beschrieben:
- In C++-Modulen schaltet die Deklaration
#include <newcplx.h>
anstelle von
#include <complex.h>
auf die CMATH-Bibliotheksfunktionen um. Dann existieren die folgenden sechs komplexen Klassen:
class complex<float>, class complex<double>, class complex<long double>, class polar<float>, class polar<double> und class polar<long double>.
Die Datentypen fComplex, dComplex, eComplex, fPolar, dPolar und ePolar werden als Synonyme für diese Klassen definiert.
Um den durch long und unsigned long bereits überbelegten Buchstaben "L" zu umgehen, wird in den CMATH-Versionen für die Borland-Compiler der Begriff extended als Synonym für long double verwendet. Da MSVC 80-bit-Fließkommazahlen nicht unterstützt, ist hier extended als doubledefiniert. Die extended-genauen komplexen Datentypen werden dementsprechend als eComplex und ePolar bezeichnet. Hierdurch wird u.a. der Weg offengehalten, CMATH zukünftig auf komplexe Ganzzahl-Typen auszudehnen, wobei liComplex und ulComplex die aus long int bzw. unsigned long bestehenden Typen sein werden.
- Wenn Sie die "klassische" class complex älterer Versionen von Borland C++ verwenden möchten, deklarieren Sie bitte
#define CMATH_CLASSIC_COMPLEX
vor (!) dem Einschließen von
<newcplx.h>.
In diesem Fall existiert nur eine Klasse: die aus doubles bestehende class complex, der das Synonym dComplex zugeordnet wird. Einfach- oder extended-genaue komplexe Typen existieren dann ebensowenig wie Funktionen in Polarkoordinaten.
- In reinen C-Modulen darf nicht
#include <newcplx.h> deklariert werden. An dessen Stelle muß stehen:
#include <cmath.h>
Falls Sie nur eine einzige Genauigkeitsstufe verwenden, können Sie auch die entsprechende typenspezifische Include-Datei einschließen:
<cfmath.h>, <cdmath.h> oder
<cemath.h>.
Die Implementation von CMATH für klassisches C basiert auf den folgenden Definitionen der komplexen Datentypen:
typedef struct { float Re, Im; } fComplex;
typedef struct { double Re, Im; } dComplex;
typedef struct { extended Re, Im; } eComplex;
typedef struct { float Mag, Arg; } fPolar;
typedef struct { double Mag, Arg; } dPolar;
typedef struct { extended Mag, Arg; } ePolar;
Wie oben erwähnt, wird der Datentyp extended als Synonym für long double (Borland-Versionen) oder double (MSVC-Version) verwendet.
- Man ersetzt Aufrufe der komplexen Member-Funktion polar durch magargtoc.
- Ebenso wie in den structs sind auch in allen definierten komplexen Klassen die Real- und Imaginärteile als "Re" und "Im" bezeichnet und (im Unterschied zu Borland C++ !) als public deklariert. Dadurch wird ein einheitlicher Zugriff in der Art z.Re, z.Im, p.Mag oder p.Arg sowohl für C++- als auch klassische C-Module ermöglicht.
- Für zeitkritische Anwendungen wird empfohlen, die C-Version anstelle der C++-Version zu verwenden, da C/C++- Compiler structs wesentlich effizienter als Klassen handhaben können. Dies heißt nicht, daß Sie Ihre Projekte nun in C statt C++ schreiben sollten. Die folgenden Hinweise zeigen, wie die C-Version von CMATH in C++-Modulen zu verwenden ist:
- Man schließe <cmath.h> anstelle von <newcplx.h> ein.
- Zur Initialisierung weise man den Real/Imaginär- oder Mag/Arg-Teilen die gewünschten Werte direkt zu (z.B. z.Re = 3; z.Im = 5; ) oder benutze die Funktionen fcplx, dcplx, ecplx, fpolr, dpolr, epolr. Die Konstruktoren complex(), fComplex(), polar(), fPolar() usw. stehen hier nicht zur Verfügung.
- Da nicht nur Member-Funktionen von Klassen, sondern natürlich auch Funktionen der als structs definierten komplexen Zahlen überladen werden können, stehen alle weiteren CMATH-Funktionen auch nach Einschluß von <cmath.h> anstelle von <newcplx.h> als überladene C++-Funktionen zur Verfügung. Sie haben also die Wahl zwischen den typenspezifischen Namen (wie cf_sin, cd_exp), oder den überladenen C++-Namen (wie sin, exp). Manchmal ist man allerdings gezwungen, die typenspezifischen Namen zu verwenden, um Zweideutigkeiten aufzulösen.
Zurück zum Inhaltsverzeichnis
1.1.2 Besonderheiten der Pascal/Delphi-Version
CMATH für Pascal/Delphi definiert sechs komplexe Datentypen:
type fComplex = record Re, Im: Single; end;
type dComplex = record Re, Im: Double; end;
type eComplex = record Re, Im: Extended; end;
type fPolar = record Mag, Arg: Float; end;
type dPolar = record Mag, Arg: Double; end;
type ePolar = record Mag, Arg: Extended; end;
Der Grund, warum der einfach-(Single-)genaue Typ den Namen fComplex anstatt sComplex erhält, ist, daß der Buchstabe "s" in Pascal schon überbelegt ist durch ShortInt und SmallInt. Daher wird dieser Typ von dem C/C++-Analogon von Single, nämlich float abgeleitet. Auf diese Weise bleiben auch die Funktionsnamen identisch für C und Pascal/Delphi.
Die Datentypen von CMATH für Pascal/Delphi sind binär kompatibel mit denjenigen der C/C++-Versionen.
Die typen-spezifischen Funktionsnamen (mit Präfix) sind dieselben wie in der C-Version. Die Syntax ist allerdings etwas verschieden, da hier komplexe Rückgabewerte am effizientesten so implementiert werden konnten, dass diese als var-Argumente an die komplexen Funktionen übergeben werden, z.B.
procedure cf_sin( var zy:fComplex; zx:fComplex );
Es sind jedoch außer den typen-spezifischen auch überladene Funktionsnamen definiert. Es sind dieselben wie in der C++ version. Hier werden die Ergebnisse als echte Rückgabewerte behandelt, z.B.
function sin( zx:fComplex ): fComplex;
Schließlich boten erst die Delphi-Versionen ab Delphi 2006 die Möglichkeit, arithmetische Operatoren für komplexe Argumente zu implementieren. CMATH für die früheren Delphi-Versionen bietet stattdessen die entsprechenden Funktionen (siehe Kap. 2.4).
Zurück zum Inhaltsverzeichnis
1.2 Lizenzbedingungen für die Shareware-Version
Falls Sie CMATH als Teil von OptiVec erhalten haben, ist die CMATH-Lizenz in der OptiVec-Lizenz enthalten. Andernfalls gelten die folgenden Lizenzbedingungen für die Shareware-Version von CMATH. Die Lizenzbedingungen für die registrierte Vollversion sind in Kap. 1.3 angegeben.
Dies ist die Shareware-Version von CMATH ("SOFTWARE").
Ihre Nutzung unterliegt den folgenden Lizenzbedingungen:
- Sie dürfen diese SOFTWARE gebührenfrei für einen Zeitraum von 90 Tagen auf einem Rechner testen.
- Mit der Shareware-Version dieser SOFTWARE erstellte Anwendungen sind nur auf demselben Rechner lauffähig, auf dem die SOFTWARE installiert wurde. Sie können und dürfen nicht an Dritte weitergegeben werden. Nach dem Ende der Test-Zeit sind sie nicht mehr ausführbar.
- Falls Sie die SOFTWARE nach Ablauf der Testzeit weiterbenutzen und/oder Anwendungen, die Funktionen dieser SOFTWARE enthalten, zu gewerblichen Zwecken verwenden möchten, müssen Sie die registrierte Vollversion erwerben (siehe Kap. 1.3).
- Sonderbedingung für die 32-bit P4 und die 64-bit P8 Bibliotheken für GCC und für LLVM CLang: Diese Bibliotheken sind Freeware. Sie dürfen kostenfrei und zeitlich unbegrenzt genutzt werden, sowohl in nicht-kommerziellen als auch in kommerziellen Anwendungen. Mit diesen Bibliotheken erstellte Anwendungen dürfen unbegrenzt an Dritte weitergegeben werden.
- Die SOFTWARE wird auf "as is"-Basis zur Verfügung gestellt. Jegliche explizite oder implizite Garantieleistungen sind ausdrücklich ausgeschlossen.
- Trotz sorgfältigen Testens können keinerlei Zusicherungen bezüglich des fehlerfreien Funktionierens, der Eignung für einen bestimmten Zweck oder der Marktgängigkeit gemacht werden.
- Daher darf diese SOFTWARE nicht in Umgebungen oder unter Umständen eingesetzt werden, unter denen Fehler der SOFTWARE zu größeren materiellen Verlusten oder gar zu Schäden an Leib und Leben führen könnten.
- Zurück-Entwickeln (Reverse engineering), Dekompilieren und Entassemblieren der SOFTWARE sind nicht gestattet. Selbstverständlich dürfen Sie aber die in Ihre eigenen Programme eingebundenen Funktionen der SOFTWARE mit Hilfe von Debuggern (wie z.B. den mit den Compilern von Borland oder Microsoft gelieferten) inspizieren.
Copyright für SOFTWARE und Dokumentation © 1996-2024 OptiCode - Dr. Martin Sander Software-Entwicklung.
Alle Rechte vorbehalten.
Zurück zum Inhaltsverzeichnis
1.3 Registrierte Vollversion
1.3.1 Preise und Bestellmöglichkeiten
Sie können entweder eine Lizenz für die jeweils für einen einzigen Target-Compiler geeigneten Bibliotheken erwerben ("CMATH for xxx") oder für einen geringen Aufpreis eine CMATH Master-Lizenz, die sämtliche unterstützten Compiler abdeckt.
Um dieses Produkt auch für diejenigen erschwinglich zu machen, die durch seinen Einsatz selbst kein Geld verdienen, bieten wir zusätzlich zur kommerziellen Edition auch eine Schulversion zu einem stark reduzierten Preis an. Inhaltlich sind beide Versionen identisch. Sie unterscheiden sich lediglich in den Nutzungs-Beschränkungen der Schulversion, die nicht für kommerzielle Zwecke und nicht in nicht-bildungsbezogenen staatlichen Institutionen eingesetzt werden darf.
Der Erwerb der registrierten Version gibt Ihnen das Recht der Verwendung auf so vielen Rechnern gleichzeitig wie Sie Exemplare erworben haben.
Das Recht, CMATH-Funktionen enthaltende Anwendungen an Dritte weiterzugeben, ist in der kommerziellen Edition enthalten. Es sind keine zusätzlichen Laufzeit-Lizenzen für Ihre Kunden erforderlich.
Großkunden-Lizenzen sind auf Anfrage erhältlich!
Preisliste
CMATH separat; für einzene Compiler: C++ Builder, Visual C++, GCC (Win), LLVM CLang (Win), Delphi, Lazarus / FreePascal oder Linux (GCC / CLang) |
| | Preise incl. 19% deutscher MWSt | Preise netto |
kommerzielle Edition |
Einzel-Lizenz |
5-fach Lizenz |
10-fach Lizenz | |
EUR 59 |
EUR 175 (35,00 pro Lizenz) |
EUR 295 (29,50 pro Lizenz) | |
EUR 49,58 |
EUR 147,06 (29,41 pro Lizenz) |
EUR 247,90 (24,79 pro Lizenz) | |
Schulversion |
Einzel-Lizenz |
5-fach Lizenz |
10-fach Lizenz | |
EUR 29 |
EUR 85 (17,00 pro Lizenz) |
EUR 145 (14,50 pro Lizenz) | |
EUR 24,37 |
EUR 71,43 (14,29 pro Lizenz) |
EUR 121,85 (12,19 pro Lizenz) | |
|
CMATH separat; Master-Lizenz für alle unterstützten Compiler |
| | Preise incl. 19% deutscher MWSt | Preise netto |
kommerzielle Edition |
Einzel-Lizenz |
5-fach Lizenz |
10-fach Lizenz | |
EUR 89 |
EUR 265 (53,00 pro Lizenz) |
EUR 445 (44,50 pro Lizenz) | |
EUR 74,79 |
EUR 222,69 (44,54 pro Lizenz) |
EUR 373,95 (37,40 pro Lizenz) | |
Schulversion |
Einzel-Lizenz |
5-fach Lizenz |
10-fach Lizenz | |
EUR 49 |
EUR 145 (29,00 pro Lizenz) |
EUR 245 (24,50 pro Lizenz) | |
EUR 41,18 |
EUR 121,85 (24,37 pro Lizenz) |
EUR 205,88 (20,59 pro Lizenz) | |
|
Bei postalischer Lieferung (CD-ROM) zzgl. EUR 5,- Versandkosten-Pauschale.
Die Preise incl. deutscher MWSt gelten innerhalb Deutschlands sowie für private Besteller innerhalb der EU. Falls Sie eine Europäische VAT ID besitzen oder von außerhalb der Europäischen Union bestellen, entfällt die deutsche MWSt. Dafür muss vom Erwerber der in seinem Heimatland gültige Satz abgeführt werden, bei Lieferung außerhalb der EU gegebenenfalls auch noch Import-Zoll.
Bestellungen bitte über www.optivec.de/order/
oder mit diesem Bestell-Formular an
OptiCode –Dr. Martin Sander Software Entwicklung
Brahmsstr. 6
D-32756 Detmold
optivec@gmx.de
Für Fragen zur Bestellung von CMATH stehen wir Ihnen unter optivec@gmx.de zur Verfügung.
Zurück zum Inhaltsverzeichnis
1.3.2 Lizenzbedingungen für die registrierte Vollversion
Falls Sie CMATH als Teil von OptiVec erhalten haben, ist die CMATH-Lizenz in der OptiVec-Lizenz enthalten. Andernfalls gelten die folgenden Lizenzbedingungen für die Vollversion von CMATH:
Dies ist eine Einzelplatz-Lizenz für CMATH ("SOFTWARE"), die Ihnen als End-Anwender von OptiCode - Dr. Martin Sander Software-Entwicklung ("OptiCode") gewährt wird. Der Begriff "Anwender" bezeichnet einen Programmierer, der Binär-Code dieser SOFTWARE in von ihm geschriebene Anwendungen einbindet. Diejenigen wiederum, die seine Anwendungen benutzen, ohne dafür diese SOFTWARE selbst installieren zu müssen, benötigen keine eigene Laufzeit-Lizenz für die SOFTWARE. Das Recht, Anwendungen kommerziell zu nutzen und weiterzugeben, ist in der Lizenzgebühr der kommerziellen Version enthalten.
Nach Zahlung der im Kaufpreis enthaltenen Lizenzgebühr dürfen Sie die SOFTWARE für unbegrenzte Zeit benutzen, sofern Sie das Copyright nicht verletzen und die folgenden Regeln einhalten:
- Die SOFTWARE darf auf jedem hierfür geeigneten Computer verwandt werden, solange nicht mehr als eine Person sie gleichzeitig benutzt. Wenn mehrere Personen die SOFTWARE auf einem oder mehreren Computern gleichzeitig benutzen wollen (z.B. in einem Netzwerk), ist eine Mehrfach-Lizenz zu erwerben.
- Sie dürfen zum persönlichen Gebrauch Backup-Kopien der gelieferten Datenträger machen. Sie dürfen die SOFTWARE nicht verleihen oder vermieten. Sie dürfen sie jedoch auf Dauer an einen anderen übertragen, sofern Sie die Original-Datenträger vollständig weitergeben und alle von Ihnen gemachten Kopien vernichten und sofern sich der Empfänger mit diesen Lizenzbedingungen einverstanden erklärt.
- Zurück-Entwickeln (Reverse engineering), Dekompilieren und Entassemblieren der SOFTWARE sind nicht gestattet. Selbstverständlich dürfen Sie aber die in Ihre eigenen Programme eingebundenen Funktionen der SOFTWARE mit Hilfe von Debuggern (wie z.B. den mit den Compilern von Borland oder Microsoft gelieferten) inspizieren.
- Falls Sie die ermäßigte Lizenzgebühr für die Schulversion anstelle der vollen Gebühr für die kommerzielle Version der SOFTWARE in Anspruch genommen haben, ist der Einsatz der SOFTWARE auf private Nutzung sowie Nutzung zum Zwecke der Ausbildung beschränkt. In diesem Falle darf die SOFTWARE nicht für kommerzielle Zwecke und nicht für andere staatliche Aufgaben als Erziehung und Ausbildung eingesetzt werden.
Anwendungen, die Funktionen dieser SOFTWARE verwenden, dürfen nur dann gebührenfrei weitergegeben werden (ohne Laufzeit-Lizenz), wenn sie mit der kommerziellen Version erstellt wurden. Außerdem müssen die Funktionen der SOFTWARE permanent in die jeweilige Anwendung eingebunden sein und dürfen dem Benutzer der Anwendung nicht als Bibliothek entgegentreten.
- Die SOFTWARE darf nicht in Umgebungen oder unter Umständen eingesetzt werden, unter denen eventuelle Fehler der SOFTWARE zu einer Gefahr für irgendjemandes Leib und Leben oder zu größeren materiellen Verlusten führen könnten.
- Die Haftung von OptiCode ist durch die beigefügte Beschränkte Garantie eingeschränkt. In jedem Fall ist die Haftung von OptiCode auf den Betrag beschränkt, den Sie tatsächlich für die Benutzung der SOFTWARE bezahlt haben.
Beschränkte Garantie für die registrierte Vollversion
- OptiCode garantiert, daß die magnetischen oder optischen Medien, auf denen die SOFTWARE aufgezeichnet ist, sowie die gedruckte Dokumentation bei normaler Benutzung frei von Material- und Verarbeitungsfehlern sind. Ferner wird garantiert, dass die SOFTWARE selbst im Wesentlichen gemäß der begleitenden gedruckten Dokumentation arbeitet.
- Die obigen Garantien gelten für einen Zeitraum von sechs Monaten ab Empfangsdatum.
- Die gesamte Haftung von OptiCode und Ihr alleiniger Anspruch als Kunde besteht nach Wahl von OptiCode entweder in der Rückerstattung des bezahlten Preises oder in dem Ersatz der obiger Garantie nicht genügenden und an OptiCode (unter Nachweis des rechtmäßigen Erwerbs) zurückgegebenen Teile.
- Trotz sorgfältigen Testens kann nicht garantiert werden, dass die SOFTWARE oder die Dokumentation vollständig frei von Fehlern sind.
- Alle impliziten Garantien, z.B. bezüglich Marktgängigkeit, Eignung für einen bestimmten Zweck oder Nichtverletzung von Rechten Dritter, sind auf die oben explizit gegebenen Garantien beschränkt.
- OptiCode ist nicht für Folgeschäden (uneingeschränkt eingeschlossen sind Schäden aus entgangenem Gewinn, Betriebsunterbrechung, Verlust von geschäftlichen Informationen oder Daten oder aus anderem finanziellen Verlust) ersatzpflichtig, die aufgrund der Benutzung dieses Produktes oder der Unfähigkeit, es zu verwenden, entstehen, selbst wenn OptiCode von der Möglichkeit eines solchen Schadens unterrichtet worden ist. Dieser Ausschluss gilt nicht für Schäden, die durch Vorsatz oder grobe Fahrlässigkeit auf seiten von OptiCode verursacht wurden. Ansprüche, die auf unabdingbaren gesetzlichen Vorschriften zur Produkthaftung beruhen, bleiben ebenfalls unberührt.
Copyright für SOFTWARE und Dokumentation
© 1996-2024 OptiCode - Dr. Martin Sander Software-Entwicklung. Alle Rechte vorbehalten.
Zurück zum Inhaltsverzeichnis
1.4 Installation und Start
Falls Sie CMATH als Teil von OptiVec erhalten haben, wird CMATH bereits bei der Installation von OptiVec mit installiert, und Sie sollten Kap. 1.4 von HANDBUCH.HTM anstelle dieses Abschnitts lesen. Falls Sie dies bereits getan haben, setzen Sie bitte bei Kap. 2 fort, oder gehen Sie zum Inhaltsverzeichnis.
Ansonsten führen Sie bitte die folgenden Schritte aus:
Sie benötigen zunächst eine bereits installierte Kopie Ihres Compilers. Installieren Sie dann CMATH, indem Sie INSTALL.EXE vom Wurzelverzeichnis der Installations-CD ausführen. Normalerweise wird CMATH in ein Verzeichnis mit dem Namen "CMATH" installiert. Es steht Ihnen jedoch frei, ein anderes Verzeichnis zu wählen. (Falls CMATH als Teil von OptiVec installiert wird, befindet es sich gemeinsam mit VectorLib und MatrixLib im Verzeichnis OPTIVEC.) Dieses Verzeichnis enthält nach abgeschlossener Installation die Dokumentation.
Sie müssen die bei der Installation von CMATH gewählten Verzeichnisse dem Bibliotheks-Suchpfad und dem Include-File-Suchpfad (C/C++) bzw. dem Units-Suchpfad (Delphi) hinzufügen.
Springen Sie zur Beschreibung für Ihre spezifische Version:
1.4.1 CMATH für C++ Builder (Embarcadero / Borland C++)
Angenommen, Ihr CMATH-Verzeichnis sei C:\CMATH, müssen Sie
C:\CMATH\LIB zu dem Bibliotheks-Suchpfad und
C:\CMATH\INCLUDE zu dem Suchpfad für Include-Dateien hinzufügen. Beides sollte sowohl in der IDE (Options/Directories) also auch - falls Sie ihn verwenden - in der Konfigurationsdatei des Kommandozeilen-Compilers, BCC32.CFG, geschehen.
Sie müssen zwei CMATH-Bibliotheken einbinden: Zuerst die CMATH-Basisbibliothek:
Plattform | Compiler | statische Laufzeitbibliothek | Laufzeitbibliothek als DLL |
Win64 | bcc64, ab RAD Studio 12 (2023) | cmbcbase64.a | cmbcbase64.a |
| bcc64, alle Versionen bis RAD Studio 11.x | cmbcx64.a | cmbcx64.a |
Win32 | "klassischer" Borland Compiler bcc32
ab RAD Studio / BCB 12 (2023) | cmbcbase32s.lib | cmbcbase32d.lib |
| ältere Versionen bis einschl. 11.x | cmathfs.lib | cmathfd.lib |
| CLang-Borland Compiler bcc32c
ab RAD Studio 12 | cmbcbase32cs.lib | cmbcbase32cd.lib |
| RAD Studio 10.x, 11.x | cmbc10_11base32cs.lib | cmbc10_11base32cd.lib |
Als zweites wählen Sie bitte zwischen der Bibliothek mit größtmöglicher Prozessor-Kompatibilität und der etwas schnelleren für neuere Prozessoren:
Plattform | Compiler | Prozessor | CMATH-Bibliothek |
Win64 | bcc64 | mind. Core2xx, AMD x64) | CMBC64_8.a |
Win32 | bcc32 (klassisch) | neuere Prozessoren (mind. Core2xx, AMD x64) | CMATHF8W.LIB |
| | 486DX/Pentium | CMATHF4W.LIB |
| bcc32c (CLang) ab C++ Builder 10.1 Berlin | neuere Prozessoren (mind. Core2xx, AMD x64) | cmbc32c_8.lib |
| | 486DX/Pentium | cmbc32c_4.lib |
| bcc32c (CLang) bis C++ Builder 10 Seattle | neuere Prozessoren (mind. Core2xx, AMD x64) | CMATHF8W.LIB |
| | 486DX/Pentium | CMATHF4W.LIB |
Alle in früheren Versionen von CMATH gültigen Einschränkungen für die Verwendung mit dem 32-bit CLang-Borland-Compiler bcc32c.exe sind aufgehoben.
Fortsetzung mit Kap. 1.5 Deklaration von CMATH-Funktionen in C/C++
1.4.2 CMATH für Visual C++ (Microsoft Visual Studio)
Angenommen, Ihr CMATH-Verzeichnis sei C:\CMATH, müssen Sie
C:\CMATH\LIB zu dem Bibliotheks-Suchpfad und
C:\CMATH\INCLUDE zu dem Suchpfad für Include-Dateien hinzufügen.
Sie müssen nicht nur eine, sondern zwei CMATH-Bibliotheken einschließen. Die erste enthält das Interface zwischen CMATH und der VC-Laufzeitbibliothek; sie ist spezifisch für die jeweils gewünschte Projekt-Konfiguration. Die zweite Bibliothek wiederum ist unabhängig von der jeweiligen Projekt-Konfiguration; durch sie entscheiden Sie über die Prozessor-Unterstützung.
Wählen Sie also zunächst die gewünschte Projekt-Konfiguration und Laufzeitbibliothek. Letztere finden Sie unter Projekt / (Konfigurations-)Eigenschaften / C/C++ / Code-Generation / Laufzeitbibliothek. Unter Projekt / (Konfigurations-)Eigenschaften / Linker / Eingabe fügen Sie die entsprechende CMATH-Bibliothek Ihrem Projekt hinzu, gemäß der folgenden Tabelle.
Plattform | Visual Studio Version | Runtime Debug DLL | Debug Static | Release DLL | Release Static |
Win64 | VS 2022 | CMVC17x64MDD.LIB | CMVCx64MTD.LIB | CMVC17x64MDR.LIB | CMVCx64MTR.LIB |
Win64 | VS 2019 | CMVC16x64MDD.LIB | CMVCx64MTD.LIB | CMVC16x64MDR.LIB | CMVCx64MTR.LIB |
| VS 2017 | CMVC15x64MDD.LIB | CMVCx64MTD.LIB | CMVC15x64MDR.LIB | CMVCx64MTR.LIB |
| VS 2015 | CMVC14x64MDD.LIB | CMVCx64MTD.LIB | CMVC14x64MDR.LIB | CMVCx64MTR.LIB |
| VS 2013 | CMVC12x64MDD.LIB | CMVC8_12x64MTD.LIB | CMVC12x64MDR.LIB | CMVC8_12x64MTR.LIB |
| VS 2012 | CMVC11x64MDD.LIB | CMVC8_12x64MTD.LIB | CMVC11x64MDR.LIB | CMVC8_12x64MTR.LIB |
| VS 2010 | CMVC8x64MDR.LIB* | CMVC8_12x64MTD.LIB | CMVC8x64MDR.LIB | CMVC8_12x64MTR.LIB* |
| VS 2008 | CMVC8x64MDR.LIB* | CMVC8_12x64MTD.LIB | CMVC8x64MDR.LIB* | CMVC8_12x64MTR.LIB |
| VS 2005 | CMVC8x64MDD.LIB | CMVC8_12x64MTD.LIB | CMVC8x64MDR.LIB | CMVC8_12x64MTR.LIB |
Win32 | VS 2022 | CMVC17MDD.LIB | CMVCMTD.LIB | CMVC17MDR.LIB | CMVCMTR.LIB |
| VS 2019 | CMVC16MDD.LIB | CMVCMTD.LIB | CMVC16MDR.LIB | CMVCMTR.LIB |
| VS 2017 | CMVC15MDD.LIB | CMVCMTD.LIB | CMVC15MDR.LIB | CMVCMTR.LIB |
| VS 2015 | CMVC14MDD.LIB | CMVCMTD.LIB | CMVC14MDR.LIB | CMVCMTR.LIB |
| VS 2013 | CMVC12MDD.LIB | CMVC8_12MTD.LIB | CMVC12MDR.LIB | CMVC8_12MTR.LIB |
| VS 2012 | CMVC11MDD.LIB | CMVC8_12MTD.LIB | CMVC11MDR.LIB | CMVC8_12MTR.LIB |
| VS 2010 | CMVC10MDD.LIB | CMVC8_12MTD.LIB | CMVC10MDR.LIB | CMVC8_12MTR.LIB |
| VS 2008 | CMVC9MDD.LIB | CMVC8_12MTD.LIB | CMVC9MDR.LIB | CMVC8_12MTR.LIB |
| VS 2005 | CMVC8MDD.LIB | CMVC8_12MTD.LIB | CMVC8MDR.LIB | CMVC8_12MTR.LIB |
*Für die veralteten VS-Versionen 2008 und 2010 stehen die 64-bit Bibliotheken fü dynamische Runtime nicht zur Verfügung. Ersatzweise können die entsprechenden VS2005-Bibliotheken verwendet werden. In diesem Fall müssen Sie eventuell zusätzliche Redistributables installieren. Sie finden diese auf www.microsoft.com/download. Geben Sie "vcredist_x86" oder "vcredist_x64" in die Suchmaske ein, um die Liste der verfügbaren Redistributables zu erhalten, und wählen diejenigen für Visual Studio 2005.
Man beachte, dass es eine gewisse Inkonsistenz in den Konfigurations- Bezeichnungen von Visual Studio gibt: Die Standard-Konfigurationen "Debug" und "Release" binden die Laufzeitbibliothek und MFC als DLL ein, stellen also die in früheren Versionen "Debug DLL" und "Release DLL" genannten Konfigurationen dar. Das bedeutet, dass die CMath-Basisbibliotheken CMVC??MDD.lib und CMVC??MDR.lib mit diesen Konfigurationen zu benutzen sind. Außerdem muss sichergestellt sein, dass die Laufzeit- und MFC-DLL's auf jedem Rechner installiert sind, auf dem eine so erstellte Anwendung laufen soll. Für viele Anwendungen empfiehlt es sich daher, Project / Properties / Configuration Properties / C/C++ / Code Generation / Runtime Library in "Multi-Thread Debug (/MTd)" oder "Multi-Thread Release (MT)" zu ändern, um durch statisches Linken die DLL-Redistributables zu vermeiden. Dies ist in der "DebugStatic"-Konfiguration in den Demo-Dateien von CMath so realisiert.
Als zweites fügen Sie nun die prozessor-spezifische CMATH-Bibliothek gemäß folgender Tabelle hinzu:
Processor | 32-bit CMATH-Bibliothek | 64-bit CMATH-Bibliothek |
P4: volle FPU-Genauigkeit (rückwärts-kompatibel zu 486DX/Pentium) | CMVC4.LIB | ---- |
P8: aktuelle Prozessoren (Core2xxx, i3, i5, i7, AMDx64) | CMVC8.LIB | CMVC64_8.LIB |
Damit CMATH sowohl in Anwendungen mit MFC als auch ohne MFC verwenden werden kann, ruft es selbst nur direkt die Windows-API auf, nicht aber über den Umweg von MFC. Wenn Sie nun aber MFC verwenden (sei es als statische Bibliothek, sei es als DLL), bindet Visual C++ die benötigte Import-Bibliothek user32.lib standardmäßig nicht mit ein. Sie müssen dies daher explizit selbst tun: Die Zeile Projekt / Einstellungen / Linker / Kategorie: Allgemein / Objekt- und Bibliothek-Module muß den Eintrag user32.lib erhalten. Andernfalls würde der Linker den Fehler "error LNK2001: Nichtaufgeloestes externes Symbol __imp__MessageBoxA@??" melden.
Fortsetzung mit Kap. 1.5 Deklaration von OptiVec-Funktionen in C/C++
1.4.3 CMATH für GCC (GNU Compiler Collection)
Angenommen, Ihr CMATH-Verzeichnis sei C:\CMATH, müssen Sie
beim Compilieren mit GCC die Option -I C:\CMATH\INCLUDE angeben.
Sie müssen nicht nur eine, sondern zwei CMATH-Bibliotheken einschließen. Die erste (die "Basis-Bibliothek") enthält das Interface zwischen CMATH und den GCC-Laufzeitbibliotheken; sie ist spezifisch für die jeweils gewählten GCC-Konfiguration. Die zweite Bibliothek wiederum ist unabhängig von der Compiler-Konfiguration; durch sie entscheiden Sie über die Prozessor-Unterstützung.
Wählen Sie die Basis-Bibliothek aus der folgenden Tabelle:
Plattform | GCC-Thread-Modell | GCC-Exception-Modell | Passende CMATH Basis-Bibliothek |
Win64 | Windows-Threads | SEH | cmgcbase64ws.lib |
| Windows-Threads | Setjmp/Longjmp | cmgcbase64wj.lib |
| Posix-Threads | SEH | cmgcbase64ps.lib |
| Posix-Threads | Setjmp/Longjmp | cmgcbase64pj.lib |
Win32 | Windows-Threads | Dwarf | cmgcbase32wd.lib |
| Windows-Threads | Setjmp/Longjmp | cmgcbase32wj.lib |
| Posix-Threads | Dwarf | cmgcbase32pd.lib |
| Posix-Threads | Setjmp/Longjmp | cmgcbase32pj.lib |
Nun wählen Sie die zweite, Prozessor-spezifische CMATH-Bibliothek aus der nächsten Tabelle:
Processor | 32-bit CMATH-Bibliothek | 64-bit CMATH-Bibliothek |
P4: volle FPU-Genauigkeit (rückwärts-kompatibel zu 486DX/Pentium) | cmgc32_4.lib | ---- |
P8: aktuelle Prozessoren (Core2xxx, i3, i5, i7, AMDx64) | cmgc32_8.lib | cmgc64_8.lib |
Ein sehr wichtiger Punkt, den es bei der Arbeit mit GCC zu beachten gilt, ist, dass der Linker Symbole in den eingeschlossenen Bibliotheken "von links nach rechts" sucht. Da die Prozessor-spezifische Bibliothek auf die Basis-Bibliothek zugreift, muss die Prozessor-spezifische Bibliothek also zuerst genannt sein.
GCC ist der einzige unter den "großen" Compilern, der in 64-bit den aus 80-bit Fließkommazahlen bestehenden Datentyp long double bzw. extended unterstützt. (Die anderen Compiler benutzen in 64-bit long double / extended einfach als Synonym für double). Dies ist ein sehr wertvolles Feature von GCC, da die zusätzliche Genauigkeit und Reichweite gelegentlich eine bedeutende Vereinfachung darstellen können. CMATH unterstützt den Datentyp eComplex sowohl für 32-bit als auch für 64-bit-.
Eine Linux-Version befindet sich in Vorbereitung und wird in das Paket CMATH für GCC eingefügt, wenn sie zur Verfügung steht.
Fortsetzung mit Kap. 1.5 Deklaration von CMATH-Funktionen in C/C++
1.4.4 CMATH für LLVM CLang
Angenommen, Ihr CMATH-Verzeichnis sei C:\CMATH, müssen Sie beim Compilieren mit CLang die Option -I C:\CMATH\INCLUDE angeben.
Sie müssen nicht nur eine, sondern zwei CMATH-Bibliotheken einschließen. Die erste (die "Basis-Bibliothek") enthält das Interface zwischen CMATH und den CLang-Laufzeitbibliotheken. (Tatsächlich benutzt CLang großenteils die Laufzeitbibliothek von Visual C++ und ist "fast" kompatibel mit Visual C++. Diese Kompatibilität ist aber so weit nur "fast" gegeben, dass CMATH eine eigene Version für CLang benötigt).
Die CMATH-Basis-Bibliothek ist cmclbase64.lib für 64-bit und cmclbase32.lib für 32-bit.
Die zweite Bibliothek wiederum entscheidet über die Prozessor-Unterstützung.
Processor | 32-bit CMATH-Bibliothek | 64-bit CMATH-Bibliothek |
P4: volle FPU-Genauigkeit (rückwärts-kompatibel zu 486DX/Pentium) | cmcl32_4.lib | ---- |
P8: aktuelle Prozessoren (Core2xxx, i3, i5, i7, AMDx64) | cmcl32_8.lib | cmcl64_8.lib |
Eine Linux-Version befindet sich in Vorbereitung und wird in das Paket CMATH für LLVM CLang eingefügt, wenn sie zur Verfügung steht.
Fortsetzung mit Kap. 1.5 Deklaration von CMATH-Funktionen in C/C++
1.4.5 CMATH für Delphi
Die Auswahl zwischen den verschiedenen CMATH-Bibliotheken erfolgt durch die Auswahl des entsprechenden Unit-Suchpfades.
Shareware-Version: Die units (.DCU Dateien) befinden sich in den Verzeichnissen CMATH\LIB4 (32-bit) bzw. CMATH\Win64\LIB8 (64-bit).
Registrierte Vollversion: Die units (.DCU Dateien) für aktuelle Prozessoren finden Sie in CMATH\LIB8 (32-bit) bzw. CMATH\Win64\LIB8 (64-bit) und CMATH\Win64\LIB8D (64-bit Debug). Die Units für 32-bit Museumsstücke (bis hinab zu 486/Pentium) befinden sich in CMATH\LIB4 und CMATH\LIB4D (Debug).
Fortsetzung mit Kap. 1.5.2 Deklaration von CMATH-Funktionen in Pascal / Delphi
1.4.6 CMATH für Lazarus / FreePascal
Die units (.ppu Dateien) und Object-Dateien (*.o) befinden sich in dem Verzeichnis CMATH\LIB8. Dieses Verzeichnis ist in Lazarus in den Suchpfad "Other units" einzutragen.
1.5 Deklaration von CMATH-Funktionen
1.5.1 Deklaration von CMATH-Funktionen in C/C++
Deklarieren Sie den Gebrauch von CMATH-Funktionen durch die Direktive
#include <newcplx.h> (nur C++, nicht C) oder
#inlucde <cmath.h> (C oder C++), wie oben beschrieben.
Falls Sie MFC oder das uralte ObjectWindows (Borland C++) verwenden, muß <newcplx.h> bzw. <cmath.h> nach(!) den Include-Dateien von MFC bzw. OWL angegeben werden.
1.5.2 Deklaration von CMATH-Funktionen in Pascal / Delphi
Nehmen Sie die CMATH unit mit der Anweisung "uses CMATH" in Ihr Programm auf.
1.6 Beispiel-Programme
Schauen Sie sie die Beispielprogramme an, indem Sie das für Ihren Compiler geeignete Projekt öffnen:
- Embarcadero / Borland C++:
12, 11.x, 10.x, XE3 oder höher: Öffnen Sie die Projektgrouppe CDEMO.groupproj (64-bit und klassischer Borland-Compiler 32-bit) oder CDemo_BCC32C.groupproj (Clang-unterstützter Compiler BCC32C; nur 32-bit).
Alternativ (für ältere Versionen: immer) öffnen Sie die einzelnen Projekte:
CDEMO.cbproj and MANDEL.cbproj sind Projekte für RAD Studio 12, 11.x, 10.x, XE-Serie, 2010, 2009
CDEMO.bdsproj and MANDEL.bdsproj sind für BDS 2006 und 2007
CDEMOB6.BPR and MANDELB6.BPR sind für BC++ Builder 6+.
- Microsoft Visual C++:
Öffnen Sie die Projektmappe CDEMO_vs20??.sln bzw. CDEMO64_vs20??.sln für Ihre VS Version.
- GCC:
Das Make-File "makefile." enthält die beiden Targets CDemo und Mandel. Es ist füt die Verwendung mit GNU-Make gedacht. Bevor Sie make aufrufen, sollten Sie im makefile den Pfad zum GCC-Compiler korrekt setzen.
- LLVM CLang:
Das Make-File "makefile." enthält das Target CDemo. Es ist füt die Verwendung mit GNU-Make gedacht. Bevor Sie make aufrufen, sollten Sie im makefile den Pfad zum CLang-Compiler korrekt setzen.
Prinzipiell sollte CLang in der Lage sein, alle Windows DLL's zu verwenden. Dies scheint aber mit den derzeitigen Versionen im Falle von GDI32.DLL nicht der Fall zu sein. Da das für die anderen Compiler vorhandene Mandelbrodt-Beispielprogramm auf Graphik-Ausgabe angewiesen ist, ist es leider für CLang nicht erhältlich, solange dieser CLang-Fehler nicht behoben ist.
- Delphi:
Öffnen Sie CDEMO.dproj oder MANDEL.dproj
- Lazarus:
Testen Sie CDEMO.lpi und MANDEL.lpi.
Nach diesen Vorbereitungen stehen Ihnen alle CMATH-Funktionen für Ihre Programme zur Verfügung.
Sollten Sie CMATH wieder von Ihrem Computer entfernen wollen, führen Sie bitte UNINSTAL.EXE aus oder löschen das Verzeichnis CMATH mit allen Unterverzeichnissen.
Zurück zum Inhaltsverzeichnis
2. Übersicht über die CMATH-Funktionen
In der folgenden Besprechung wird h&aum l;ufig nur die fComplex- oder fPolar-Version einer Funktion explizit aufgeführt. Die Versionen für dComplex / dPolar und eComplex / ePolarsind exakt analog.
Alle Funktionen für die Sprachen C und Pascal/Delphi haben ein Präfix, das den Datentyp angibt, mit dem sie arbeiten:
"cf_" oder "pf_" steht für einfache Genauigkeit (Argumente und Rückgabewerte vom Typ fComplex oder fPolar, gegebenenfalls zusammen mit float bwz. Single).
"cd_" oder "pd_" ststeht für doppelte Genauigkeit (Argumente und Rückgabewerte vom Typ dComplex oder dPolar, evtl. zusammen mit double).
"ce_" und "pe_" bezeichnen Funktionen in extended-Genauigkeit.
In C++ und Delphi sind Synonyme für alle diese Funktionen definiert. Diese Synonyme haben kein Präfix, da die Typeninformation implizit vom Compiler verarbeitet wird. Diese überladenen Funktionsnamen sind weitestgehend identisch mit den üblicherweise in komplexen Klassenbibliothek verwendeten (sofern die jeweilige Funktion auch dort existiert). Eine wichtige Ausnahme stellt die Member-Funktion polar dar, die durch magargtoc ersetzt werden mußte, da der Begriff "polar" nun für die Klassen in Polarkoordinaten reserviert ist.
Nur C++: Um die typenspezifischen C-Funktionsnamen in Ihren C++-Modulen verwenden, schließen Sie
<cmath.h> anstelle von
<newcplx.h> ein.
2.1. Initialisierung komplexer Zahlen
Die komplexen Klassen werden in der folgenden Beschreibung stets mit ihren Kurznahmen fComplex, fPolar usw. bezeichnet. In C++ können Sie aber immer stattdessen die Template-Nomenklatur verwenden und beispielsweise "complex<float>" schreiben, wo hier "fComplex" angegeben ist, und so weiter für alle übrigen komplexen Typen und Klassen.
Komplexe Zahlen werden initialisiert, indem ihrem Real- und Imaginärteil bzw. ihrem Mag- und Arg-Teil die gewünschten Werte zugewiesen werden, z.B.:
z.Re = 3.0; z.Im = 5.7;
p.Mag = 8.8; p.Arg = 3.14;
(Für Pascal/Delphi muß der Zuweisungs-Operator natürlich ":=" geschrieben werden).
Alternativ kann die Initialisierung auch mittels der Funktionen fcplx oder fpolr durchgeführt werden:
C/C++:
z = fcplx( 3.0, 5.7 );
p = fpolr( 4.0, 0.7 );
Pascal/Delphi:
fcplx( z, 3.0, 5.7 );
fpolr( p, 3.0, 5.7 );
Für doppelt-genaue komplexe Zahlen gebrauche man dcplx und dpolr, für extended-genaue ecplx und epolr.
2.2. Datentyp-Umwandlung
Umwandlungen zwischen den verschiedenen komplexen Datentypen werden durch die folgenden Funktionen bewerkstelligt:
cftocd, cdtocf, cftoce, cetocf, cdtoce, cetocd | Aufwärts- oder Abwärts-Umwandlung innerhalb der cartesisch-komplexen Typen |
pftopd, pdtopf, pftope, petopf, pdtope, petopd | Aufwärts- oder Abwärts-Umwandlung innerhalb der polar-komplexen Typen |
cftopf, cftopd, cftope,
cdtopf, cdtopd, cdtope,
cetopf, cetopd, cetope | Umwandlung von cartesischen in polar-komplexe Typen |
pftocf, pftocd, pftoce,
pdtocf, pdtocd, pdtoce,
petocf, petocd, petoce | Umwandlung von polaren in cartesisch-komplexe Typen |
OVERFLOW-Fehler bei den Abwärts-Umwandlungen werden stillschweigend behoben: Die Programmausführung wird mit dem größtmöglichen vorzeichenrichtigen Wert fortgesetzt.
nur C++: |
Für C++-Module existieren überladene Konstruktoren als Alternative zu den obengenannten Funktionen:
Grundformen:
fComplex fComplex( float RePart, float ImPart=0 );
fComplex fComplex( dComplex );
fComplex fComplex( eComplex );
fPolar fPolar( float MagPart, float ArgPart=0 );
fPolar fPolar( dPolar );
fPolar fPolar( ePolar );
Umwandlungen cartesisch <--> polar:
fComplex fComplex( fPolar );
fComplex fComplex( dPolar );
fComplex fComplex( ePolar );
fPolar fPolar( fComplex );
fPolar fPolar( dComplex );
fPolar fPolar( eComplex );
Ähnlich wie die Konstruktoren fComplex() und fPolar() existieren auch dComplex(), dPolar(), eComplex und ePolar() in überladenen Versionen, die dieselben Aufgaben für die Klassen dComplex, dPolar, eComplex und ePolar übernehmen. Wie oben für die C/Pascal/Delphi-Versionen beschrieben, werden OVERFLOW-Fehler bei den Abwärtsumwandlungen abgefangen und stillschweigend behoben (ohne Aufruf von _matherr).
|
Ein besonderer Konstruktor für polar-komplexe Zahlen ist
fPolar pf_principal( fPolar __p );
und (nur für C++) seine überladene Form mit zwei getrennten reellen Eingabezahlen
fPolar principal( float Mag, float Arg );
Diese Funktionen reduzieren den Eingabewert von Arg auf den Bereich -p < Arg <= +p. Man erinnere sich, daß jede komplexe Zahl unendlich viele Darstellungen in Polarkoordinaten besitzt, deren Winkel sich um ganzzahlige Vielfache von 2 p unterscheiden. Die Darstellung mit -p < Arg <= +p wird der Hauptwert (engl. principal value) genannt.
Man beachte, daß diese Funktionen neben der polaren Quadratwurzel-Funktion pf_sqrt die einzigen Funktionen in Polarkoordinaten sind, die die Ausgabe auf den Hauptwert reduzieren. Alle übrigen akzeptieren und retournieren Argumente, deren Winkel außerhalb dieses Bereiches liegen dürfen.
Die Umwandlung zwischen cartesischem und polaren Format verläuft über transzendente Funktionen und ist daher recht zeitaufwendig. Gelegentlich wird in Lehrbüchern herausgestellt, daß Multiplikationen schneller in Polarkoordinaten durchgeführt werden können, während Additionen wesentlich schneller in cartesischen Koordinaten berechnet werden können. So wahr dies ist, darf man nicht den Schluss ziehen, durch häufiges Wandeln von der einen in die andere Darstellung könne man Zeit gewinnen, da diese Unterschiede viel kleiner als der zur Umwandlung nötige Rechenaufwand sind. Daher ist zu empfehlen, im allgemeinen dem cartesischen Format treu zu bleiben. Nur in den folgenden Fällen hat die Umwandlung wirklich Sinn:
- Es liegen ausschließlich Multiplikationen, Divisionen und von diesen abgeleitete mathematische Funktionen vor (wie square, sqrt, ipow). Dann sollten Sie in Polarkoordinaten rechnen.
- Die komplexe Exponentialfunktion ist zu berechnen. In diesem Fall bringt cf_exptop Sie auf "natürliche" Weise von cartesischen in Polarkoordinaten.
- Sie arbeiten in Polarkoordinaten und müssen den Logarithmus ziehen. In diesem Fall stellt pf_logtoc (oder ähnlich pf_log2toc, pf_log10toc) einen natürlichen Übergang in cartesische Koordinaten dar.
Zurück zum Inhaltsverzeichnis
2.3 Komplexe Grundfunktionen
Folgende komplexe Grundfunktionen sind in CMATH definiert:
(Die doppelt- und extended-genauen Versionen sind exakt analog zu der cf_ / pf_-Version.)
Zurück zum Inhaltsverzeichnis
2.4 Arithmetische Operationen
Nur C++ und Delphi ab Delphi 2006: | Der vollständige Satz arithmetischer Operatoren ist für alle komplexen Klassen bzw. Datentypen definiert. Diese Operatoren existieren auch für "gemischte" Argumente, wo ein Argument komplex, das andere reell ist, oder wo die Argumente von unterschiedlicher Fließkomma-Genauigkeit sind.
C++, cartesisch-komplexe Klassen:
+ - * / += -= *= /= == !=
C++, polar-komplexe Klassen:
* / *= /= == !=
Delphi 2006 oder höher, cartesisch-komplexe Datentypen:
+ - * / = <>
Delphi 2006+, polar-komplexe Datentypen:
* / = <>
|
Nur Delphi vor v2006: | Anstelle der für die neueren Delphi-Versionen definierten Operatoren können hier die folgenden Funktionen aufgerufen werden:
add sub mul divide
Sie sind jeweils für zwei komplexe oder für ein komplexes und ein reelles Argument definiert. |
Da nur die Sprache C++, nicht aber das klassische C oder frühere Versionen von Pascal/Delphi das Überladen arithmetischer Operatoren erlaubt, sind die arithmetischen Operationen komplexer Zahlen zusätzlich als Funktionen implementiert, die sowohl von C/Pascal/Delphi- als auch von C++-Modulen aus aufgerufen werden können:
Cartesisch | Polar |
|
cf_add | N.A. |
Addition zweier komplexer Zahlen |
cf_addRe | N.A. |
Addition einer komplexer und einer reellen Zahl |
cf_sub | N.A. |
Subtraktion zweier komplexer Zahlen (zweiter Operand wird vom ersten abgezogen) |
cf_subRe | N.A. |
Subtraktion einer reellen von einer komplexen Zahl |
cf_subrRe | N.A. |
Subtraktion einer komplexen von einer reellen Zahl |
cf_mul | pf_mul |
Multiplikation zweier komplexer Zahlen |
cf_mulRe | pf_mulRe |
Multiplikation einer komplexen mit einer reellen Zahl |
cf_mulconj | pf_mulconj |
Multiplikation einer komplexen Zahl mit der komplex-konjugierten Form einer anderen |
cf_div | pf_div |
Division zweier komplexer Zahlen (erster Operand wird durch den zweiten Operanden geteilt) |
cf_divRe | pf_divRe |
Division einer komplexen durch eine reelle Zahl |
cf_divrRe | pf_divrRe |
Division einer reellen durch eine komplexe Zahl |
(ähnlich die doppelt- und extended-genauen Versionen)
Der Zuweisungs-Operator "=" bzw. ":=" ist der einzige auch in klassischem C und in Pascal/Delphi für komplexe Zahlen definierte Operator.
Zurück zum Inhaltsverzeichnis
2.5 Mathematische Funktionen
Alle üblicherweise in den komplexen Klassenbibliotheken zu findenden mathematischen Funktionen und noch einige zusätzliche sind in CMATH enthalten:
Wie oben erwähnt, bieten Exponential- und Logarithmus-Funktionen einen natürlichen Übergang zwischen cartesischen und Polarkoordinaten. Während die Funktionen exp und log fComplex sowohl als Eingabe- als auch als Ausgabewert verlangen, übernimmt cf_exptop einen fComplex-Eingabewert und gibt fPolar zurück. In umgekehrter Richtung übernimmt pf_logtoc einen fPolar-Wert und gibt fComplex zurück.
Zurück zum Inhaltsverzeichnis
3. Fehlerbehandlung
3.1 Allgemeines zur Fehlerbehandlung komplexer Funktionen
Die Fehlerbehandlung komplexer Funktionen folgt derjenigen reeller Funktionen und Operatoren. Das bedeutet, daß bei den arithmetischen Operationen zwar durch entsprechende Auslegung der Algorithmen (insbesondere bei der Division) die Gefahr von Fehlern durch Überlauf von Zwischenergebnissen eliminiert wird, überlaufende Endergebnisse aber nicht abgefangen werden.
Überlauf-Fehler oder Divisionen durch Null führen daher bei den arithmetischen Funktionen zum Programm-Abbruch.
Anders sieht es bei den mathematischen Funktionen und bei den Datentyp-Umwandlungen aus: Alle Überlauf- oder Divisionsfehler werden sorgfältig abgefangen. Alle hierbei eventuell ausgegebenen Fehlermeldungen nennen dabei den C/Pascal-Namen (anstelle der überladenen C++/Delphi-Funktion) mit dem Präfix, das den Datentyp angibt.
Falls Sie CMATH als Teil von OptiVec erhalten haben, sollten Sie Kap. 5 von HANDBUCH.HTM anstelle des vorliegenden Kapitels lesen.
Überlauf-, Singularitäts- und Genauigkeits-Verlust-Fehler werden durch Setzen des f¨r die jeweilige Funktion passenden Standardwertes abgefangen. Bereichsfehler (DOMAIN) führen zu dem Ergebnis NAN (not-a-number).
Nur für Debug-Bibliotheken: Wie oben bereits erwähnt, kann durch Aufruf von V_setFPErrorHandling( int fpHandlingMode ); eingestellt werden, welche Fehlerarten zu einer Meldung und welche ggf. zu einem Programm-Abbruch führen. Die vorhandenen Optionen werden durch vordefinierte Konstanten fperrXXX gesetzt:
Konstante | Bedeutung |
fperrIgnore | Sämtliche Fließkommafehler stillschweigend behandeln |
fperrNoteDOMAIN | Bereichsfehler melden |
fperrAbortDOMAIN | Meldung und Programmabbruch bei Bereichsfehlern |
fperrNoteSING | Singularitäten (meist Divisionen durch 0) melden |
fperrAbortSING | Meldung und Programmabbruch bei Singularitäten |
fperrNoteOVERFLOW | Überlauf melden |
fperrAbortOVERFLOW | Meldung und Programmabbruch bei Überlauf |
fperrNoteTLOSS | Totalen Genauigkeitsverlust melden |
fperrAbortTLOSS | Meldung und Programmabbruch bei Totalem Genauigkeitsverlust |
fperrDefault | Standardeinstellung = fperrAbortDOMAIN + fperrNoteSING + fperrNoteOVERFLOW |
Beim Aufruf von V_setFPErrorHandling sollten diese Konstanten addiert oder mit dem OR-Operator verknüpft werden. Man beachte, dass dies nur die Behandlung von Fehlern beeinflußt, die innerhalb von OptiVec-Funktionen auftreten. Die zu C/C++ oder Pascal/Delphi gehörenden Standard-Funktionen bleiben hiervon unberührt.
Zurück zum Inhaltsverzeichnis
3.1.2 Pascal/Delphi-Spezifika
Wie CMATH Fließkomma-Fehler in den mathematischen komplexen Funktionen behandeln soll, kann durch Aufruf von V_setFPErrorHandling definiert werden. Eine Anzahl von vordefinierten Konstanten fperrXXX steht für die Konstruktion des gewünschten Fehlerbehandlungs-Modus zur Verfügung:
Konstante | Wert | Bedeutung |
fperrIgnore | 0 | alle Fließkomma-Fehler ignorieren: Ergebnis stillschweigend auf Standardwert setzen, keine Fehlermeldung ausgeben, Programmausführung fortsetzen |
fperrNoteDOMAIN | $0001 | Fehlermeldung für DOMAIN-Fehler ausgeben |
fperrNoteSING | $0002 | Fehlermeldung für SING-Fehler ausgeben |
fperrNoteOVERFLOW | $0003 | Fehlermeldung für OVERFLOW-Fehler ausgeben |
fperrNoteTLOSS | $0004 | Fehlermeldung für TLOSS-Fehler ausgeben |
fperrAbortDOMAIN | $0101 | Programm im Falle von DOMAIN-Fehler abbrechen |
fperrAbortSING | $0202 | Programm im Falle von SING-Fehler abbrechen |
fperrAbortOVERFLOW | $0303 | Programm im Falle von OVERFLOW-Fehler abbrechen |
fperrAbortTLOSS | $0404 | Programm im Falle von TLOSS-Fehler abbrechen |
fperrDefaultHandling | $0107 | Entspricht fperrAbortDOMAIN + fperrNoteSING + fperrNoteOVERFLOW |
Beispiel:
V_setFPErrorHandling( fperrAbortDOMAIN + fperrAbortSING + fperrAbortOVERFLOW + fperrNoteTLOSS );
In diesem Beispiel wird das Programm mit einer Fehlermeldung abgebrochen, falls einer der schwereren Fehler, DOMAIN oder SING, auftritt. Im Falle der weniger schweren OVERFLOW- und TLOSS-Fehler wird zwar eine Meldung ausgegeben, aber die Programmausführung mit den für die jeweilige Funktion vorgegebenen Standardwerten fortgesetzt. Falls mehrere Fehler desselben Fehlertyps nacheinander innerhalb ein- und derselben Funktion auftreten, wird nur eine einzige Meldung ausgegeben. Die folgenden Fehler werden stillschweigend behoben.
Zurück zum Inhaltsverzeichnis
3.2 Fortgeschrittene Fehlerbehandlung: Meldungen in eine Datei schreiben
Allgemein 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:
V_setErrorEventFile( "MyLogFil.TXT", 0 ); /* C/C++ */
V_setErrorEventFile( 'MyLogFil.TXT', FALSE ); (* Pascal/Delphi *)
Hier werden alle folgenden Fehlermeldungen nur in das Log-File MyLogFil.TXT geschrieben, aber keine auf dem Bildschirm angezeigt. Die Standardeinstellung, d.h. Meldungsausgabe auf dem Bildschirm (unter Windows in MessageBoxen) wird durch V_closeErrorEventFile wiederhergestellt. Diese letztere Funktion hat keine Argumente und gibt auch nichts zurück.
Man beachte, dass die beschriebene Umleitung von Fehlermeldungen nur für Fehler gilt, die innerhalb von CMATH- bzw. OptiVec-Funktionen auftreten. Es steht dem Nutzer aber frei, eigene Fehlermeldungen mit der Funktion V_printErrorMsg( const char *MyMessage ) auszugeben.
Einzelne Konfigurationen der von CMATH unterstützten Compiler erlauben nicht den vollen Umfang der oben angegebenen Optionen. Bei manchen fehlt entweder die Ausgabe in eine Message-Box oder die Ausgabe auf den Konsolen-Bildschirm. In diesen Fällen wird ggf. eine Fehlermeldung ausgegeben und die Ausgabe auf die jeweils andere Option umgeleitet.
Zurück zum Inhaltsverzeichnis
4. Syntax-Referenz
Außer bei den Datentyp-Umwandlungen ist in der folgenden Zusammenstellung nur die Syntax für float / fComplex / fPolar-Genauigkeit angegeben. Die Syntax der entsprechenden doppelt- oder extended-genauen Funktionen ist exakt analog.
Falls Sie die "klassische" class complex verwenden, ist die Syntax für sie ebenfalls analog. Man ersetze lediglich float durch double und fComplex durch complex. Wenn es nur diesen einzigen komplexen Typ gibt, sind die Typenumwandlungs-Operatoren und -Funktionen natürlich ebenso wenig definiert wie sämtliche polar-komplexen Funktionen.
Zurück zum Inhaltsverzeichnis
4.1 Funktionsdeklarationen für C und Pascal/Delphi
Für die Funktionen der Genauigkeitsstufen double / dComplex / dPolar und extended / eComplex / ePolar lauten die Präfixe cd_, pd_, ce_ bwz. pe_. Die Dopplung von Delphi-functions (Resultat wird zurückgegeben) und procedures (Resultat wird in Variabler gespeichert) erklärt sich aus historischen Gründen, nämlich dass frühe Delphi-Versionen keine complexen Rückgabewerte erlaubten.
float cf_abs( fComplex __z );
function cf_abs( zx:fComplex ): Single;
float pf_abs( fPolar __p );
function pf_abs( px:fPolar ): Single;
fComplex cf_acos( fComplex __z );
function cf_acos( zx:fComplex ): fComplex;
procedure cf_acos( var zy:fComplex; zx:fComplex );
fComplex cf_add( fComplex __x, fComplex __y );
function cf_add( zx, zy:fComplex ): fComplex;
procedure cf_add( var zz:fComplex; zx, zy:fComplex );
fComplex cf_addRe( fComplex __x, float __yRe );
function cf_addRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_addRe( var zz:fComplex; zx:fComplex; yRe:Single );
float cf_arg( fComplex __z );
function cf_arg( zx:fComplex ): Single;
float pf_arg( fPolar __z );
function pf_arg( px:fPolar ): Single;
fComplex cf_asin( fComplex __z );
function cf_asin( zx:fComplex ): fComplex;
procedure cf_asin( var zy:fComplex; zx:fComplex );
fComplex cf_atan( fComplex __z );
function cf_atan( zx:fComplex ): fComplex;
procedure cf_atan( var zy:fComplex; zx:fComplex );
eComplex cdtoce( dComplex __zd );
function cdtoce( zx:dComplex ): eComplex;
procedure cdtoce( var zy:eComplex; zx:dComplex );
fComplex cdtocf( dComplex __zd );
function cdtocf( zx:dComplex ): fComplex;
procedure cdtocf( var zy:fComplex; zx:dComplex );
dPolar cdtopd( dComplex __zd );
function cdtopd( zx:dComplex ): dPolar;
procedure cdtopd( var py:dPolar; zx:dComplex );
ePolar cdtope( dComplex __zd );
function cdtope( zx:dComplex ): ePolar;
procedure cdtope( var py:ePolar; zx:dComplex );
fPolar cdtopf( dComplex __zd );
function cdtopf( zx:dComplex ): fPolar;
procedure cdtopf( var py:fPolar; zx:dComplex );
dComplex cetocd( eComplex __ze );
function cetocd( zx:eComplex ): dComplex;
procedure cetocd( var zy:dComplex; zx:eComplex );
fComplex cetocf( eComplex __ze );
function cetocf( zx:eComplex ): fComplex;
procedure cetocf( var zy:fComplex; zx:eComplex );
dPolar cetopd( eComplex __ze );
function cetopd( zx:eComplex ): dPolar;
procedure cetopd( var py:dPolar; zx:eComplex );
ePolar cetope( eComplex __ze );
function cetope( zx:eComplex ): ePolar;
procedure cetope( var py:ePolar; zx:eComplex );
fPolar cetopf( eComplex __ze );
function cetopf( zx:eComplex ): fPolar;
procedure cetopf( var py:fPolar; zx:eComplex );
dComplex cftocd( fComplex __zf );
function cftocd( zx:fComplex ): dComplex;
procedure cftocd( var zy:dComplex; zx:fComplex );
eComplex cftoce( fComplex __zf );
function cftoce( zx:fComplex ): eComplex;
procedure cftoce( var zy:eComplex; zx:fComplex );
dPolar cftopd( fComplex __zf );
function cftopd( zx:fComplex ): dPolar;
procedure cftopd( var py:dPolar; zx:fComplex );
ePolar cftope( fComplex __zf );
function cftope( zx:fComplex ): ePolar;
procedure cftope( var py:ePolar; zx:fComplex );
fPolar cftopf( fComplex __zf );
function cftopf( zx:fComplex ): fPolar;
procedure cftopf( var py:fPolar; zx:fComplex );
fComplex cf_conj( fComplex __z );
function cf_conj( zx:fComplex ): fComplex;
procedure cf_conj( var zy:fComplex; zx:fComplex );
fPolar pf_conj( fPolar __p );
function pf_conj( px:fPolar ): fPolar;
procedure pf_conj( var py:fPolar; px:fPolar );
fComplex cf_cos( fComplex __z );
function cf_cos( zx:fComplex ): fComplex;
procedure cf_cos( var zy:fComplex; zx:fComplex );
fComplex cf_cosh( fComplex __z );
function cf_cosh( zx:fComplex ): fComplex;
procedure cf_cosh( var zy:fComplex; zx:fComplex );
fComplex cf_cubic( fComplex __z );
function cf_cubic( zx:fComplex ): fComplex;
procedure cf_cubic( var zy:fComplex; zx:fComplex );
fPolar pf_cubic( fPolar __p );
function pf_cubic( px:fPolar ): fPolar;
procedure pf_cubic( var py:fPolar; px:fPolar );
fComplex cf_div( fComplex __x, fComplex __y );
function cf_div( zx, zy:fComplex ): fComplex;
procedure cf_div( var zz:fComplex; zx, zy:fComplex );
fPolar pf_div( fPolar __x, fPolar __y );
function pf_div( px, py:fPolar ): fPolar;
procedure pf_div( var pz:fPolar; px, py:fPolar );
fComplex cf_divRe( fComplex __x, float __yRe ); /* x / yRe */
function cf_divRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_divRe( var zz:fComplex; zx:fComplex; yRe:Single );
fPolar pf_divRe( fPolar __x, float __yRe ); /* x / yRe */
function pf_divRe( px:fPolar; yRe:Single ): fPolar;
procedure pf_divRe( var pz:fPolar; px:fPolar; yRe:Single );
fComplex cf_divrRe( fComplex __x, float __yRe ); /* yRe / x */
function cf_divrRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_divrRe( var zz:fComplex; zx:fComplex; yRe:Single );
fPolar pf_divrRe( fPolar __x, float __yRe ); /* yRe / x */
function pf_divrRe( px:fPolar; yRe:Single ): fPolar;
procedure pf_divrRe( var pz:fPolar; px:fPolar; yRe:Single );
fComplex cf_exp( fComplex __z );
function cf_exp( zx:fComplex ): fComplex;
procedure cf_exp( var zy:fComplex; zx:fComplex );
fPolar cf_exptop( fComplex __z );
function cf_exptop( zx:fComplex ): fPolar;
procedure cf_exptop( var py:fPolar; zx:fComplex );
fComplex fcplx( float __ReVal, float __ImVal);
function fcplx( xRe, xIm:Single ): fComplex;
procedure fcplx( var zy:fComplex; xRe, xIm:Single );
fPolar fpolr( float __MagVal, float __ArgVal);
function fpolr( xMag, xArg:Single ): fPolar;
procedure fpolr( var py:fPolar; xMag, xArg:Single );
float cf_imag( fComplex __z );
function cf_imag( zx:fComplex ): Single;
float pf_imag( fPolar __p );
function pf_imag( px:fPolar ): Single;
fComplex cf_inv( fComplex __z );
function cf_inv( zx:fComplex ): fComplex;
procedure cf_inv( var zy:fComplex; zx:fComplex );
fPolar pf_inv( fPolar __p );
function pf_inv( px:fPolar ): fPolar;
procedure pf_inv( var py:fPolar; zx:fComplex );
fComplex cf_ipow( fComplex __z, int __exponent );
function cf_ipow( zx:fComplex; exponent:Integer ): fComplex;
procedure cf_ipow( var zy:fComplex; zx:fComplex; exponent:Integer );
fPolar pf_ipow( fPolar __p, int __exponent );
function pf_ipow( px:fPolar; exponent:Integer ): fPolar;
procedure pf_ipow( var py:fPolar; px:fPolar; exponent:Integer );
fComplex cf_ln( fComplex __z );
function cf_ln( zx:fComplex ): fComplex;
procedure cf_ln( var zy:fComplex; zx:fComplex );
fComplex pf_lntoc( fPolar __p );
function pf_lntoc( px:fPolar ): fComplex;
procedure pf_lntoc( var zy:fComplex; px:fPolar );
fComplex cf_log( fComplex __z );
function cf_log( zx:fComplex ): fComplex;
procedure cf_log( var zy:fComplex; zx:fComplex );
fComplex pf_logtoc( fPolar __p );
function pf_logtoc( px:fPolar ): fComplex;
procedure pf_logtoc( var zy:fComplex; zx:fPolar );
fComplex cf_log2( fComplex __z );
function cf_log2( zx:fComplex ): fComplex;
procedure cf_log2( var zy:fComplex; zx:fComplex );
fComplex pf_log2toc( fPolar __p );
function pf_log2toc( px:fPolar ): fComplex;
procedure pf_log2toc( var zy:fComplex; px:fPolar );
fComplex cf_log10( fComplex __z );
function cf_log10( zx:fComplex ): fComplex;
procedure cf_log10( var zy:fComplex; zx:fComplex );
fComplex pf_log10toc( fPolar __p );
function pf_log10toc( px:fPolar ): fComplex;
procedure pf_log10toc( var zy:fComplex; px:fPolar );
fComplex cf_magargtoc( float __mag, float __angle );
function cf_magargtoc( mag, angle:Single ): fComplex;
procedure cf_magargtoc( var zy:fComplex; mag, angle:Single );
fComplex cf_mul( fComplex __x, fComplex __y );
function cf_mul( zx, zy:fComplex ): fComplex;
procedure cf_mul( var zz:fComplex; zx, zy:fComplex );
fPolar pf_mul( fPolar __x, fPolar __y );
function pf_mul( px, py:fPolar ): fPolar;
procedure pf_mul( var zz:fPolar; zx, zy:fPolar );
fComplex cf_mulconj( fComplex __x, fComplex __y );
function cf_mulconj( zx, zy:fComplex ): fComplex;
procedure cf_mulconj( var zz:fComplex; zx, zy:fComplex );
fPolar pf_mulconj( fPolar __x, fPolar __y );
function pf_mulconj( px, py:fPolar ): fPolar;
procedure pf_mulconj( var zz:fPolar; zx, zy:fPolar );
fComplex cf_mulRe( fComplex __x, float __yRe );
function cf_mulRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_mulRe( var zz:fComplex; zx:fComplex; yRe:Single );
fPolar pf_mulRe( fPolar __x, float __yRe );
function pf_mulRe( px:fPolar; yRe:Single ): fPolar;
procedure pf_mulRe( var pz:fPolar; px:fPolar; yRe:Single );
fComplex cf_neg( fComplex __z );
function cf_neg( zx:fComplex ): fComplex;
procedure cf_neg( var zy:fComplex; zx:fComplex );
fPolar pf_neg( fPolar __p );
function pf_neg( px:fPolar ): fPolar;
procedure pf_neg( var py:fPolar; px:fPolar );
float cf_norm( fComplex __z );
function cf_norm( zx:fComplex ): Single;
float pf_norm( fPolar __p );
function pf_norm( px:fPolar ): Single;
dComplex pdtocd( dPolar __pd );
function pdtocd( px:dPolar ): dComplex;
procedure pdtocd( var zy:dComplex; px:dPolar );
eComplex pdtoce( dPolar __pd );
function pdtoce( px:dPolar ): eComplex;
procedure pdtoce( var zy:eComplex; px:dPolar );
fComplex pdtocf( dPolar __pd );
function pdtocf( px:dPolar ): fComplex;
procedure pdtocf( var zy:fComplex; px:dPolar );
ePolar pdtope( dPolar __pd );
function pdtope( px:dPolar ): ePolar;
procedure pdtope( var py:ePolar; px:dPolar );
fPolar pdtopf( dPolar __pd );
function pdtopf( px:dPolar ): fPolar;
procedure pdtopf( var py:fPolar; px:dPolar );
dComplex petocd( ePolar __pe );
function petocd( px:ePolar ): dComplex;
procedure petocd( var zy:dComplex; px:ePolar );
eComplex petoce( ePolar __pe );
function petoce( px:ePolar ): eComplex;
procedure petoce( var zy:eComplex; px:ePolar );
fComplex petocf( ePolar __pe );
function petocf( px:ePolar ): fComplex;
procedure petocf( var zy:fComplex; px:ePolar );
dPolar petopd( ePolar __pe );
function petopd( px:ePolar ): dPolar;
procedure petopd( var py:dPolar; px:ePolar );
fPolar petopf( ePolar __pe );
function petopf( px:ePolar ): fPolar;
procedure petopf( var zy:fPolar; zx:ePolar );
dComplex pftocd( fPolar __pf );
function pftocd( px:fPolar ): dComplex;
procedure pftocd( var zy:dComplex; px:fPolar );
eComplex pftoce( fPolar __pf );
function pftoce( px:fPolar ): eComplex;
procedure pftoce( var zy:eComplex; px:fPolar );
fComplex pftocf( fPolar __pf );
function pftocf( px:fPolar ): fComplex;
procedure pftocf( var zy:fComplex; px:fPolar );
dPolar pftopd( fPolar __pf );
function pftopd( px:fPolar ): dPolar;
procedure pftopd( var zy:dPolar; zx:fPolar );
ePolar pftope( fPolar __pf );
function pftope( px:fPolar ): ePolar;
procedure pftope( var zy:ePolar; zx:fPolar );
fComplex cf_polar( float mag, float arg ); /* same as cf_magargtoc */
function cf_polar( mag, arg:Single ): fComplex;
procedure cf_polar( var zy:fComplex; mag, arg:Single );
fComplex cf_pow( fComplex __base, fComplex __exponent );
function cf_pow( zx:fComplex; exponent:Integer ): fComplex;
procedure cf_pow( var zy:fComplex; zx:fComplex; exponent:Integer );
fComplex cf_powReBase( float __base, fComplex __exponent );
function cf_powReBase( base:Single; exponent:fComplex ): fComplex;
procedure cf_powReBase( var zy:fComplex; base:Single; exponent:fComplex );
fComplex cf_powReExpo( fComplex __base, float __exponent );
function cf_powReExpo( zx:fComplex; exponent:Single ): fComplex;
procedure cf_powReExpo( var zy:fComplex; zx:fComplex; exponent:Single );
fPolar pf_powReExpo( fPolar __base, float __exponent );
function pf_powReExpo( px:fPolar; exponent:Single ): fPolar;
procedure pf_powReExpo( var py:fPolar; px:fPolar; exponent:Single );
fComplex cf_quartic( fComplex __z );
function cf_quartic( zx:fComplex ): fComplex;
procedure cf_quartic( var zy:fComplex; zx:fComplex );
fPolar pf_quartic( fPolar __p );
function pf_quartic( px:fPolar ): fPolar;
procedure pf_quartic( var py:fPolar; zx:fPolar );
float cf_real( fComplex __z );
function cf_real( zx:fComplex ): Single;
float pf_real( fPolar __p );
function pf_real( px:fPolar ): Single;
fComplex cf_sin( fComplex __z );
function cf_sin( zx:fComplex ): fComplex;
procedure cf_sin( var zy:fComplex; zx:fComplex );
fComplex cf_sinh( fComplex __z );
function cf_sinh( zx:fComplex ): fComplex;
procedure cf_sinh( var zy:fComplex; zx:fComplex );
fComplex cf_square( fComplex __z );
function cf_square( zx:fComplex ): fComplex;
procedure cf_square( var zy:fComplex; zx:fComplex );
fPolar pf_square( fPolar __p );
function pf_square( px:fPolar ): fPolar;
procedure pf_square( var py:fPolar; zx:fPolar );
fComplex cf_sqrt( fComplex __z );
function cf_sqrt( zx:fComplex ): fComplex;
procedure cf_sqrt( var zy:fComplex; zx:fComplex );
fPolar pf_sqrt( fPolar __p );
function pf_sqrt( px:fPolar ): fPolar;
procedure pf_sqrt( var py:fPolar; px:fPolar );
fComplex cf_sub( fComplex __x, fComplex __y );
function cf_sub( zx, zy:fComplex ): fComplex;
procedure cf_sub( var zz:fComplex; zx, zy:fComplex );
fComplex cf_subRe( fComplex __x, float __yRe ); /* x - yRe */
function cf_subRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_subRe( var zz:fComplex; zx:fComplex; yRe:Single );
fComplex cf_subrRe( fComplex __x, float __yRe ); /* yRe - x */
function cf_subrRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_subrRe( var zz:fComplex; zx:fComplex; yRe:Single );
fComplex cf_tan( fComplex __z );
function cf_tan( zx:fComplex ): fComplex;
procedure cf_tan( var zy:fComplex; zx:fComplex );
fComplex cf_tanh( fComplex __z );
function cf_tanh( zx:fComplex ): fComplex;
procedure cf_tanh( var zy:fComplex; zx:fComplex );
Zurück zum Inhaltsverzeichnis
4.2 Überladene C++/Delphi-Funktionen
float abs( fComplex _z );
function abs( zx:fComplex ): Single;
float abs( fPolar _p );
function abs( px:fPolar ): Single;
fComplex acos( fComplex _z );
function acos( zx:fComplex ): fComplex;
function add( zx, zy:fComplex ): fComplex;
function add( zx:fComplex; yRe:Single ): fComplex;
function add( yRe:Single; zx:fComplex ): fComplex;
function addRe( zx:fComplex; yRe:Single ): fComplex;
float arg( fComplex _z );
function arg( zx:fComplex ): Single;
float arg( fPolar _p );
function arg( px:fPolar ): Single;
fComplex asin( fComplex _z );
function asin( zx:fComplex ): fComplex;
fComplex atan( fComplex _z );
function atan( zx:fComplex ): fComplex;
fComplex conj( fComplex _z );
function conj( zx:fComplex ): fComplex;
fPolar conj( fPolar _p );
function conj( px:fPolar ): fPolar;
fComplex cos( fComplex _z );
function cos( zx:fComplex ): fComplex;
fComplex cosh( fComplex _z );
function cosh( zx:fComplex ): fComplex;
fComplex cubic( fComplex _z );
function cubic( zx:fComplex ): fComplex;
fPolar cubic( fPolar _p );
function cubic( px:fPolar ): fPolar;
function divide( zx, zy:fComplex ): fComplex;
function divide( zx:fComplex; yRe:Single ): fComplex;
function divide( yRe:Single; zx:fComplex ): fComplex;
function divide( px, py:fPolar ): fPolar;
function divide( px:fPolar; yRe:Single ): fPolar;
function divide( yRe:Single; px:fPolar ): fPolar;
function divRe( zx:fComplex; yRe:Single ): fComplex;
function divRe( px:fPolar; yRe:Single ): fPolar;
function divrRe( zx:fComplex; yRe:Single ): fComplex;
function divrRe( px:fPolar; yRe:Single ): fPolar;
fComplex exp( fComplex _z );
function exp( zx:fComplex ): fComplex;
fPolar exptop( fComplex _z );
function exptop( zx:fComplex ): fPolar;
fComplex fComplex( float Re_part, float Im_part=0 );
fComplex fComplex( dComplex cd );
fComplex fComplex( eComplex ce ); // type-casting constructors
fComplex fComplex( fPolar pf ); // interconversion from polar
fComplex fComplex( dPolar pd );
fComplex fComplex( ePolar pe );
float imag(); // to be used as zim = z.imag();
float imag( fComplex _z ); // to be used as zim = imag( z );
function imag( zx:fComplex ): Single;
float imag( fPolar _p );
function imag( px:fPolar ): Single;
fComplex inv( fComplex _z );
function inv( zx:fComplex ): fComplex;
fPolar inv( fPolar _p );
function inv( px:fPolar ): fPolar;
fComplex ipow( fComplex __base, int __expon );
function ipow( zx:fComplex; exponent:Integer ): fComplex;
fPolar ipow( fPolar __base, int __expon );
function ipow( px:fPolar; exponent:Integer ): fPolar;
fComplex ln( fComplex _z );
function ln( zx:fComplex ): fComplex;
fComplex lntoc( fPolar _p );
function lntoc( px:fPolar ): fComplex;
fComplex log( fComplex _z );
function log( zx:fComplex ): fComplex;
fComplex logtoc( fPolar _p );
function logtoc( px:fPolar ): fComplex;
fComplex log2( fComplex _z );
function log2( zx:fComplex ): fComplex;
fComplex log2toc( fPolar _p );
function log2toc( px:fPolar ): fComplex;
fComplex log10( fComplex _z );
function log10( zx:fComplex ): fComplex;
fComplex log10toc( fPolar _p );
function log10toc( px:fPolar ): fComplex;
fComplex magargtoc( float _mag, float _angle );
function magargtoc( mag, angle:Single ): fComplex;
function mul( zx, zy:fComplex ): fComplex;
function mul( zx:fComplex; yRe:Single ): fComplex;
function mul( yRe:Single; zx:fComplex ): fComplex;
function mul( px, py:fPolar ): fPolar;
function mul( px:fPolar; yRe:Single ): fPolar;
function mul( yRe:Single; px:fPolar ): fPolar;
function mulRe( zx:fComplex; yRe:Single ): fComplex;
function mulRe( px:fPolar; yRe:Single ): fPolar;
fComplex neg( fComplex _z );
function neg( zx:fComplex ): fComplex;
fPolar neg( fPolar _p );
function neg( px:fPolar ): fPolar;
float norm( fComplex _z );
function norm( zx:fComplex ): Single;
float norm( fPolar _p );
function norm( px:fPolar ): Single;
fComplex pow( fComplex __base, fComplex __expon);
fComplex pow( float __base, fComplex __expon);
fComplex pow( fComplex __base, float __expon );
function pow( zx, exponent:fComplex ): fComplex;
function pow( zx:fComplex; exponent:Single ): fComplex;
function pow( base:Single; exponent:fComplex ): fComplex;
function pow( px:fPolar; exponent:Single ): fPolar;
fComplex powReBase( float __base, fComplex __expon );
function powReBase( base:Single; exponent:fComplex ): fComplex;
fComplex powReExpo( fComplex __base, float __expon );
function powReExpo( zx:fComplex; exponent:Single ): fComplex;
fPolar powReExpo( fPolar __base, float __expon );
function powReExpo( px:fPolar; exponent:Single ): fPolar;
fPolar principal( fPolar _p );
fPolar principal( floag __mag, float __arg );
function principal( px:fPolar ): fPolar;
fComplex quartic( fComplex _z );
function quartic( zx:fComplex ): fComplex;
fPolar quartic( fPolar _p );
function quartic( px:fPolar ): fPolar;
float z.real(); // to be used as zre = z.real();
float real( fComplex _z ); // to be used as zre = real ( _z );
function real( zx:fComplex ): Single;
float real( fPolar _p );
function real( px:fPolar ): Single;
fPolar reimtop( float _re, float _im );
function reimtop( re, im:Single ): fPolar;
fComplex sin( fComplex _z );
function sin( zx:fComplex ): fComplex;
fComplex sinh( fComplex _z );
function sinh( zx:fComplex ): fComplex;
fComplex sqrt( fComplex _z );
function sqrt( zx:fComplex ): fComplex;
fPolar sqrt( fPolar _p );
function sqrt( px:fPolar ): fPolar;
fComplex square( fComplex _z );
function square( zx:fComplex ): fComplex;
fPolar square( fPolar _z );
function square( px:fPolar ): fPolar;
function sub( zx, zy:fComplex ): fComplex;
function sub( zx:fComplex; yRe:Single ): fComplex;
function sub( yRe:Single; zx:fComplex ): fComplex;
function subRe( zx:fComplex; yRe:Single ): fComplex;
function subrRe( zx:fComplex; yRe:Single ): fComplex;
fComplex tan( fComplex _z );
function tan( zx:fComplex ): fComplex;
fComplex tanh( fComplex _z );
function tanh( zx:fComplex ): fComplex;
Zurück zum Inhaltsverzeichnis
E N D E
Copyright für OptiVec und CMATH Software und Dokumentation
© 1996-2024 OptiCode - Dr. Martin Sander Software-Entwicklung
Alle Rechte vorbehalten.