Komplexe Zahlen Division



  • Hallo,

    ich hoffe, es kann mir einer helfen. Ich habe ein Programm geschrieben zur Division von Komplexen Zahlen. Doch irgendwie funktioniert es nicht bzw. ich komme nicht weiter. Ich hoffe, dass mir jemand sagen kann, was ich falsch mache..

    namespace Übung_2_
    {
        public struct Complex
        {
            public double real;
            public double imaginär;
    
            public Complex(double real, double imaginär)
            {
                this.real = real;
                this.imaginär = imaginär;
            }
    
               public static Complex operator /(Complex A, Complex B)
            {
                double A, B;
                double a, b, c, d;
    
                    A.real = (a*c+b*d)/(c*c+d*d);  
                    B.real = (b*c-a*d)/(c*c+d*d);
    
                return new Complex(A,B);
    
            }
    
            public override string ToString()
            {
                return (System.String.Format("{0} + {1}i", real, imaginär));
            }
        }
    
        class Complex1
        {
            static void Main()
            {                     
    
                Complex c1 = new Complex(2.3, 3.7);
                Complex c2 = new Complex(1.4, 2.3);
                Complex c3 = c1 / c2;
    
                System.Console.WriteLine("Die erste komplexe Zahl: " + c1);
                System.Console.WriteLine("Díe zweite komplexe Zahl: " + c2);
                System.Console.WriteLine("Die Division der beiden komplexen Zahlen: " + c3);
                System.Console.ReadKey();
            }
        }
    }
    


  • In Zeile 20/21 sind a,b,c,d nicht initialisiert. Ansonsten ist "funktioniert nicht" keine sinnvolle Fehlerbeschreibung.



  • Danke für deine Antwort.

    Genau da hakt es bei mir. Ich weiß nicht, ob man diese Operation so machen kann.
    Ich habe ehrlich gesagt keine Ahnung, wie ich diese am besten initialiseren soll.



  • Die ganzen lokalen Variablen in der Funktion sind überflüssig - du solltest die übergebenen Parameter A und B benutzen...

    Deine obere Formel entspricht dabei dann dem Realanteil und deine untere Formel ist der Imaginäranteil (sofern du für a, b, c und d die passenden Werte A.real, A.imaginär, ... einsetzt bzw. die lokalen Variablen genau so initialisierst).

    PS: Die Parameter einer Funktion werden idR. kleingeschrieben, also a und b (jedoch kämst du dann mit den lokalen Parametern - sofern du diese weiter nutzt - durcheinander, so daß du die Parameter auch dividend und divisor nennen könntest).



  • Danke!!

    Ich stehe total auf dem Schlauch. Ich weiß einfach nicht, wie ich diese Operation anders ausdrücken soll. Ich habe mir das nicht so kompliziert vorgestellt.



  • So habe nochmal etwas probiert:

    public static Complex operator /(Complex A, Complex B, Complex a, Complex b, Complex c, Complex d)
            {
    
                A = (a.real * c.real + b.real * d.real) / (c.real * c.real + d.real * d.real);
                B = (b.imaginär * c.imaginär - a.imaginär * d.imaginär) / (c.imaginär * c.imaginär + d.imaginär * d.imaginär);
    
                return new Complex(A, B);
    

    So sieht es aktuell aus. Jetzt kommt nur noch Fehler: der überladene binäre Operator "/" nimmt zwei Parameter an.
    Kann mir jemand weiterhelfen?



  • Puh, da fehlt aber einiges am Grundverständnis.

    Hier mal die Lösung (weil ansonsten wird das wohl ein endloses Ping-Pong-Spiel hier):

    public static Complex operator /(Complex A, Complex B)
    {
      double a = A.real;
      double b = A.imaginär;
      double c = B.real;
      double d = B.imaginär;
    
      double r = (a*c+b*d)/(c*c+d*d);
      double i = (b*c-a*d)/(c*c+d*d);
    
      return new Complex(r, i);
    }
    

    So, und jetzt versuche es zu verstehen.

    PS: Welchen Namen die Variablen in der Formel tragen, ist völlig egal - aber ich habe diese jetzt so belassen, wie in deinem ersten Beitrag.

    Die Alternative wäre eben direkt die Parameter in der Formel zu benutzen, aber dann richtig:

    double r = (A.real*B.real+A.imaginär*B.imaginär)/(B.real*B.real+B.imaginär*B.imaginär);
    double i = ...; // deine Aufgabe ;-)
    

    PPS: Umlaute in den Variablennamen (z.B. "imaginär") würde ich vermeiden, auch wenn C# (im Gegensatz zu C oder C++) damit klar kommt (aber je nach Editor kriegst du damit Probleme).



  • Super, tausend Dank. So macht es auch Sinn...

    Aber, was ist jetzt noch falsch? Ich habe versucht das Programm zu kompilieren, dann kommt die Fehlermeldung:

    "Eine Ausnahme (erste Chance) des Typs "System.InvalidOperationException" ist in mscorlib.dll aufgetreten.

    Zusätzliche Informationen: Schlüssel können nicht gelesen werden, wenn keine der Anwendungen eine Konsole besitzt, oder wenn die Konsoleneingabe aus einer Datei umgeleitet wurde. Verwenden Sie Console.Read.

    Falls ein Handler für diese Ausnahme vorhanden ist, kann das Programm möglicherweise weiterhin sicher ausgeführt werden."



  • Entferne

    System.Console.ReadKey();
    

    oder ersetze es durch

    System.Console.Read(); // bzw. ReadLine();
    

    (steht ja auch so in der Fehlermeldung!)



  • Tausend Dank bis hierhin.

    Ich möchte nun jetzt noch den Fall abfangen, wenn man die komplexen Zahlen die im Nenner stehen = 0 sind.

    Complex c1 = new Complex(2.3, 3.7);
                Complex c2 = new Complex(1.4, 2.3);
    
                Complex c3 = c1 / c2;
    
                if (c2 == 0)
                {
                    System.Console.WriteLine("geht nicht");
    
                }
    
                else
                {
                    System.Console.WriteLine("Die erste komplexe Zahl: " + c1);
                    System.Console.WriteLine("Die zweite komplexe Zahl: " + c2);
                    System.Console.WriteLine("Die Division der beiden komplexen Zahlen: " + c3);
    
                    System.Console.ReadLine();
    

    So etwas habe ich versucht, das geht leider nicht. Ich weiß, dass c2==0 so ohne weiteres nicht geht, weil eine Konvertierung von einer Dezimalzahl und einer komplexen Zahl und anders rum nicht so einfach möglich ist.
    Wie ist das möglich, dass ich den o.g. Fall abfange?



  • Schlüssel können nicht gelesen werden, wenn keine der Anwendungen eine Konsole besitzt, oder wenn die Konsoleneingabe aus einer Datei umgeleitet wurde.

    Werden die Fehlermeldungen bei MS von dressierten Affen übersetzt?



  • Gelo2802 schrieb:

    Ich weiß, dass c2==0 so ohne weiteres nicht geht, weil eine Konvertierung von einer Dezimalzahl und einer komplexen Zahl und anders rum nicht so einfach möglich ist.
    Wie ist das möglich, dass ich den o.g. Fall abfange?

    Überlade den == Operator und lass Vergleiche mit int zu.



  • Hallo Gelo2802,

    du mußt selbstverständlich zuerst auf 0 abfragen und nur im anderen Fall darfst du die Division durchführen. Am besten direkt im Operator / durchführen und dort dann überprüfen, ob der Divisorausdruck "(c*c+d*d)" Null ergibt (bevor du die Division durchführst).



  • Danke für den Tipp!

    Ich habe es nochmal an einer der Stelle vor der Division probiert:

    public static Complex operator /(Complex A, Complex B)
            {
                double a = A.real;
                double b = A.imaginär;
                double c = B.real;
                double d = B.imaginär;
                double r;
                double i;
    
                //double r = (a * c + b * d) / (c * c + d * d);
                //double i = (b * c - a * d) / (c * c + d * d);
    
                double r1 = (a * c + b * d);
                double r2 = (c * c + d * d);
                double i1 = (b * c - a * d);
    
                if (r2 == 0)
                {
                    System.Console.WriteLine("geht nicht");
    
                }
    
                else
                {
                    r = r1 / r2;
                    i = i1 / r2;
    
                    return new Complex(r, i);
                }
    
            }
    

    Fehlermeldung: Nicht alle Codepfade geben einen Wert zurück.

    Ich vermute, weil ich in der for-Schleife keinen Rückgabewert liefere. Doch was soll ich da liefern?



  • Welche for-Schleife? Du hast im else-Zweig ein return, aber nicht im if-Zweig... Normalerweise würde ich da eine Exception erwarten.



  • Ach sorry, habe mich verschrieben, meine natürlich den if-Zweig, wo ich kein Return habe.



  • Ja, das ist böse. Du musst etwas zurückgeben... oder eine Exception werfen, ansonsten kommt eh eine Exception bzw. undefiniertes Verhalten.



  • So, es funktioniert. Ich habe es mit einem Exception gelöst. Sind Imagninär - und Realteil == 0, dann wird eine Exception geworfen.

    Vielen lieben Dank an alle.


Anmelden zum Antworten