Da das hier ein rein mathematisches Problem ist, muss man das auch so lösen.
Der Ansatz ist recht simpel. Man negiert eine reelle Zahl indem man sie ins Komplexe überführt und dort mit e^(i*pi) multipliziert. Das klingt jetzt etwas kompliziert, aber wenn man die eulersche Darstellung nimmt, reciht es die Phase mit pi zu summieren.
Delphi-Quellcode:
procedure TForm1.NegButtonClick(Sender: TObject);
var Kart:IKart;
Euler:IEuler;
begin
//Vorbereitung
Kart:=TComplex.create as IKart;
Kart.Imag:=0;
Kart.Real:=StrToFloat(Eingabe.Text);
Euler:=Kart as IEuler;
//Negation
Euler.Phase:=Euler.Phase+pi;
//Ergebnis
Ausgabe.Caption:=FloatToStr(Kart.Real);
end;
Die beiden Interfaces sehen so aus:
Delphi-Quellcode:
type
IEuler=Interface
['{5EBED258-ACED-4D74-AB9D-C7048887343A}']
procedure setPhase(value:Double);
procedure setBetrag(value:Double);
function getPhase:Double;
function getBetrag:Double;
property Phase:Double read getPhase write setPhase;
property Betrag:Double read getBetrag write setBetrag;
end;
IKart=Interface
['{93216A14-7CB0-4377-B844-793511F3C24F}']
procedure setReal(value:double);
procedure setImag(value:Double);
function getReal:Double;
function getImag:Double;
property Real:Double read getReal write setReal;
property Imag:Double read getImag write setImag;
end;
Und die Klasse dazu:
Delphi-Quellcode:
interface
type
TComplex=class(TInterfacedObject,IKart,IEuler)
Constructor Create;
private
FReal,FImag:Double;
FBetrag,FPhase:Double;
procedure setReal(value:double);
procedure setImag(value:Double);
procedure setPhase(value:Double);
procedure setBetrag(value:Double);
function getReal:Double;
function getImag:Double;
function getPhase:Double;
function getBetrag:Double;
procedure Euler2Kart;
procedure Kart2Euler;
end;
implementation
{ TComplex }
constructor TComplex.Create;
begin
FReal:=0;
FImag:=0;
FBetrag:=0;
FPhase:=0;
end;
procedure TComplex.Euler2Kart;
begin
FReal:=cos(FPhase)*FBetrag;
FImag:=sin(FPhase)*FBetrag;
end;
function TComplex.getBetrag: Double;
begin
result:=FBetrag;
end;
function TComplex.getImag: Double;
begin
result:=FImag;
end;
function TComplex.getPhase: Double;
begin
result:=FPhase;
end;
function TComplex.getReal: Double;
begin
result:=FReal;
end;
procedure TComplex.Kart2Euler;
begin
FBetrag:=sqrt(sqr(FReal)+sqr(FImag));
asm
MOV EAX, Self
FLD QWORD PTR [EAX].FImag
FLD QWORD PTR [EAX].FReal
FPATAN
FWAIT
FST QWORD PTR [EAX].FPhase
end;
if FPhase<0
then FPhase:=FPhase+2*pi;
end;
procedure TComplex.setBetrag(value: Double);
begin
FBetrag:=value;
Euler2Kart;
end;
procedure TComplex.setImag(value: Double);
begin
FImag:=value;
Kart2Euler;
end;
procedure TComplex.setPhase(value: Double);
begin
while value<0
do Value:=Value+2*pi;
while value>=2*pi
do Value:=Value-2*pi;
FPhase:=Value;
Euler2Kart;
end;
procedure TComplex.setReal(value: double);
begin
FReal:=value;
Kart2Euler;
end;
Achja: Für den Arctan musste ich mal kurz auf Assembler zurückgreifen (wegen FPATAN)
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.