在Delphi中,我将一个3x3矩阵表声明为Single数组的数组,如下所示:
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 ^)?
此致
答案 0 :(得分:5)
问题中的代码运行正常。就个人而言,我会说Move
是复制记忆的惯用方法。此外,我将使用SizeOf(m_Table)
来获取类型的大小。
我想指出你的比较与浮点相等运算符不同。也许这就是你想要的,但你应该意识到这一点。例如,使用浮点比较,零和零比较相等,但不与内存比较相比。并且NaN总是比较不相等,即使是相同的位模式。
我还要评论一下,如果您为这些矩阵声明了一个类型,它会使您的代码更具扩展性。如果没有它,您将无法编写接受此类对象的函数。
答案 1 :(得分: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;
如果需要,还包括隐式赋值和运算符等高级功能。
但是,如果你真的使用矩阵运算,不要重新发明轮子。使用已经存在且经过全面测试的库,这将为您节省大量的麻烦和调试时间。
答案 2 :(得分:1)
您应该使用TMatrix单元中的标准System.Math.Vectors类型,然后您可以直接将其与if Matrix1 = Matrix2 then
进行比较并指定为Matrix1 := Matrix2