![]() |
Re: Quadratische Gleichungen vollständig lösen
Zitat:
- Strings als Lösungen einer quadrischen Gleichung mit double-Koeffizienten sind einfach unsäglich (warum nicht gleich mit string-Koeffizienten, dann hätte der Unsinn wenigsten Methode) - Auf die Rundungsfehler/Auslöschung bei "-B/2 + sqrt(Radikand)" und positivem B wird wieder nicht eingegangen. - Eine völlig unmotivierte magische Konstanten 1E-6 entscheidet über 1 bzw 2 Lösungen. Dabei wir alles verworfen, bei denen sqrt(Radikand)<0.001 ist. - Es wird nicht gestestet, wieviel Lösungen zurückgeliefert werden. - Für die Ausgabe der Lösungen wird die Lösungsfunktion zweimal auf gerufen. Allerdings konsequenter Weise auch dann wenn's nur eine Lösung gibt. Anders als jfheins halte ich eine QG-Lösung in der Codelib für durchaus sinnvoll, wenn sie universell und so genau wie möglich ist. |
Re: Quadratische Gleichungen vollständig lösen
Ich habe versucht zumindest die Strings rauszunehmen und ich hoffe, das der vergleich auf Radikant = 0 jetzt besser ist :P
Auch kann man angeben, ob man eine komplexe Zahl haben möchte. Als kleines extra, kann man jetzt auch berechnen, wie denn X für A = 0, B != 0 gilt :P
Delphi-Quellcode:
MfG
type
TCmplxNumber = record RealPart, ImaginaryPart : Double end; TCmplxNumbers = array of TCmplxNumber; function CmplxNumber(const ARealPart, AImaginaryPart : Double) : TCmplxNumber; begin Result.RealPart := ARealPart; Result.ImaginaryPart := AImaginaryPart; end; function pq( A, B, C : Double; const AUseComplexNumbers : Boolean): TCmplxNumbers ; var Radikand, re, im: Double; begin // ax² + bx + c = 0 if IsZero(A) then begin if not IsZero(B) then begin // 0x^2 + bx + c = 0 ==> x := -c/b SetLength(Result, 1) Result := CmplxNumber(-c/b, 0); end; Exit end; B := B / A; //p C := C / A; //q // Radikand berechnen Radikand := Sqr(B/2) - C; //Realteil berechnen re:=-B/2; // Imaginärteil berechnen im := Sqrt(Abs(Radikand)); if Radikand > 0 then begin // zwei reele Lösungen SetLength(Result, 2); Result[0] := CmplxNumber(re + im, 0); Result[1] := CmplxNumber(re - im, 0); end else if IsZero(Radikand) then begin // eine reele Lösung SetLength(Result, 1); Result[0] := CmplxNumber(re); end else if (Radikand < 0) and (AUseComplexNumbers) then begin // keine reele, aber zwei komplexe Lösungen // Radikand:=-Radikand; SetLength(Result, 2); Result[0] := CmplxNumber(re, im); Result[1] := CmplxNumber(re, -im); end else SetLength(Result, 0); end; xZise |
Re: Quadratische Gleichungen vollständig lösen
Dann werfe ich mal das hier in den Raum:
Delphi-Quellcode:
Ich hab versucht, das ganze etwas an die numerische Berechnung anzupassen (
type
TComplex = record real, imaginary: Double; end; TQuadraticSolution = Array[0..1] of TComplex; implementation function SolveQuadratic(a, b, c: Double): TQuadraticSolutiuon; var t, ti: Double; begin if iszero(b) and iszero(c) then begin Result[0].real := 0; Result[0].imaginary := 0; Result[1].real := 0; Result[1].imaginary := 0; exit; end; if iszero(a) then raise Exception.Create('Coefficient a must not be zero!'); if b*b-4*a*c < 0 then begin t := -0.5 * b; ti := -0.5 * sign(b) * sqrt(4*a*c-b*b)); Result[0].real := t/a; Result[0].imaginary := ti/a; Result[1].real := t/a; Result[1].imaginary := -1 * ti/a; end else begin t := -0.5 * (b + sign(b) * sqrt(b*b-4*a*c)); Result[0].real := t/a; Result[0].imaginary := 0; Result[1].real := c/t; Result[1].imaginary := 0; end; end; ![]() Edit: kleine Korrektur - ist leider nicht ausprobiert :angel: |
Re: Quadratische Gleichungen vollständig lösen
jfheins schrieb:
Zitat:
x1 = -1 + 1,414 i und x2 = -1 - 1,414 i zurückliefern. Probiere das 'mal bitte! Da gefällt mir meine letzte Variante besser. |
Re: Quadratische Gleichungen vollständig lösen
Zitat:
MfG xZise |
Re: Quadratische Gleichungen vollständig lösen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Obige Werte liefern das korrekte Ergebnis - (1,-1,-2) ebenfalls (x1=-1, x2=2)
Code:
namespace Test_2
{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } public bool iszero(Double a) { return Math.Abs(a) < 1e-6; } public TQuadraticSolution SolveQuadratic(Double a, Double b, Double c) { TQuadraticSolution Result; if (iszero(b) && iszero(c)) { Result.first.real = 0; Result.first.imaginary = 0; Result.second.real = 0; Result.second.imaginary = 0; return Result; } if (iszero(a)) throw new ArgumentNullException("a", "Coefficient a must not be zero!"); if (b * b - 4 * a * c < 0) { Double t = -0.5 * b; Double ti = -0.5 * Math.Sign(b) * Math.Sqrt(4 * a * c - b * b); Result.first.real = t / a; Result.first.imaginary = ti / a; Result.second.real = t / a; Result.second.imaginary = -1 * ti / a; } else { Double t = -0.5 * (b + Math.Sign(b) * Math.Sqrt(b * b - 4 * a * c)); Result.first.real = t / a; Result.first.imaginary = 0; Result.second.real = c / t; Result.second.imaginary = 0; } return Result; } private void button1_Click(object sender, EventArgs e) { var solutions = SolveQuadratic((Double)numericUpDown1.Value, (Double)numericUpDown2.Value, (Double)numericUpDown3.Value); label1.Text = solutions.first.ToString(); label2.Text = solutions.second.ToString(); } } public struct TComplex { public Double real; public Double imaginary; public override String ToString() { if (imaginary < 0) return String.Format("{0} - {1} i", real, -imaginary); else return String.Format("{0} + {1} i", real, imaginary); } } public struct TQuadraticSolution { public TComplex first, second; } } |
Re: Quadratische Gleichungen vollständig lösen
Okay, wenn du mit den komplexen Werten weiterrechnen willst, gefällt mir deine Variante.
Die Namensgebung deiner Variablen würde ich noch anpassen. Zitat:
z = a + b * i Gruß Wolfgang |
Re: Quadratische Gleichungen vollständig lösen
Okay, hab's korrigiert ;)
|
Re: Quadratische Gleichungen vollständig lösen
Ich möchte jetzt 'mal kurz zusammenfassen.
Für die Schulmathematik genügt eigentlich die Kenntnis der PQ-Formel aus jeder Formelsammlung oder bei Wikipedia. Mancheiner fragt sich wohl inzwischen: "Wofür brauche ich das?". Interessant wird da Ganze erst in der E-Technik, wenn Widerstände, Spulen und Kondensatoren in Reihe, parallel oder noch komplizierter verschaltet werden. Dann gibt es sehr selten nur noch reelle Ergebnisse. Wer sich da 'mal einlesen möchte, für den gibt eigentlich nur ein Übungsbuch: Helmut Lindner, Bd.2, Aufgaben zur Wechselstromtechnik. Das wird an allen Unis als Standardwerk seit über 30 Jahren eingesetzt und stresst die meisten Studenten. Gibts in jeder Stadtbibliothek mehrfach oder für 9,90 € im Handel. Ich danke allen, die sich hier rege beteiligt habe, vor allen aber Aphton und jfheins, die zeigten, wie man aus Funktionen mehrere Werte zurückgeben kann. Das kannte ich als alter Pascalianer noch nicht, aber jetzt. Man darf ja auch im Alter noch dazulernen.:-) Nochmal danke an alle! |
Re: Quadratische Gleichungen vollständig lösen
Ich habe mich noch einmal mit dem Thema beschäftigt und versucht,
die Verbesserungsvorschläge der Beteiigten zu diesem Thresd umzusetzen. Daher stelle ich folgende Lösung zur Diskussion:
Delphi-Quellcode:
Bedeutung von Rückgabewert c, wenn
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,[b]Math[/b]; type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Button1: TButton; Edit6: TEdit; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} type MySolution = Record a,b:double; c:integer;// 1: 2 real solution; 2: 1 real solution; // 3: 2 complex solutions end; // Wolfgang Mix - Delphi-PRAXiS // Solve quadratic equations function SolveQuadraticEquation( a, b, c : Double ): MySolution; var p, q , discriminant, re, im: Double; begin // ax² + bx + c = 0 if (a = 0) then raise Exception.CreateFmt ('a should not be zero, no quadratic equation',[result.a]); p := b / a; q := c / a; // calculate discriminant discriminant := sqr(p/2) - q; // calculate real value re:=-p/2; // calculate imaginary value im:=sqrt(abs(discriminant)); if discriminant > 0 then begin // 2 solutions Result.a := -p/2 + sqrt( discriminant); Result.b := -p/2 - sqrt( discriminant); Result.c := 1; end else if Math.IsZero(discriminant) then //needs unit math begin // 1 solution Result.a := -p/2; Result.b := Result.a; Result.c := 2; end else if discriminant < 0 then begin // 2 complex solutions Result.a := re; Result.b := im; Result.c := 3; end; end; procedure TForm1.Button1Click(Sender: TObject); var a,b,c: double; indicator:integer; begin a:=StrToFloat(Edit1.Text); b:=StrToFloat(Edit2.Text); c:=StrToFloat(Edit3.Text); if (a=0) then begin // Don't calculate showmessage ('a should not be zero, no quadratic equation'); sleep(2000); exit; end else begin indicator:= SolveQuadraticEquation(a,b,c).c; Edit4.Text:=FloatToStr(SolveQuadraticEquation(a,b,c).a); Edit5.Text:=FloatToStr(SolveQuadraticEquation(a,b,c).b); Edit6.Text:=IntToStr(indicator); case indicator of 1: Label1.Caption:='2 real solutions'; 2: Label1.Caption:='1 real solution'; 3: Label1.Caption:='2 complex solutions'; end; end; end; end. c=1 --> 2 relle Lösungen Result[0] und Result[1] c=2 --> 1 reelle Lösung Result[0] = Result[1] c=3 --> 2 komplexe Lösungen Result[0] = Realteil +- Result[1] = Imaginärteil Nachdem die Lösung mittels PQ-Formel hier im Forum hinreichend diskutiert wurde und wir zu einer befriedigenden Lösung in Post #30 gekommen sind, zeige ich zusätzlich noch die Lösung mittels "Mitternachtformel", die wohl bei Lehrern/Dozenten noch beliebter ist. da der Umweg über die Berechnung von p und q entfällt. Zusätzlich habe ich mir im Unterschied zu oben noch die Diskriminante (c=4) als 4. Rückgebewert zurückgeben lassen. Wie man dann die Rückgabewerte ausgeben kann, zeige ich im Button1.Click.
Delphi-Quellcode:
Der böse Lehrer (wm) verlangt jetzt noch von (Fach-)Gymnasiasten:
//Wolfgang Mix - Delphi-PRAXiS
function SolveQuadraticEquation( a, b, c : Double ): MySolution; var discriminant, re, im: Double; begin // ax² + bx + c = 0 if (a = 0) then raise Exception.CreateFmt ('a should not be zero, no quadratic equation',[result.a]); // calculate discriminant discriminant := sqr(b)-4*a*c;; Result.d := discriminant; // calculate real value re:=-b/(2*a); // calculate imaginary value im:=sqrt(abs(discriminant))/(2*a); //Form1.Edit7.Text:=FloatToStr(discriminant); if discriminant > 0 then begin // 2 solutions Result.a := -b/(2*a) + sqrt( discriminant)/(2*a); Result.b := -b/(2*a) - sqrt( discriminant)/(2*a); Result.c := 1; end else if Math.IsZero(discriminant) then //needs unit math begin // 1 solution Result.a := -b/(2*a); Result.b := Result.a; Result.c := 2; end else if discriminant < 0 then begin // 2 complex solutions Result.a := re; Result.b := im; Result.c := 3; end; end; procedure TForm1.Button1Click(Sender: TObject); var a,b,c,discriminant: double; indicator:integer; begin RichEdit1.Lines.Clear; a:=StrToFloat(Edit1.Text); b:=StrToFloat(Edit2.Text); c:=StrToFloat(Edit3.Text); if (a=0) then begin // Don't calculate showmessage ('a should not be zero, no quadratic equation'); sleep(2000); exit; end else begin indicator:= SolveQuadraticEquation(a,b,c).c; case indicator of 1: Begin Label1.Caption:='2 real solutions'; RichEdit1.Lines.Add ('X1= ' + (FloatToStr(SolveQuadraticEquation(a,b,c).a))); RichEdit1.Lines.Add ('X2= ' + (FloatToStr(SolveQuadraticEquation(a,b,c).b))); End; 2: Begin Label1.Caption:='1 real solution'; RichEdit1.Lines.Add ('X= ' + (FloatToStr(SolveQuadraticEquation(a,b,c).a))); end; 3: Begin Label1.Caption:='2 complex solutions'; RichEdit1.Lines.Add ('X1= ' + (FloatToStr(SolveQuadraticEquation(a,b,c).a))+ ' + ' + FloatToStr(SolveQuadraticEquation(a,b,c).b )+ ' i '); RichEdit1.Lines.Add ('X2= ' + (FloatToStr(SolveQuadraticEquation(a,b,c).a))+ ' - ' + FloatToStr(SolveQuadraticEquation(a,b,c).b )+ ' i '); End; end; discriminant:= SolveQuadraticEquation(a,b,c).d; Edit4.Text:=FloatToStr(discriminant); Edit5.Text:=IntToStr(indicator); end; end; Beweisen Sie, daß PQ-Formel und "Mitternachtsformel" absolut identisch sind. Das ist gemein von dem Typen :mrgreen: Gruß Wolfgang |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz