Kalkulator liczb zespolonych - błędne obliczenia

0

Witam, dostałem na zadanie zrobienie kalkulatora liczb zespolonych w Lazarusie, jeśli mam być szczery do nie do końca wiem jak to powinno wyglądać, zrobiłem coś takiego(załącznik z projektem) i jest źle, błędnie oblicza fazę. Był bym wdzięczny za pomoc.

0

No to od czego by tu zacząć ... może od początku. Nie wiem czy zdajesz sobie sprawę ale operacje na liczbach zespolonych wykonuje się mniej więcej tak jak na wielomianach więc ten kod:

try
      z1r:=StrToFloat(Edit1.Text);
      z1i:=StrToFloat(Edit2.Text);
      z2r:=StrToFloat(Edit3.Text);
      z2i:=StrToFloat(Edit4.Text);
    except
      ShowMessage('Uzupelnij wszystkie pola cyframi');
    end;

     if Mnozenie.Checked then begin
         wr:=z1r*z2r;
         wi:=z1i*z2i;
      end
        else if Dzielenie.Checked then begin
         wr:=z1r/z2r;
         wi:=z1i/z2i;
      end;

mniej więcej pokazuje, że jednak powinieneś najpierw nieco doczytać na temat tych liczb. Polecam:
http://obliczone.pl/wzory-i-w%C5%82asno%C5%9Bci/636-liczby-zespolone
Gdy zrozumiesz o co dokładnie chodzi to zakodowanie tego nie powinno być problemem.
Prosty przykład to przetestowania: (1 + i) * (3 + i) powinno dać Ci 2 + 4i pamiętaj bowiem że i^2=-1
Natomiast dzielenie (3+i) / (2+i) powinno dać Ci 7/5 - 1/5i

0

Ok do biorę się do przerabiania, choć wydaję mi się że wygodniej będzie pierwsze zamienić liczbę na postać wykładniczą i wtedy ją przemnożyć a następnie wrócić do postaci algebraicznej, tym bardziej że wynik zapisany w postaci wykładniczej też powinien być.

0

Problem z liczeniem wartości chyba rozwiązany, pozostaje problem z obliczaniem właściwego kąta, nie mam pojęcia dlaczego wypisuje zły kąt kiedy wartość Re z liczby jest równa zero. Mógł by ktoś rzucić okiem co może być nie tak.

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    Edit8: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Dodawanie: TRadioButton;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Odejmowanie: TRadioButton;
    Mnozenie: TRadioButton;
    Dzielenie: TRadioButton;
    Dzialania: TRadioGroup;
    Stopnie: TRadioButton;
    Radiany: TRadioButton;
    Jednostka: TRadioGroup;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure Edit2Change(Sender: TObject);
    procedure Edit3Change(Sender: TObject);
    procedure Edit4Change(Sender: TObject);
    procedure Edit5Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Label1Click(Sender: TObject);
    procedure Label2Click(Sender: TObject);
    procedure Label4Click(Sender: TObject);
    procedure DodawanieChange(Sender: TObject);
    procedure DzialaniaClick(Sender: TObject);
    procedure MnozenieChange(Sender: TObject);
    procedure OdejmowanieChange(Sender: TObject);
    procedure JednostkaClick(Sender: TObject);
    procedure RadianyChange(Sender: TObject);
    procedure StopnieChange(Sender: TObject);


  private
    { private declarations }


  public
    { public declarations }

  end;

var
  Form1: TForm1;
var
  z1r,z1i,z2r,z2i,wr,wi,wartosc,wykladnik,modul2,modul1,wyk1,wyk2:double;

implementation

{$R *.lfm}

{ TForm1 }

// Funkcja obliczająca faze;
function Faza(im:double; re:double): double;
begin
     if re = 0 then begin
        result:=PI/2;
     end else begin
    Result:= arctan(im/re);
     end;
end;

