2009-05-22 38 views
6

Ich versuche, eine Funktion in C++ zu schreiben, die für X mithilfe der quadratischen Gleichung löst. Das ist, was ich ursprünglich geschrieben, die so lange zu arbeiten scheint, da es keine komplexen Zahlen für eine Antwort:Quadratische Gleichung in C++ lösen

float solution1 = (float)(-1.0 * b) + (sqrt((b * b) - (4 * a * c))); 
solution1 = solution1/(2*a); 

cout << "Solution 1: " << solution1 << endl; 

float solution2 = (float)(-b) - (sqrt((b*b) - (4 * a * c))); 
solution2 = solution2/(2*a); 
cout << "Solution 2: " << solution2; 

Wenn zum Beispiel verwende ich die Gleichung: x^2 - x - 6, I bekomme die Lösung 3, -2 richtig.

Meine Frage ist, wie würde ich für komplexe Zahlen berücksichtigen .... zum Beispiel angesichts der Gleichung:

x^2 + 2x + 5

Solving von Hand, würde ich -1 + 2i, -1 - 2i.

Nun, ich denke, zwei Frage, kann ich die oben genannten besser und auch machen es für die komplexe Zahl?

Danke für jede Hilfe!

+3

Die anderen Jungs zur Verfügung gestellt gute Antworten so für mich keinen Grund, sie zu versuchen und den Schatten stellen;) Wenn Sie jedoch eine allgemeinere Lösung der Gleichung ax wollen^2 + bx + c = 0, das eine erinnern = = 0 sollte ein gültiger Wert sein. Dies würde zu einer Division von Null führen, daher müssen Sie diesen Fall separat behandeln. In diesem Fall würde das bedeuten, dass Sie eine lineare Gleichung mit einer Wurzel haben. Prost! – ralphtheninja

+0

Sie implizieren, Sie sind besorgt über komplexe Wurzeln, aber was ist mit komplexen Koeffizienten in der ursprünglichen Gleichung? –

+1

Komplexe Koeffizienten erfordern einen anderen Ansatz vollständig. Also wird das die nächste Frage sein :) * schreit ab und bereitet eine Antwort vor Hand vor * – ralphtheninja

Antwort

8

So etwas wie dies funktionieren würde:

struct complex { double r,i; } 
struct pair<T> { T p1, p2; } 

pair<complex> GetResults(double a, double b, double c) 
{ 
    pair<complex> result={0}; 

    if(a<0.000001) // ==0 
    { 
    if(b>0.000001) // !=0 
     result.p1.r=result.p2.r=-c/b; 
    else 
     if(c>0.00001) throw exception("no solutions"); 
    return result; 
    } 

    double delta=b*b-4*a*c; 
    if(delta>=0) 
    { 
    result.p1.r=(-b-sqrt(delta))/2/a; 
    result.p2.r=(-b+sqrt(delta))/2/a; 
    } 
    else 
    { 
    result.p1.r=result.p2.r=-b/2/a; 
    result.p1.i=sqrt(-delta)/2/a; 
    result.p2.i=-sqrt(-delta)/2/a; 
    } 

    return result; 
} 

diese Weise können Sie die Ergebnisse in ähnlicher Weise für beide reelle und komplexe Ergebnisse zu erzielen (die realen Ergebnisse haben nur den imaginären Teil auf 0 gesetzt). Würde mit Boost noch schöner aussehen!

edit: für die Delta-Sache behoben und eine Überprüfung für degenerierte Fälle wie a = 0 hinzugefügt. Schlaflose Nacht ftl!

+0

Wenn der sqrt erfolgreich ist, ist das Ergebnis> = 0. Und wenn das Argument negativ ist, stürzt dein Programm ab. Sie sollten das Zeichen zuerst testen und danach das Quadrat berechnen. Wenn das Vorzeichen negativ wäre, würden Sie result.first.i = + sqrt (4 * a * c-b * b)/2/a festlegen. (Warum definieren Sie Ihren eigenen Typ, wenn es ein perfektes feines std :: pair gibt?) – MSalters

+0

sollte Delta = b * b-4 * a * c sein, und nehmen Sie sqrt nur wenn delta> = 0. delta = 0 oder a = 0 sind gültige Fälle, wenn wir eine Wurzel haben. Was ist, wenn a = b = 0 und c = 1? –

+0

Was wäre wenn? Das ist keine quadratische Funktion, und der/2/a Teil wird fehlschlagen. Dies funktioniert ziemlich gut, wenn delta = 0, außer dass tou'll das gleiche Ergebnis zweimal zurückgibt. – MSalters

