AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi [Tutorial] Quadratische Gleichungen vollständig lösen

[Tutorial] Quadratische Gleichungen vollständig lösen

Ein Thema von Wolfgang Mix · begonnen am 24. Jul 2009 · letzter Beitrag vom 10. Apr 2010
Antwort Antwort
Seite 3 von 9     123 45     Letzte » 
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#21

Re: Quadratische Gleichungen vollständig lösen

  Alt 26. Jul 2009, 22:47
Zitat von Wolfgang Mix:
Ich hoffe, die meisten von Euch können jetzt mit dieser Variante leben:
Sterben wird daran schon niemand Allerdings kann ich mir nicht vorstellen, daß viele mit der Variante zufrieden sind. Ehrlich gesagt, habe ich sowas aus meiner Sicht Unsinniges schon lange nicht mehr gesehen. Hier mindestens fünf Gründe:

- 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.
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#22

Re: Quadratische Gleichungen vollständig lösen

  Alt 26. Jul 2009, 23:03
Ich habe versucht zumindest die Strings rauszunehmen und ich hoffe, das der vergleich auf Radikant = 0 jetzt besser ist

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

Delphi-Quellcode:
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;
MfG
xZise
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.577 Beiträge
 
#23

Re: Quadratische Gleichungen vollständig lösen

  Alt 26. Jul 2009, 23:27
Dann werfe ich mal das hier in den Raum:
Delphi-Quellcode:
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;
Ich hab versucht, das ganze etwas an die numerische Berechnung anzupassen ( http://en.wikipedia.org/wiki/Quadrat...implementation )

Edit: kleine Korrektur - ist leider nicht ausprobiert
  Mit Zitat antworten Zitat
Benutzerbild von Wolfgang Mix
Wolfgang Mix

Registriert seit: 13. Mai 2009
Ort: Lübeck
1.222 Beiträge
 
Delphi 2005 Personal
 
#24

Re: Quadratische Gleichungen vollständig lösen

  Alt 27. Jul 2009, 11:09
jfheins schrieb:

Zitat:
Edit: kleine Korrektur - ist leider nicht ausprobiert
Bei Eingabe von a=1, b=2 und c=3 muß die Funktion
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.
Wolfgang Mix
if you can't explain it simply you don't understand it well enough - A. Einstein
Mein Baby:http://www.epubli.de/shop/buch/Grund...41818516/52824
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#25

Re: Quadratische Gleichungen vollständig lösen

  Alt 27. Jul 2009, 11:12
Zitat von Wolfgang Mix:
Da gefällt mir meine letzte Variante besser.
Und warum das? Mit Strings kannst du nicht weiterrechnen. Und wieder zurück konvertieren ginge zwar, aber nur sicher, wenn du ein Ergebnis hast. Ansonsten könnte das ja imaginär sein. Da ist jfheins wohl die beste, weil diese - im Gegensatz zu unseren - extra auf Fließkomma ausgerichtet ist.

MfG
xZise
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.577 Beiträge
 
#26

Re: Quadratische Gleichungen vollständig lösen

  Alt 27. Jul 2009, 11:56
Zitat von Wolfgang Mix:
Bei Eingabe von a=1, b=2 und c=3 muß die Funktion
x1 = -1 + 1,414 i und
x2 = -1 - 1,414 i zurückliefern. Probiere das 'mal bitte!
In Ermangelung eines Delphi: Anbei der übersetzte c# Code mit Testprogramm ...

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;
    }
}
Angehängte Dateien
Dateityp: exe test_2_170.exe (10,5 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Wolfgang Mix
Wolfgang Mix

Registriert seit: 13. Mai 2009
Ort: Lübeck
1.222 Beiträge
 
Delphi 2005 Personal
 
#27

Re: Quadratische Gleichungen vollständig lösen

  Alt 27. Jul 2009, 14:02
Okay, wenn du mit den komplexen Werten weiterrechnen willst, gefällt mir deine Variante.
Die Namensgebung deiner Variablen würde ich noch anpassen.

Zitat:
var public Double complex;
meint wohl den Imaginärteil der komplexen Zahl, die aus Real- und Imaginärteil besteht

z = a + b * i

Gruß

Wolfgang
Wolfgang Mix
if you can't explain it simply you don't understand it well enough - A. Einstein
Mein Baby:http://www.epubli.de/shop/buch/Grund...41818516/52824
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.577 Beiträge
 
#28

Re: Quadratische Gleichungen vollständig lösen

  Alt 27. Jul 2009, 14:11
Okay, hab's korrigiert
  Mit Zitat antworten Zitat
Benutzerbild von Wolfgang Mix
Wolfgang Mix

Registriert seit: 13. Mai 2009
Ort: Lübeck
1.222 Beiträge
 
Delphi 2005 Personal
 
#29

Re: Quadratische Gleichungen vollständig lösen

  Alt 27. Jul 2009, 15:02
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!
Wolfgang Mix
if you can't explain it simply you don't understand it well enough - A. Einstein
Mein Baby:http://www.epubli.de/shop/buch/Grund...41818516/52824
  Mit Zitat antworten Zitat
Benutzerbild von Wolfgang Mix
Wolfgang Mix

Registriert seit: 13. Mai 2009
Ort: Lübeck
1.222 Beiträge
 
Delphi 2005 Personal
 
#30

Re: Quadratische Gleichungen vollständig lösen

  Alt 5. Nov 2009, 20:19
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:
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.
Bedeutung von Rückgabewert c, wenn
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:
//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;
Der böse Lehrer (wm) verlangt jetzt noch von (Fach-)Gymnasiasten:
Beweisen Sie, daß PQ-Formel und "Mitternachtsformel" absolut identisch sind.
Das ist gemein von dem Typen

Gruß

Wolfgang
Wolfgang Mix
if you can't explain it simply you don't understand it well enough - A. Einstein
Mein Baby:http://www.epubli.de/shop/buch/Grund...41818516/52824
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +2. Es ist jetzt 00:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf