int64 上的 SHR 不返回预期结果



我正在将一些C#代码移植到Delphi(XE5)。C# 代码包含如下代码:

long t = ...
...                
t = (t >> 25) + ...

我把它翻译成

t: int64;
...
t := (t shr 25) + ...

现在我看到德尔菲(有时)计算了错误的负 t 移位值,例如:

-170358640930559629 shr 25
Windows Calculator: -5077083139
C# code: -5077083139
Delphi: 
-170358640930559629 shr 25               = 544678730749 (wrong)

在本例中,-1*((-t shr 25)+1) 在德尔菲中给出正确的值。

对于 t 的其他负值,简单的类型转换为整数似乎给出了正确的结果:

integer(t shr 25)

我在二进制操作和表示方面处于极限,因此我将不胜感激任何帮助,只需在 Delphi 中获得与 C# 和 Windows 计算器相同的结果。

根据 Filipe 回答中链接的文章(其中说明了德尔菲进行shr而不是其他人进行sar的原因),以下是我对此的看法:

function CalculatorRsh(Value: Int64; ShiftBits: Integer): Int64;
begin
  Result := Value shr ShiftBits;
  if (Value and $8000000000000000) > 0 then
    Result := Result or ($FFFFFFFFFFFFFFFF shl (64 - ShiftBits));
end;

正如你在这里读到的,C和Delphi对待Shr的方式是不同的。不是要指责,但C的>>并不是真正的shr,它实际上是一个sar。无论如何,我找到的唯一解决方法是手动进行数学运算。下面是一个示例:

function SAR(a, b : int64): int64;
begin
  result := round(a / (1 shl b));
end;

希望对您有所帮助!

最新更新