Pregunta

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.

¿Fue útil?

Solución

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;

Otros consejos

As you can read here, the way C and Delphi treat Shr is different. Not meaning to point fingers, but C's >> isn't really a shr, it's actually a sar. Anyways, the only workaround that I've found is doing your math manually. Here's an example:

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

Hope it helps!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top