3

BorlandDelphi7を使用してPascalプログラミングを行っています。複雑な数学関数のかなり基本的な(そして無料の)ソースコードライブラリをダウンロードしましたが、残念ながら、使用例はありませんでした。私はPascalのクラスにあまり詳しくないので、始めるにはその使用法の簡単な例を1つだけ必要だと思います。

何でもかまいません。2つの数字を足し合わせた例でも始められます。これが私が試したことです(私が知っている非常に足の不自由な人)。私の問題は、クラスコンストラクターの使い方がわからないことだと思います。

uses ComplexMath in 'complexmath.pas'

var z1,z2,z3 : TComplexNumber;
begin
  z1.R:=1.0; z1.I:=2.0;
  z2.R:=3.0; z2.I:=-1.0;
  z3 := TComplexMath.Add(z1,z2);
end.

TComplexMathの完全なソースコードは、http://delphi.about.com/library/weekly/aa070103a.htmから入手できます。また、以下のソースコードの部分的なリストを切り取って貼り付けました(このコードは、切り取られたことを明示的に示した場合を除いて、完全なファイルであることに注意してください)。

TComplexMathの部分的なソースコードリストは次のとおりです。

unit ComplexMath;

interface

uses Windows, SysUtils, Classes, Controls, Math;

type
  TComplexNumber = record
    R : single;
    I : single;
  end;

TComplexMath = class(TComponent)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;

    function Add(C1, C2 : TComplexNumber) : TComplexNumber; overload;
    { Returns the complex sum of C1 and C2 }

    function Add(C1, C2, C3 : TComplexNumber) : TComplexNumber; overload;
    { Returns the complex sum of C1 and C2 and C3 }

    ... and a bunch more like this ...

implementation

procedure Register;
  begin
    RegisterComponents('delphi.about.com', [TComplexMath]);
  end;

constructor TComplexMath.Create(AOwner : TComponent);
  begin
    inherited Create(AOwner);
  end;

 function TComplexMath.Add(C1, C2 : TComplexNumber) : TComplexNumber;
   begin
     Result.R := C1.R + C2.R;
     Result.I := C1.I + C2.I;
   end;

    ... and a bunch more like this ...

end.

しばらく苦労した後、私は最終的にクラス定義を取り除き、関数自体だけを使用しました(関数の単純なライブラリのように)。そして、これは私にとってはうまくいっていますが、このコンポーネントがどのように使用されることを意図していたかではないことを私は知っています。誰かがこのクラスを意図した方法で使用する非常に簡単な例を見せてくれたら本当にありがたいです。

4

2 に答える 2

7

使用目的は次のとおりです。

var
  cm: TComplexMath;

  z, w, sum: TComplexNumber;
begin

  cm := TComplexMath.Create(Self) // or nil, can most likely be anything
  try
    sum := cm.Add(z, w); // Now sum is the sum of z and w
  finally
    cm.Free;
  end;

end;

TComplexMathまた、アプリケーションの起動時(またはユニットの初期化など)にインスタンスを作成し、それをアプリケーションの存続期間中使用することもできます。

unit Unit1;

interface

var
  cm: TComplexMath;

...

implementation

procedure Test;
begin

  sum := cm.Add(z, w); // Now sum is the sum of z and w

end;

...

initialization

  cm := TComplexMath.Create(nil);

finialization

  cm.Free;

最後に、これはコンポーネントであるため、設計時にフォームにドロップできます。インスタンスはと呼ばれComplexMath1、次のようにフォームクラスで使用できます。

procedure TForm1.Button1Click(Sender: TObject);
var
  z, w, sum: TComplexNumber;    
begin
  sum := ComplexMath1.Add(z, w);
end;

私はこのクラスのデザインが本当に嫌いです。まず、必要なインスタンスは1つだけなので、代わりに関数クラスを関数にしてみませんか?本当に:なぜクラスを使用するのですか?最後に、Delphiの最新バージョンを使用する場合は、高度なレコードと演算子のオーバーロードを使用して、整数のような単純な型のようにz + w、ソースコードで機能するようにすることができます。zw

于 2013-02-25T19:03:40.593 に答える
7

私はそのコードをまったく使用しません。私の見解では本当に弱いです。これがより良いものです:

type
  TComplex = record
  public
    class operator Implicit(const D: Double): TComplex;
    class operator Negative(const C: TComplex): TComplex;
    class operator Equal(const C1, C2: TComplex): Boolean;
    class operator NotEqual(const C1, C2: TComplex): Boolean;
    class operator Add(const C1, C2: TComplex): TComplex;
    class operator Add(const C: TComplex; const D: Double): TComplex;
    class operator Add(const D: Double; const C: TComplex): TComplex;
    class operator Subtract(const C1, C2: TComplex): TComplex;
    class operator Subtract(const C: TComplex; const D: Double): TComplex;
    class operator Subtract(const D: Double; const C: TComplex): TComplex;
    class operator Multiply(const C1, C2: TComplex): TComplex;
    class operator Multiply(const C: TComplex; const D: Double): TComplex;
    class operator Multiply(const D: Double; const C: TComplex): TComplex;
    class operator Divide(const C1, C2: TComplex): TComplex;
    class operator Divide(const C: TComplex; const D: Double): TComplex;
    class operator Divide(const D: Double; const C: TComplex): TComplex;
    function IsZero: Boolean;
    function IsNonZero: Boolean;
    function Conj: TComplex;
    function Sqr: TComplex;
    function Sqrt: TComplex;
    function Mag: Double;
    function SqrMag: Double;
  public
    r: Double;
    i: Double;
  end;

const
  ZeroComplex: TComplex = ();//initialise to zero;

class operator TComplex.Implicit(const D: Double): TComplex;
begin
  Result.r := D;
  Result.i := 0.0;
