Jean-Milost Reymond
Jean-Milost Reymond

Reputation: 1943

Memory copy and memory compare array of array of Single

In Delphi, I declared a 3x3 matrix table as an array of array of Single, like this:

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

Now I want to memory compare the content with another table, or memory copy the table content from another table. I know that I can create a nested loop to do that, but I want to do the job without any loop, if possible.

My question is, it is correct to copy or compare the memory like this:

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

If not, what is the correct way to do that?

And as a subsidiary question, is there a better way to get the length to copy instead of 9 * SizeOf(Single), like e.g. SizeOf(m_Table^)?

Regards

Upvotes: 2

Views: 326

Answers (3)

EugeneK
EugeneK

Reputation: 2224

You should use standard TMatrix type from System.Math.Vectors unit, then you can just compare it directly as if Matrix1 = Matrix2 then and assign as Matrix1 := Matrix2

Upvotes: 1

Arnaud Bouchez
Arnaud Bouchez

Reputation: 43033

The correct and easiest way may be to define a type:

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

Then you can directly write:

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;

Using sizeof() make your code safe and readable.

You may define a wrapper type with methods:

{ 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;

Including then advanced features like implicit assignment, and operators, if needed.

But don't reinvent the wheel, if you really to work with matrix arithmetic. Use an already existing and fully tested library, which will save you a lot of trouble and debugging time.

Upvotes: 5

David Heffernan
David Heffernan

Reputation: 612993

The code in the question works fine. Personally I would say that Move is the idiomatic way to copy memory. Further I would use SizeOf(m_Table) to obtain the size of the type.

I would point out that your comparison differs from the floating point equality operator. Perhaps that's what you want, but you should be aware of this. For instance zero and minus zero compare equal using floating point comparison but not with memory compare. And NaNs always compare not equal, even with identical bit patterns.

Let me also comment that it would make your code more extendible if you declared a type for these matrices. Without that you won't be able to write functions that accept such objects.

Upvotes: 5

Related Questions