3

我怎么能用 Delphi 6 做到这一点?UInt64 在 Delphi 6 中是未知的。它是在以后的版本中引入的。

var
  i, j: Int64;

  if UInt64(i) < UInt64(j) then ...


I am thinking of an asm procedure. 

function UInt64CompareLT(i, j: Int64): Boolean;
asm
 ???
end;

function UInt64CompareGT(i, j: Int64): Boolean;
asm
 ???
end;
4

3 回答 3

7

Int64Recfrom 类型SysUtils是为挑选 64 位整数部分的任务而设计的。

如果您碰巧使用的是早于该类型的 Delphi,请自行定义:

type
  Int64Rec = packed record
    case Integer of
      0: (Lo, Hi: Cardinal); 
      1: (Cardinals: array [0..1] of Cardinal); 
      2: (Words: array [0..3] of Word);
      3: (Bytes: array [0..7] of Byte);
  end;

更重要的是,您只需要一个函数,该函数返回 -1 表示小于,1 表示大于,0 表示等于。像这样的东西:

function CompareUInt64(const i, j: Int64): Integer;
begin
  if Int64Rec(i).Hi < Int64Rec(j).Hi then
    Result := -1
  else if Int64Rec(i).Hi > Int64Rec(j).Hi then
    Result := 1
  else if Int64Rec(i).Lo < Int64Rec(j).Lo then
    Result := -1
  else if Int64Rec(i).Lo > Int64Rec(j).Lo then
    Result := 1
  else
    Result := 0;
end;

这个想法是你首先比较高阶部分,只有当它相等时,你才会继续比较低阶部分。

这可以通过比较函数来简化Cardinal

function CompareCardinal(const i, j: Cardinal): Integer;
begin
  if i < j then
    Result := -1
  else if i > j then
    Result := 1
  else
    Result := 0;
end;

function CompareUInt64(const i, j: Int64): Integer;
begin
  Result := CompareCardinal(Int64Rec(i).Hi, Int64Rec(j).Hi);
  if Result = 0 then
    Result := CompareCardinal(Int64Rec(i).Lo, Int64Rec(j).Lo);
end;

最后,如果您需要问题的布尔函数,可以在这个更通用的函数之上实现它们。

于 2013-09-05T06:41:20.940 回答
2

不需要使用汇编程序(但是,当然,你可以这样做):你可以比较 Int64 的高和低部分:

  function UInt64CompareLT(i, j: Int64): Boolean;
  begin
    if (LongWord(i shr 32) < LongWord(j shr 32)) then
      Result := true
    else if (LongWord(i shr 32) > LongWord(j shr 32)) then
      Result := false
    else if (LongWord(i and $FFFFFFFF) < LongWord(j and $FFFFFFFF)) then
      Result := true
    else
      Result := false;
  end;

  function UInt64CompareGT(i, j: Int64): Boolean;
  begin
    if (LongWord(i shr 32) > LongWord(j shr 32)) then
      Result := true
    else if (LongWord(i shr 32) < LongWord(j shr 32)) then
      Result := false
    else if (LongWord(i and $FFFFFFFF) > LongWord(j and $FFFFFFFF)) then
      Result := true
    else
      Result := false;
  end;
于 2013-09-05T06:18:04.623 回答
1

使用汇编器是可能的,但会将您的代码绑定到特定的机器架构。
您可以在纯 Pascal 中实现这一点,如下所示:

type
  //Delcare a variant record to have 2 ways to access the same data in memory.
  T64Bit = record
  case Integer of
    0: (I64: Int64;);
    1: (Small: Cardinal; Big: Cardinal);
  end;

var
  I, J: T64Bit;

begin
  //You can set the value via normal Int64 assignment as follows:
  I.I64 := 1;
  J.I64 := 2;

  //Then you can compare the "big" and "small" parts on the number using
  //unsigned 32-bit comparisons as follows.
  if (I.Big < J.Big) or ((I.Big = J.Big) and (I.Small< J.Small)) then

  //The logic is as follows... 
  //  If the big part is less than, the the small part doesn't matter
  //  If the big parts are equal, then the comparison of the small parts determines the result.
于 2013-09-05T06:44:38.920 回答