end;

class operator TComplex.Negative(const C: TComplex): TComplex;
begin
  Result.r := -C.r;
  Result.i := -C.i;
end;

class operator TComplex.Equal(const C1, C2: TComplex): Boolean;
begin
  Result := (C1.r=C2.r) and (C1.i=C2.i);
end;

class operator TComplex.NotEqual(const C1, C2: TComplex): Boolean;
begin
  Result := not (C1=C2);
end;

class operator TComplex.Add(const C1, C2: TComplex): TComplex;
begin
  Result.r := C1.r + C2.r;
  Result.i := C1.i + C2.i;
end;

class operator TComplex.Add(const C: TComplex; const D: Double): TComplex;
begin
  Result.r := C.r + D;
  Result.i := C.i;
end;

class operator TComplex.Add(const D: Double; const C: TComplex): TComplex;
begin
  Result.r := D + C.r;
  Result.i := C.i;
end;

class operator TComplex.Subtract(const C1, C2: TComplex): TComplex;
begin
  Result.r := C1.r - C2.r;
  Result.i := C1.i - C2.i;
end;

class operator TComplex.Subtract(const C: TComplex; const D: Double): TComplex;
begin
  Result.r := C.r - D;
  Result.i := C.i;
end;

class operator TComplex.Subtract(const D: Double; const C: TComplex): TComplex;
begin
  Result.r := D - C.r;
  Result.i := -C.i;
end;

class operator TComplex.Multiply(const C1, C2: TComplex): TComplex;
begin
  Result.r := C1.r*C2.r - C1.i*C2.i;
  Result.i := C1.r*C2.i + C1.i*C2.r;
end;

class operator TComplex.Multiply(const C: TComplex; const D: Double): TComplex;
begin
  Result.r := C.r*D;
  Result.i := C.i*D;
end;

class operator TComplex.Multiply(const D: Double; const C: TComplex): TComplex;
begin
  Result.r := D*C.r;
  Result.i := D*C.i;
end;

class operator TComplex.Divide(const C1, C2: TComplex): TComplex;
var
  R, Denominator: Double;
begin
  if abs(C2.r)>=abs(C2.i) then begin
    R := C2.i/C2.r;
    Denominator := C2.r+R*C2.i;
    Result.r := (C1.r+R*C1.i)/Denominator;
    Result.i := (C1.i-R*C1.r)/Denominator;
  end else begin
    R := C2.r/C2.i;
    Denominator := C2.i+R*C2.r;
    Result.r := (C1.r*R+C1.i)/Denominator;
    Result.i := (C1.i*R-C1.r)/Denominator;
  end;
end;

class operator TComplex.Divide(const C: TComplex; const D: Double): TComplex;
begin
  Result := C*(1.0/D);
end;

class operator TComplex.Divide(const D: Double; const C: TComplex): TComplex;
var
  R, Denominator: Double;
begin
  if abs(C.r)>=abs(C.i) then begin
    R := C.i/C.r;
    Denominator := C.r+R*C.i;
    Result.r := D/Denominator;
    Result.i := -R*Result.r;
  end else begin
    R := C.r/C.i;
    Denominator := C.i+R*C.r;
    Result.i := -D/Denominator;
    Result.r := -R*Result.i;
  end;
end;

function TComplex.IsZero: Boolean;
begin
  Result := Self=ZeroComplex;
end;

function TComplex.IsNonZero: Boolean;
begin
  Result := Self<>ZeroComplex;
end;

function TComplex.Conj: TComplex;
begin
  Result.r := r;
  Result.i := -i;
end;

function TComplex.Sqr: TComplex;
begin
  Result := Self*Self;
end;

function TComplex.Sqrt: TComplex;
var
  x, y, v, w: Double;
begin
  if IsZero then begin
    Result := ZeroComplex;
  end else begin
    x := abs(r);
    y := abs(i);
    if x>=y then begin
      v := y/x;
      w := System.Sqrt(x)*System.Sqrt(0.5*(1.0+System.Sqrt(1.0+v*v)));
    end else begin
      v := x/y;
      w := System.Sqrt(y)*System.Sqrt(0.5*(v+System.Sqrt(1.0+v*v)));
    end;
    if r>=0.0 then begin
      Result.r := w;
      Result.i := i/(2.0*w);
    end else begin
      if i>=0.0 then begin
        Result.i := w;
      end else begin
        Result.i := -w;
      end;
      Result.r := i/(2.0*Result.i);
    end;
  end;
end;

function TComplex.Mag: Double;
var
  x, y, Temp: Double;
begin
  x := abs(r);
  y := abs(i);
  if x=0.0 then begin
    Result := y;
  end else if y=0.0 then begin
    Result := x;
  end else if x>y then begin
    Temp := y/x;
    Result := x*System.Sqrt(1.0+Temp*Temp);
  end else begin
    Temp := x/y;
    Result := y*System.Sqrt(1.0+Temp*Temp);
  end;
end;

function TComplex.SqrMag: Double;
begin
  Result := System.Sqr(r) + System.Sqr(i);
end;

+これは、演算子のオーバーロードを使用して、、、および演算子-を実装します。このレコードに基づいて記述できるコードは、質問で参照しているコンポーネントよりもはるかに表現力豊かであることがわかります。*/TComplex

リンクしたコードには、さらに多くの機能が実装されています。ただし、この回答のレコードを拡張して機能を追加するのは簡単です。

もちろん、Delphi 7を使用しているので、この回答のコードは役に立ちません。これは、演算子のオーバーロードが後で導入されるまで導入されなかったためです。深刻な数学を行う場合は、コードを読みやすくするために演算子のオーバーロードが必要です。

于 2013-02-25T19:17:09.873 に答える