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
Thema durchsuchen
Ansicht
Themen-Optionen

[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
gammatester

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

Re: Quadratische Gleichungen vollständig lösen

  Alt 29. Jan 2010, 08:27
Ein weiterer Bug und zwei Vorschläge:

Bug:
a=1, b=1e140, c=1
ergibt
X1= -2,14326739881213E123
X2= -1E140
a wird zwar erst richtig mit Vieta berechnet, dann aber im else-Zweig von 'p<0' überschrieben.

Vorschlag 1:
Das Demo-Programm ist so geändert, das nur einmal die Gleichung gelöst wird, und nicht 6! (in Worten sechsmal) bei komplexen Lösungen.

Vorschlag 2:
Der "Small p"-Zweig wurde entfernt, wenn er beigehalten werden soll (wofür keine Notwendigkeit besteht, für kleine negative p wird er zB ja auch nicht benutzt!), muß eine Fallunterscheidung Diskriminante <0 und >=0 eingebaut werden.

Hier der vollständige Code.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Math, ComCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Edit4: TEdit;
    Edit5: TEdit;
    Button2: TButton;
    RichEdit1: TRichEdit;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  MySolution = Record
    a,b,d:double;
    c:integer;// 1: 2 real solution; 2: 1 real solution;
              // 3: 2 complex solutions
end;

//Wolfgang Mix - Delphi-PRAXiS
function SolveQuadraticEquation( a, b, c : Double ): MySolution;
var p, q , discriminant, discriminant2, 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;

  //if p is a very big number - sqr(p/2) > MaxDouble
  if abs(p)>sqrt(Math.MaxDouble) then
  begin
    //code
    showmessage('p is a very big number');
    //showmessage(floattostr(Math.MaxDouble));
    result.a:=abs(p) + sqrt(0.25 - (q/p)/p);
    result.b:=abs(p) - sqrt(0.25 - (q/p)/p);
    result.c:=1;
    result.d:=0.25 - (q/p)/p;
    exit;
  end;

  // calculate discriminant
  discriminant := sqr(p/2) - q;
  Result.d := discriminant;

  // calculate real value
  re:=-p/2;
  // calculate imaginary value
  im:=sqrt(abs(discriminant));
  //Form1.Edit7.Text:=FloatToStr(discriminant);

  if discriminant > 0 then
  begin // 2 solutions
    if p>=0 then
    begin
      Result.b := -p/2 - sqrt(discriminant);
      Result.a := q/Result.b; //x1 mit Vieta
      Result.c := 1;
    end
    else begin
      Result.a := -p/2 + sqrt( discriminant);
      Result.b := q/Result.a; //x2 mit Vieta
      Result.c := 1;
    end;
  end

  else

  if discriminant < 0 then
  begin // 2 complex solutions
     Result.a := re;
     Result.b := im;
     Result.c := 3;
  end
  else

  begin // 2 equal solutions
    Result.a := -p/2;
    Result.b := Result.a;
    Result.c := 2;
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,discriminant: double;
    indicator:integer;
    qs: MySolution;

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
     {WE: Gleichung nur einmal lösen und Ergebnisse anzeigen}
     qs := SolveQuadraticEquation(a,b,c);
     indicator := qs.c;
     case indicator of
       1: Begin
            Label1.Caption:='2 real solutions';
            RichEdit1.Lines.Add ('X1= ' + FloatToStr(qs.a));
            RichEdit1.Lines.Add ('X2= ' + FloatToStr(qs.b));
          End;
       2: Begin
            Label1.Caption:='1 real solution';
            RichEdit1.Lines.Add ('X= ' + FloatToStr(qs.a));
          end;
       3: Begin
            Label1.Caption:='2 complex solutions';
            RichEdit1.Lines.Add ('X1= ' + FloatToStr(qs.a)+
                                      ' + ' + FloatToStr(qs.b)+ ' i ');
            RichEdit1.Lines.Add ('X2= ' + FloatToStr(qs.a)+
                                      ' - ' + FloatToStr(qs.b )+ ' i ');
          End;
     end;
     discriminant:= qs.d;
     Edit4.Text:=FloatToStr(discriminant);
     Edit5.Text:=IntToStr(indicator);
   end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  RichEdit1.Clear;
end;

end.
  Mit Zitat antworten Zitat
Antwort Antwort


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 +1. Es ist jetzt 22:51 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