我正在将一些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;
希望对您有所帮助!