Search code examples
delphidelphi-xe5int64

SHR on int64 does not return expected result


I'm porting some C# code to Delphi (XE5). The C# code has code like this:

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

I translated this to

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

Now I see that Delphi (sometimes) calculates wrong values for shifting negative t's, e.g.:

-170358640930559629 shr 25
Windows Calculator: -5077083139
C# code: -5077083139

Delphi: 
-170358640930559629 shr 25               = 544678730749 (wrong)

For this example, -1*((-t shr 25)+1) gives the correct value in Delphi.

For other negative values of t a simple typecast to integer seems to give the correct result:

integer(t shr 25)

I am at my limit regarding binary operations and representations, so I would appreciate any help with simply getting the same results in Delphi like in C# and Windows calculator.


Solution

  • Based on the article linked in Filipe's answer (which states the reason to be Delphi carrying out a shr as opposed to others doing a sar), here's my take on this:

    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;