procedure TForm1.Label1Click(Sender: TObject);
begin
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
      z1r:=StrToFloat(Edit1.Text);
      z1i:=StrToFloat(Edit2.Text);
      z2r:=StrToFloat(Edit3.Text);
      z2i:=StrToFloat(Edit4.Text);
      //Dodawanie i odejmowanie
      if Dodawanie.Checked then begin
         wr:=z1r+z2r;
         wi:=z1i+z2i;
      //Obliczanie modulu dla wyniku dodawania oraz fazy
         wartosc:= sqrt(wr*wr+wi*wi);
         wykladnik:=(Faza(wi,wr)/PI)*180;

      end
      else if Odejmowanie.Checked then begin
         wr:=z1r-z2r;
         wi:=z1i-z2i;
      //Obliczanie modulu dla wyniku odejmowania oraz fazy
         wartosc:= sqrt(wr*wr+wi*wi);
         wykladnik:=(Faza(wi,wr)/PI)*180;
      end
      else if Mnozenie.Checked then begin
         //Obliczanie modulow
         modul1:=sqrt(z1r*z1r+z1i*z1i);
         modul2:=sqrt(z2r*z2r+z2i*z2i);
         //Obliczanie fazy
         wyk1:=Faza(z1i,z1r);
         wyk2:=Faza(z2i,z2r);

         ShowMessage(floattostr(wyk1));
         ShowMessage(floattostr(wyk2));

         //Wykonanie dzialania
         wartosc:= modul1*modul2;
         wykladnik:=((wyk1+wyk2)/PI)*180 ;
         wr:=wartosc*(cos(wyk1+wyk2));
         wi:=wartosc*(sin(wyk1+wyk2));
      end
      else if Dzielenie.Checked then begin
         //Obliczanie modulow
         modul1:=sqrt(z1r*z1r+z1i*z1i);
         modul2:=sqrt(z2r*z2r+z2i*z2i);
         //Obliczanie fazy
         wyk1:=Faza(z1i,z1r);
         wyk2:=Faza(z2i,z2r);
         //Wykonanie dzialania
         wartosc:= modul1/modul2;
         wykladnik:=((wyk1-wyk2)/PI)*180 ;
         wr:=wartosc*(cos(wyk1-wyk2));
         wi:=wartosc*(sin(wyk1-wyk2));
      end;




     Edit5.Text:=FloatToStr(wr);
     Edit6.Text:=FloatToStr(wi);
     Edit7.Text:=FloatToStr(wartosc);
     Edit8.Text:=FloatToStr(wykladnik);
    end;

procedure TForm1.Button2Click(Sender: TObject);
begin
     Edit1.Text:=FloatToStr(0);
     Edit2.Text:=FloatToStr(0);
     Edit3.Text:=FloatToStr(0);
     Edit4.Text:=FloatToStr(0);
     Edit5.Text:=FloatToStr(0);
     Edit6.Text:=FloatToStr(0);
     Edit7.Text:=FloatToStr(0);
     Edit8.Text:=FloatToStr(0);
end;



procedure TForm1.Edit2Change(Sender: TObject);
begin

end;

procedure TForm1.Edit3Change(Sender: TObject);
begin

end;

procedure TForm1.Edit4Change(Sender: TObject);
begin

end;

procedure TForm1.Edit5Change(Sender: TObject);
begin

end;

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

procedure TForm1.Label2Click(Sender: TObject);
begin

end;

procedure TForm1.Label4Click(Sender: TObject);
begin

end;

procedure TForm1.DodawanieChange(Sender: TObject);
begin

end;

procedure TForm1.DzialaniaClick(Sender: TObject);
begin

end;

procedure TForm1.MnozenieChange(Sender: TObject);
begin

end;

procedure TForm1.OdejmowanieChange(Sender: TObject);
begin

end;

procedure TForm1.JednostkaClick(Sender: TObject);
begin

end;

procedure TForm1.RadianyChange(Sender: TObject);
begin

end;

procedure TForm1.StopnieChange(Sender: TObject);
begin

end;

end.

 
0

faza nie jest pi/2 dla urojonych.

np. dla -1i faza będzie raptem 3/2 pi == -pi/2;

rozumiesz?

1 użytkowników online, w tym zalogowanych: 0, gości: 1