2016-12-28 21 views
2

の配列の配列を比較し、私はこのように、単一の配列の配列として3×3のマトリクス表を宣言: メモリコピーとメモリは、Delphiでシングル

m_Table: array [0..2] of array [0..2] of Single; 

今、私はメモリにしたいとの内容を比較します別のテーブルまたはメモリは、別のテーブルのテーブルコンテンツをコピーします。私はそれを行うネストループを作成できることを知っていますが、可能であれば、ループなしでそのジョブを実行したいと思います。

私の質問は、それは次のようにメモリをコピーしたり、比較することが正しいとされていますされていない場合

CompareMem(m_Table, other.m_Table, 9 * SizeOf(Single)); 
CopyMemory(m_Table, other.m_Table, 9 * SizeOf(Single)); 

、それを行うための正しい方法は何ですか?

副次的な質問として、9 * SizeOf(Single)の代わりにコピーする長さを取得するより良い方法があります。 SizeOf(m_Table ^)?

ありがとうございます。

答えて

5

問題のコードは問題ありません。個人的には、Moveはメモリをコピーする慣習的な方法だと思います。さらに、タイプのサイズを取得するのにSizeOf(m_Table)を使用します。

私はあなたの比較が浮動小数点等価演算子とは異なることを指摘します。おそらくそれがあなたが望むものですが、あなたはこれに気づくべきです。例えば、ゼロとマイナスゼロは、浮動小数点比較を使用して比較を行いますが、メモリ比較は使用しません。また、NaNは常に同一ではなく、同じビットパターンであっても比較しません。

これらの行列の型を宣言すると、コードをより拡張可能にすることにもなります。それがなければ、そのようなオブジェクトを受け入れる関数を書くことはできません。

5

正しいと最も簡単な方法は、タイプ定義することがあります。そして、あなたが直接書き込むことができます

type 
    TMatrix3x3 = array [0..2,0..2] of Single; 

を:

var 
    v1, v2: TMatrix3x3; 
begin 
    fillchar(v1,sizeof(v1),0); 
    move(v1,v2,sizeof(v1)); 
    if comparemem(@v1,@v2,sizeof(v1)) then 
    writeln('equals'); 
end; 

sizeof()を使用してコードを安全かつ読みやすくします。

あなたはメソッドを持つラッパー型定義することができます。必要であれば、その後、高度な暗黙の割り当てなどの機能、および演算子など

{ TMatrix3x3 } 

type 
    TMatrix3x3 = record 
    v: array [0..2,0..2] of Single; 
    procedure Zero; 
    procedure Copy(var dest: TMatrix3x3); 
    procedure Fill(const source: TMatrix3x3); 
    function Equals(const other: TMatrix3x3): boolean; 
    end; 

procedure TMatrix3x3.Copy(var dest: TMatrix3x3); 
begin 
    move(v,dest,sizeof(v)); 
end; 

function TMatrix3x3.Equals(const other: TMatrix3x3): boolean; 
begin 
    result := CompareMem(@v,@other.v,sizeof(v)); 
end; 

procedure TMatrix3x3.Fill(const source: TMatrix3x3); 
begin 
    move(source,v,sizeof(v)); 
end; 

procedure TMatrix3x3.Zero; 
begin 
    fillchar(v,sizeof(v),0); 
end; 

を。

実際に行列演算で作業する場合は、ホイールを再発明しないでください。すでに存在し、完全にテストされたライブラリを使用すると、多くのトラブルやデバッグ時間を節約できます。

+0

として割り当てることができ、System.Math.Vectorsユニットから標準TMatrixタイプを使用する必要があり、私はそのようなタイプを持っている良いものがある疑い。私はそのようなタイプのすべての自分のルーチンをロールバックしたことを知っています。 –

+1

回答の強化されたレコードに関するいくつかの問題。メソッドの主体を変更するメソッドを提示します。それはレコードの問題です。 constパラメタでこのようなメソッドを呼び出すと、意味エラーに繋がります。メモリが書き込み可能でない場合でも実行時エラーが発生します。レコードに変更メソッドを持たないでください。値を返す静的クラス関数を使用します。そして、equals演算子は等しくないと少し役に立たない。さらに、バイナリ比較は浮動小数点比較とは異なります。それは微妙ですが重要です。 –

+1

さらに、コピーと塗りつぶしのメソッドを削除することができ、それらの代わりに普通の古い ':= '代入演算子を使用します。ゼロに設定したい場合は、その値で型付き定数を宣言し、代入を使用するのが最善の方法です。 –

1

あなたは、あなたがちょうどif Matrix1 = Matrix2 thenとして直接それを比較すると、既存のライブラリについてはMatrix1 := Matrix2

+0

あなたは大きな前提をしています。そのRTLタイプは2D空間用です。しかし、質問者は、例えば、3D方位行列に興味がある可能性があります。 –

+1

@DavidHeffernan質問は明示的に3x3の行列についてです – EugeneK

+0

あなたが参照する型は2D空間用です。私の3x3マトリックスは3D空間用です。そのタイプが適切かどうかは分かりません。このタイプが2Dか3Dかはわかりません。 –

関連する問題