complex.cpp (Aufgabe 1)

Complex infinity

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

complex.cpp (Aufgabe 1)
Kurze und simple Frage:
Was soll unsere Implementierung machen, wenn wir durch 0+0i teilen lassen?
Fehler werfen oder es laufen lassen?

(Division durch 0 wirft hier keinen Fehler sondern setzt den Wert = -1.#INF und das Ergebnis ist definiert als “komplex unendlich”)


Ich habe auch noch eine allgemeine Frage…
Bei Fehlerabfragen ist es doch uns ueberlassen, ob wir assertions verwenden oder einfach if-Abfragen oder Aehnliches machen oder?
Hauptsache der Fehler wird gefunden und richtig behandelt?!

EDIT:
Ich kriege immer bei double einen seg fault… wenn ich das Gleiche mit float oder was anderem kompiliere geht es aber…:

double array[5];
for(int i=0; i<5; i++){
	array[i] = i;
}

Matrix<double> m6(5,1,array);
m6.print();

Any ideas?


Meinst du mit Fehlerabfragen auch sowas, wie die Division durch 0 bzw. Multiplikation einer nxm mit einer rxs Matrix, wobei m != r?
Es würde mich aber auch interessieren, wie wir so etwas behandeln sollen!


Hast du genügend Speicher angelegt? int und float haben ja normal 4 byte, double 8 byte.

Edit: und auch korrekt die Daten kopiert? (memcopy etc.)


Brauche ich wirklich memcpy bei der Aufgabe?
Naja wenn ich von einem Template ein Array erstelle mit = new T[groesseInInt]; dann hat das Array doch den Typ “T” und es muesste doch somit automatisch der richtige Speicher allokiert werden?
Soviel Zeilen Code sind ja in diesem Konstruktor eig nicht…


hint Valgrind hint


Ah des geht auch fuer C++? Wusste ich nicht…
Die ganzen Manpages fuer C… gelten die quasi auch fuer C++? ALso sind das die gleichen Funktionen?


Sollen wir bei der Matrizenmultiplikation (mit anderen Matrizen und mit Skalaren) eigentlich eine neue Matrix erstellen, die die neuen Werte hat oder das this-Objekt so verändern, dass das Ergebnis praktisch in der this-Matrix gespeichert wird?


Ja ok, genau so meinte ich das schon :wink: Scheint erstmal richtig zu sein.
Interessant wäre noch, an welcher Stelle im Code es kracht, aber das kannst du ja, wie schon erwähnt, mit valgrind rausfinden.

Die Manpages gelten natürlich genauso, da C eine Teilmenge von C++ ist. Allerdings sollte man bspw. nicht [m]#include <string.h>[/m], sondern [m]#include [/m] verwenden, da das letztere im Namespace std definiert ist.
Als ganz gute Referenzseite kann ich www.cplusplus.com empfehlen.

Was würdest du denn als Nutzer einer Matrixklasse bei folgendem Code erwarten?

Matrix A;
Matrix B;
...
Matrix C = A * B;

(Kannst dir ja überlegen, was entsprechend für int etc. passieren würde :wink: )


Hab vor einigen Semestern ein Testcase fuer die Aufgabe(n) geschrieben, zu finden unter:

/home/cip/2010/he29heri/pub/algoks

Hat fuer alle Punkte bei den Abgaben gereicht, sollte also fuer Grenzfaelle hilfreich sein (falls ich sie getestet hab). Ist aber schon ein paar Semester her, kann also gut sein, dass sich die Aufgabenstellung (leicht) veraendert hat.

2 Likes

Wie du exakt abbrichst ist egal, Hauptsache das Program stirbt. Ich hab damals einfach [m]assert()[/m] verwendet.


Danke! :slight_smile:

[s]Ich habe aber folgendes Problem, gleich bei einem der ersten Tests bricht das Programm ab:

A1: mainTEST.cpp:84: int main(): Assertion `fabs(((c2).getReal()) - (1.0f)) < 0.0001' failed.

Werde daraus aber nicht sonderlich schlau, was könnte ich falsch gemacht haben?[/s]
Fehler gefunden.

1 Like

Damit meinst du jetzt aber die Testfälle, oder? Mir ist immer noch nicht klar, was passieren soll, wenn ich z.B. zwei Matrizen nicht multiplizieren kann, weil deren Länge und Höhe nicht übereinstimmt (im Moment gebe ich dann einfach eine 0-Matrix zurück). Deine main läuft bei mir allerdings sonst problemlos :wink:


Wenn zwei Matrizen nicht multiplizierbar sind, klingt das für mich stark nach einem Fehlerfall. Denn eine 0-Matrix ist sicher nicht das, was der Nutzer sich in diesem Fall wünscht ;).


Ich hätte mal eine generelle Frage zu C++:
Wir müssen die 2 Methoden schreiben:
Complex &Complex::operator+=(const Complex &r) {

Complex Complex::operator+(const Complex &r) {

Wieso steht beim ersten ein & vor dem 2.Complex?
Ich dachte anfangs, dass liegt daran, dass wir den operator “+=” neu definieren, aber das kann nicht stimmen, dann müsste bei der 2.Methode auch ein & stehen…

bzw. Das 1.Complex ist der Rückgabetyp, aber was bedeutet das 2. Complex?


Beim ersten bekommst du eine Referenz auf ein Objekt (welches?) zurück (daher das [m]&[/m]), da du mit dem +=-Operator dieses ja veränderst (analog zu [m]int a = 0; a += 3;[/m]).
Im zweiten Fall soll ein neues Objekt vom Typ Complex erstellt und zurückgegeben werden (eben wie [m]int a = 0; int b = a + 3;[/m]).

Das [m]Complex::[/m] ist einfach der Zugriff auf den Namespace, da du das Ganze ja nicht in der complex.h schreibst, sondern in einer Datei außerhalb (complex.cpp). Das drückt einfach die Zugehörigkeit zu der Klasse aus, da sonst der Compiler ja nicht weiß, zu welcher Klasse der Operator gehören soll (eine Bindung an Dateinamen wie in Java gibt es ja in C++ nicht).


Die Operatoren sind ja etwas unterschiedlich. Das [m]Complex::[/m] sagt in beiden Fällen, dass die Funktion zur Klasse Complex gehört. (Die eigentliche Klassendefinition ist ja in der .h-Datei.)

Complex Complex::operator+(const Complex &r)

Hier erstellst du ein neues Objekt, addierst this (linke Seite) und den Parameter (rechte Seite) und returnst das neue Objekt vom Typ [m]Complex[/m].

Complex &Complex::operator+=(const Complex &r)

Hier veränderst du das this-Objekt (linke Seite) und returnst eine Referenz auf dieses Objekt - der Rückgabetyp ist also [m]Complex &[/m]. (Wieso das & Zeichen nicht rechts steht kommt wohl von der komischen C-Syntax mit der man Pointer anlegt: [m]int *a, b;[/m] legt einen Pointer und eine Variable an, um das zu verdeutlichen schreibt man den Stern nicht zum Typ…).


Gibts dafür schon ne Antwort? Falls ja seh ich sie grad nicht ^^


Also ich würde sagen, dass es reicht, wenn man es abfragt, eine Meldung ausgibt (bzw. assert) und das Prog beendet.
Denke nicht, dass wir es so detailliert haben müssen und die Zah als komplex unendlich darstellen sollen.

1 Like