{ Programm 6.3. : Record von komplexen Zahlen ,   von Rene' Scholz }

program complex(input,output);

uses crt;

type    typ  =  (CART,POLAR);
        cplx =  record                    { Vereinbarung von complex }
                       form  : typ;
                       case    typ  of
                           CART    : (a,b :real;);
                           POLAR   : (r,w :real;);
                       end;

        cx   = ^cplx;

{
function cls;
begin
 writeln( chr(27), '[2J', chr(27), '[;H' );
end;
}




function Lies_Aufgabe ( var z1,z2 : cplx) :String;   { MenÜ-Programm }
var      aufg    : string;
         op,fm   : char;
         ip      : real;

begin
 clrscr;
 writeln('        Programm        *** COMPLEX ***        by Rene'' Scholz ');
 writeln;writeln;writeln;
 writeln('Ausfuehrung von Multiplikation und Division komplexer Zahlen .');
 writeln('Es ist kartesische oder polare Darstellung moeglich .');
 writeln;writeln;
 writeln('Konvention : 0 (pi)  <  Winkel  <  2 (pi)  ');
 writeln;writeln;
 writeln('Ende :  Geben Sie  '' N ''  auf die Frage  '' Weiter ? ''  ein.');
 writeln;writeln;
 repeat
    write('Welche Darstellung wollen Sie verwenden   ??    ( K \ P )     :');
    readln(fm);
 until (fm=#13) or (fm='K') or (fm='k') or (fm='P') or (fm='p') ;

 if fm<>#13 then
  begin
    writeln;writeln;writeln;writeln;
    case fm of
    'K' , 'k' :
        begin
           z1.form:=CART;
           z2.form:=CART;
           write('    Geben Sie den Real-Teil der ersten Zahl ein  :');
           readln(z1.a);
           write('    Geben Sie den Img.-Teil der ersten Zahl ein  :');
           readln(z1.b);
           writeln;
           write('    Geben Sie den Real-Teil der zweiten Zahl ein  :');
           readln(z2.a);
           write('    Geben Sie den Img.-Teil der zweiten Zahl ein  :');
           readln(z2.b);
           writeln;
        end;

    'P' , 'p' :
        begin
           z1.form:=POLAR;
           z2.form:=POLAR;
           repeat
             write(' Geben Sie den Radius der ersten Zahl ein  :  ');
             readln(ip);
           until ip>0;
           z1.r:=ip;
           write(' Geben Sie den Winkel der ersten Zahl ein  ( in pi ) :  ');
           readln(z1.w);
           writeln;
           repeat
             write(' Geben Sie den Radius der zweiten Zahl ein  :  ');
             readln(ip);
           until ip>0;
           z2.r:=ip;
           write(' Geben Sie den Winkel der zweiten Zahl ein  ( in pi ) :  ');
           readln(z2.w);
           writeln;
        end;
     end;                           { of case }

    repeat
      if z1.form=CART then
        begin
           clrscr;
           write('                  Zahl 1 ist :            ');
           write(z1.a:6:2 );
           if z1.b<0 then writeln(' ',  z1.b:6:2 ,'*i'       )
                     else writeln(' + ',z1.b:6:2 ,'*i'       );

           write('                  Zahl 2 ist :            ');
           write(z2.a:6:2 );
           if z2.b<0 then writeln(' ',  z2.b:6:2 ,'*i'       )
                     else writeln(' + ',z2.b:6:2 ,'*i'       );
           writeln;
        end

      else
        begin
           clrscr;
           write('                  Zahl 1 ist :               ');
           writeln(z1.r:6:2 , '*e^(i*' , z1.w:6:2 , '*pi)'  );
           write('                  Zahl 2 ist :               ');
           writeln(z2.r:6:2 , '*e^(i*' , z2.b:6:2 , '*pi)'  );
           writeln;
        end;

      writeln;writeln('Welche Operation wollen Sie ausfuehren : ');
      writeln('     < * >        --->   Multiplikation        oder');
      writeln('     < : >        --->   Division ');
      writeln;write('Operation         --->   ??  ');
      readln(op);
    until (op='*') or (op=':');
    if op='*' then Lies_aufgabe:='mult' else Lies_aufgabe:='div';
  end
  else Lies_aufgabe:='';

end;                                { of read_aufgabe }



function multiplikation (var z1,z2 :cplx) :cx;
var   res  :cplx;
begin
 if z1.form=CART then
   begin
    res.form:=CART;
    res.a:=z1.a*z2.a - z1.b*z2.b;
    res.b:=z1.a*z2.b + z2.a*z1.b;
   end

 else
   begin
    res.form:=POLAR;
    res.r:=z1.r*z2.r;
    res.w:=z1.w+z2.w;
     if res.w >2 {pi} then
       repeat
         res.w:=res.w-2;
       until res.w <2 ;
   end;
 Multiplikation:=@res;
end;                                { of Multiplikation }



function Division (z1,z2 :cplx) :cx;
var  res     :cplx;
     betrag  :real;
begin
 if z1.form=CART then
  begin
   res.form:=CART;
   betrag:=z2.a*z2.a + z2.b*z2.b;
   res.a:=( z1.a*z2.a + z1.b*z2.b )/betrag ;
   res.b:=( z2.a*z1.b - z1.a*z2.b )/betrag ;
  end

 else
  begin
   res.form:=POLAR;
   res.r:=z1.r/z2.r;
   res.w:=z1.w - z2.w;
   if res.w >2 {pi} then
     repeat
        res.w:=res.w - 2 {pi} ;
     until res.w <2 ;
   if res.w <0 then
     repeat
        res.w:=res.w + 2 {pi} ;
     until res.w >0 ;
  end;
 Division:=@res;
end;                                { of Division }




var   what                 : string;
      weiter               : char;
      zahl_1,zahl_2,erg    : cplx;

begin                               { Main }
 clrscr;
  repeat
    what:=Lies_Aufgabe(zahl_1,zahl_2);
    if what<>'' then
     begin
      if what = 'mult'
        then  erg:=Multiplikation(zahl_1,zahl_2)^
        else  erg:=Division(zahl_1,zahl_2)^;
      writeln;writeln;writeln;writeln;
      if erg.form = CART then
        begin
          write('Ergebniss :       ',erg.a:4:2 );
          if erg.b<0  then  writeln(' ',erg.b:6:2 , '*i')
                      else  writeln(' + ',erg.b:6:2 , '*i');
        end

      else
         writeln('Ergebniss :       ',erg.r:6:2 , '*e^(i*',
                                      erg.w:6:2 , '*pi' , ')' );

      writeln;writeln;writeln;writeln;
      write('Weiter ??         ( Y / N )  ');
      readln(weiter);
     end;

  until  (weiter='N') or (weiter='n') ;

 clrscr;
 writeln('  By. ');

end.