4

Sie haben es mehr oder weniger, überprüfen Sie einfach, ob der Teil, der in der Quadratwurzel ist negativ ist und dann verfolgen Sie das separat in Ihren Ermäßigungen.

3

Als Randnotiz: Beim Dividieren immer prüfen, ob der Nenner nicht Null ist. Und denken Sie daran Punktzahlen für Floating wie etwas zu verwenden:

#inlcude <float.h> 
if (fabs(a) < FLT_EPSILON) 
    then a is considered 0 
3

Sie könnten im Grunde verwenden nur std::complex<float> statt float Unterstützung für komplexe Zahlen zu erhalten.

1

Nicking die Idee von Blindy:

typedef std::complex<double> complex; 
using std::pair; 
pair<complex> GetResults(double a, double b, double c) 
{ 
    double delta=(b*b-4*a*c); 
    double inv_2a = 1/2/a; 
    if(delta >= 0) { 
    double root = sqrt(delta); 
    return std::make_pair(
     complex((-b-root)*inv_2a), 
     complex((-b+root)*inv_2a); 
    } else { 
    double root = sqrt(-delta); 
    return std::make_pair(
     complex(-b*inv_2a, -root*inv_2a)), 
     complex(-b*inv_2a, +root*inv_2a))); 
    } 
} 
20

Ein wichtiger Hinweis auf all dies. Die in diesen Antworten und in der ursprünglichen Frage gezeigten Lösungen sind nicht robust.

Die bekannte Lösung (-b + - sqrt (b^2 - 4ac))/2a ist bekannt, nicht robust in die Berechnung bilden sollen, wenn ac sehr klein b^2 compered ist, weil man zwei sehr ähnliche Werte subtrahiert. Es ist besser, die weniger bekannte Lösung 2c/(-b - + sqrt (b^2 -4ac)) für die andere Wurzel zu verwenden.

temp = -0.5 * (b + sign(b) * sqrt(b*b - 4*a*c); 
x1 = temp/a; 
x2 = c/temp; 

Die Verwendung von Zeichen (b) stellt sicher, dass wir nicht subtrahieren zwei ähnliche Werte:

eine stabile Lösung kann als berechnet werden.

Für das OP, ändern Sie dies für komplexe Zahlen wie von anderen Plakaten gezeigt.

+1

+1 Dies ist erheblich rechenintensiver als '(-b +/- sqrt (b * b - 4 * a * c))/(2a)'. Übrigens: da 'temp' 0.0 sein kann, ist die übliche Vorabteilungsüberprüfung erforderlich. (z. B. a, b, c = 1,0,0). – chux

+0

'temp' kann nur 0 sein, wenn' b' 0 ist –

-1

Ich habe das Programm ohne Verwendung von 'math.h' Header und versuchte auch verschiedene Logik ... aber mein Programm kann nur die quadratischen Gleichungen, die Koeffizienten von 'x-Quadrat' als eins haben ..... und wo Der Koeffizient von 'x' kann als eine Addition von zwei Zahlen ausgedrückt werden, die Faktoren eines konstanten Terms sind. z. x Quadrat + 8x + 16; x Quadrat + 7x + 12; etc. hier 8 = 4 + 4 & 16 = 4 * 4; Hier kann der Koeffizient von x als eine Addition von zwei Zahlen ausgedrückt werden, die Faktoren des konstanten Terms 16 sind ... Ich selbst bin nicht völlig damit zufrieden, habe aber etwas anderes versucht, ohne die Formel zur Lösung der quadratischen Gleichung zu verwenden. Code ist;

 #include<iostream.h> 
     #include<conio.h> 
     class quadratic 
       { 
       int b,c ; 
       float l,k; 
       public: 
       void solution(); 
       }; 
     void quadratic::solution() 
      { 
       cout<<"Enter coefficient of x and the constant term of the quadratic eqn where coefficient of x square is one"; 
       cin>>b>>c; 

       for(l=1;l<b;l++) 
        { 
        for(k=1;k<b;k++) 
        { 
        if(l+k==b&&l*k==c) 
         { 
          cout<<"x="<<-l<<"\t"<<"or"<<"\t"<<"x="<<-k; 
          cout<<"\n"; 
         } 
        } 
       } 
      } 
       void main() 
       { 
        quadratic a; 
        clrscr(); 
        a.solution(); 
        getch(); 
       }